Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Fix IPC view/toggle/set-tag commands to trigger render and status updates, fix clearctl socket leak
src/ipc.rs | 10 ++++++++++
src/ipc_server.rs | 4 +++-
src/wayland.rs | 15 ++++++++-------
3 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/src/ipc.rs b/src/ipc.rs
index c65cfad..f332f6a 100644
--- a/src/ipc.rs
+++ b/src/ipc.rs
@@ -91,7 +91,9 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) {
.collect();
seat.focused_window_id = visible_ids.last().copied();
}
+ state.needs_render = true;
state.needs_focus = true;
+ state.needs_status_update = true;
}
}
}
@@ -124,6 +126,8 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) {
}
state.needs_focus = true;
}
+ state.needs_render = true;
+ state.needs_status_update = true;
}
}
}
@@ -400,6 +404,8 @@ fn handle_set_mode_command(rest: &str, state: &mut WindowManager) {
let win_title = window.title.as_deref().unwrap_or("Window");
crate::config::show_notification("clearwm", &format!("Tiling mode set to {} for: {}", mode.as_str(), win_title));
}
+ state.needs_render = true;
+ state.needs_status_update = true;
}
}
@@ -475,6 +481,8 @@ fn handle_tag_layout_command(rest: &str, state: &mut WindowManager) {
if state.notifications_enable {
crate::config::show_notification("clearwm", &format!("Tag {} layout set to {}", tag, mode.as_str()));
}
+ state.needs_render = true;
+ state.needs_status_update = true;
}
}
}
@@ -512,6 +520,8 @@ fn handle_set_tag_command(rest: &str, state: &mut WindowManager) {
}
state.needs_focus = true;
}
+ state.needs_render = true;
+ state.needs_status_update = true;
}
}
}
diff --git a/src/ipc_server.rs b/src/ipc_server.rs
index 3969dc4..c88b819 100644
--- a/src/ipc_server.rs
+++ b/src/ipc_server.rs
@@ -1,4 +1,4 @@
-use std::io::Read;
+use std::io::{Read, Write};
use std::os::unix::net::{UnixListener, UnixStream};
use std::sync::mpsc;
@@ -78,6 +78,8 @@ fn ipc_server_main(tx: mpsc::Sender<String>, pipe_write: libc::c_int) {
}
}
if sent {
+ let _ = stream.write_all(b"ok\n");
+ dead.push(i);
unsafe {
libc::write(pipe_write, &1u8 as *const u8 as *const libc::c_void, 1);
}
diff --git a/src/wayland.rs b/src/wayland.rs
index 2b2eb7e..5422dd2 100644
--- a/src/wayland.rs
+++ b/src/wayland.rs
@@ -2596,6 +2596,7 @@ impl Dispatch<RiverLibinputConfigV1, ()> for AppState {
tap_finger_count: -1, // not yet received
tap_info_received: false,
});
+ state.wm.tap_config_applied = false;
}
river_libinput_config_v1::Event::Finished => {}
_ => {}
@@ -2608,22 +2609,20 @@ impl Dispatch<RiverLibinputConfigV1, ()> for AppState {
impl Dispatch<RiverLibinputDeviceV1, ()> for AppState {
fn event(
state: &mut Self,
- _proxy: &RiverLibinputDeviceV1,
+ proxy: &RiverLibinputDeviceV1,
event: river_libinput_device_v1::Event,
_data: &(),
_conn: &Connection,
- _qhandle: &QueueHandle<Self>,
+ qhandle: &QueueHandle<Self>,
) {
match event {
river_libinput_device_v1::Event::TapSupport { finger_count } => {
- if let Some(dev) = state.libinput_devices.last_mut() {
+ if let Some(dev) = state.libinput_devices.iter_mut().find(|d| d.device.id().protocol_id() == proxy.id().protocol_id()) {
dev.tap_finger_count = finger_count;
eprintln!("[libinput] tap support: {} fingers", finger_count);
}
- // Don't apply tap config here — devices arrive one at a time.
- // If we apply after the first device (which may not support tap),
- // tap_config_applied gets set too early and we miss the touchpad.
- // Instead, apply in RenderStart after all devices have been discovered.
+ // Apply tap config directly when info is received, in case we are waking up
+ crate::wayland::apply_tap_config(state, qhandle);
}
river_libinput_device_v1::Event::TapDefault { state: tap_state } => {
let _ = tap_state;
@@ -2635,6 +2634,8 @@ impl Dispatch<RiverLibinputDeviceV1, ()> for AppState {
}
river_libinput_device_v1::Event::Removed => {
eprintln!("[libinput] device removed");
+ state.libinput_devices.retain(|d| d.device.id().protocol_id() != proxy.id().protocol_id());
+ state.wm.tap_config_applied = false;
}
_ => {}
}