Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Add gestures config to input section, toggle trackpad gesture handlers, and support window focus raising
scripts/cce-desktop-menu | 14 ++++++++++++--
src/server/cce_window_management.rs | 5 +++++
src/server/config.rs | 7 +++++++
src/server/cursor.rs | 30 ++++++++++++++++++++++++++++++
src/server/seat.rs | 8 ++++++++
src/server/window.rs | 10 +++++-----
src/server/window_manager.rs | 14 +++++++-------
7 files changed, 74 insertions(+), 14 deletions(-)
diff --git a/scripts/cce-desktop-menu b/scripts/cce-desktop-menu
index e7732cf..ec5ab11 100644
--- a/scripts/cce-desktop-menu
+++ b/scripts/cce-desktop-menu
@@ -32,11 +32,13 @@ json_layout='{
"justify": "left",
"widgets": [
{ "type": "button", "text": "Terminal", "id": "terminal" },
+ { "type": "button", "text": "Files", "id": "files" },
+ { "type": "button", "text": "Data Editor", "id": "data_editor" },
{ "type": "button", "text": "Applications", "id": "apps" },
- { "type": "button", "text": "System Settings", "id": "settings" },
+ { "type": "button", "text": "Settings", "id": "settings" },
{ "type": "button", "text": "Expose Windows", "id": "expose" },
{ "type": "button", "text": "Reload Config", "id": "reload" },
- { "type": "button", "text": "Exit CCE", "id": "exit" }
+ { "type": "button", "text": "Logout", "id": "exit" }
]
}
]
@@ -55,6 +57,14 @@ case "$btn" in
# Run terminal
foot &
;;
+ "files")
+ # Run files
+ /home/lsgalante/.local/bin/cce-files &
+ ;;
+ "data_editor")
+ # Run data editor
+ /home/lsgalante/.local/bin/cce-data-editor &
+ ;;
"apps")
# Run applications search/list
$CLEAR_CLOUD --mode apps &
diff --git a/src/server/cce_window_management.rs b/src/server/cce_window_management.rs
index 881e716..e737729 100644
--- a/src/server/cce_window_management.rs
+++ b/src/server/cce_window_management.rs
@@ -118,6 +118,11 @@ unsafe extern "C" fn toplevel_set_floating(
if let Some(window) = resolve_window(server, window_key) {
(*window).tiling_mode = crate::tiling::TilingMode::Floating;
(*window).mode_locked = true;
+ if let Some(seat) = (*server).wm.first_seat() {
+ if (*seat).focused == crate::seat::Focus::Window(window) {
+ (*server).wm.raise_window(window);
+ }
+ }
(*server).wm.dirty_windowing();
// Send floating_state(1)
diff --git a/src/server/config.rs b/src/server/config.rs
index c45ad6d..5251176 100644
--- a/src/server/config.rs
+++ b/src/server/config.rs
@@ -213,6 +213,12 @@ pub struct InputDeviceConfigRule {
pub scroll_factor: Option<f64>,
}
+#[derive(Debug, Deserialize, Clone, Default, PartialEq, Eq)]
+pub struct GesturesConfig {
+ pub swipe: Option<bool>,
+ pub pinch: Option<bool>,
+}
+
#[derive(Debug, Deserialize, Clone, Default)]
pub struct InputConfig {
pub tap_to_click: Option<bool>,
@@ -223,6 +229,7 @@ pub struct InputConfig {
pub dwtp: Option<bool>,
pub trackpoint_accel_speed: Option<f64>,
pub trackpoint_accel_profile: Option<String>,
+ pub gestures: Option<GesturesConfig>,
}
#[derive(Debug, Deserialize, Clone, Default)]
diff --git a/src/server/cursor.rs b/src/server/cursor.rs
index abb3549..3e8dfef 100644
--- a/src/server/cursor.rs
+++ b/src/server/cursor.rs
@@ -1534,6 +1534,11 @@ unsafe extern "C" fn handle_swipe_begin(listener: *mut ffi::wl_listener, data: *
let event = data as *mut ffi::wlr_pointer_swipe_begin_event;
let seat = &mut *cursor.seat;
+ let wm = &(*seat.server).wm;
+ let swipe_enabled = wm.input_config.gestures.as_ref().and_then(|g| g.swipe).unwrap_or(true);
+ if !swipe_enabled {
+ return;
+ }
seat.handle_activity();
cursor.gesture_dx = 0.0;
@@ -1559,6 +1564,11 @@ unsafe extern "C" fn handle_swipe_update(listener: *mut ffi::wl_listener, data:
let event = data as *mut ffi::wlr_pointer_swipe_update_event;
let seat = &mut *cursor.seat;
+ let wm = &(*seat.server).wm;
+ let swipe_enabled = wm.input_config.gestures.as_ref().and_then(|g| g.swipe).unwrap_or(true);
+ if !swipe_enabled {
+ return;
+ }
seat.handle_activity();
if (*event).fingers == 3 {
@@ -1698,6 +1708,11 @@ unsafe extern "C" fn handle_swipe_end(listener: *mut ffi::wl_listener, data: *mu
let event = data as *mut ffi::wlr_pointer_swipe_end_event;
let seat = &mut *cursor.seat;
+ let wm = &(*seat.server).wm;
+ let swipe_enabled = wm.input_config.gestures.as_ref().and_then(|g| g.swipe).unwrap_or(true);
+ if !swipe_enabled {
+ return;
+ }
seat.handle_activity();
log::info!("handle_swipe_end: cancelled={}", (*event).cancelled);
@@ -1724,6 +1739,11 @@ unsafe extern "C" fn handle_pinch_begin(listener: *mut ffi::wl_listener, data: *
let event = data as *mut ffi::wlr_pointer_pinch_begin_event;
let seat = &mut *cursor.seat;
+ let wm = &(*seat.server).wm;
+ let pinch_enabled = wm.input_config.gestures.as_ref().and_then(|g| g.pinch).unwrap_or(true);
+ if !pinch_enabled {
+ return;
+ }
seat.handle_activity();
cursor.gesture_scale = 1.0;
@@ -1746,6 +1766,11 @@ unsafe extern "C" fn handle_pinch_update(listener: *mut ffi::wl_listener, data:
let event = data as *mut ffi::wlr_pointer_pinch_update_event;
let seat = &mut *cursor.seat;
+ let wm = &(*seat.server).wm;
+ let pinch_enabled = wm.input_config.gestures.as_ref().and_then(|g| g.pinch).unwrap_or(true);
+ if !pinch_enabled {
+ return;
+ }
seat.handle_activity();
if cursor.gesture_triggered {
@@ -1815,6 +1840,11 @@ unsafe extern "C" fn handle_pinch_end(listener: *mut ffi::wl_listener, data: *mu
let event = data as *mut ffi::wlr_pointer_pinch_end_event;
let seat = &mut *cursor.seat;
+ let wm = &(*seat.server).wm;
+ let pinch_enabled = wm.input_config.gestures.as_ref().and_then(|g| g.pinch).unwrap_or(true);
+ if !pinch_enabled {
+ return;
+ }
seat.handle_activity();
if cursor.gesture_triggered {
diff --git a/src/server/seat.rs b/src/server/seat.rs
index a4458b4..dd00fd9 100644
--- a/src/server/seat.rs
+++ b/src/server/seat.rs
@@ -310,6 +310,13 @@ impl Seat {
}
}
+ if let Focus::Window(window) = new_focus {
+ if !window.is_null() && (*window).tiling_mode == crate::tiling::TilingMode::Floating {
+ (*self.server).wm.raise_window(window);
+ (*self.server).wm.dirty_windowing();
+ }
+ }
+
if self.focused == new_focus {
return;
}
@@ -950,6 +957,7 @@ impl Seat {
{
(*win).tiling_mode = crate::tiling::TilingMode::Floating;
(*win).mode_locked = true;
+ (*self.server).wm.raise_window(win);
}
match op.op_type {
diff --git a/src/server/window.rs b/src/server/window.rs
index 04fe070..2a57993 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -270,7 +270,7 @@ impl Window {
}
pub unsafe fn is_status_bar(&self) -> bool {
- self.get_app_id_string().as_deref() == Some("cce-status")
+ self.get_app_id_string().as_deref().map_or(false, |id| id.starts_with("cce-status"))
}
@@ -630,7 +630,7 @@ impl Window {
return;
}
let app_id_str = self.get_app_id_string().unwrap_or_default();
- if app_id_str.is_empty() || app_id_str == "cce-status" {
+ if app_id_str.is_empty() || app_id_str.starts_with("cce-status") {
return;
}
let title_str = self.get_title_string().unwrap_or_default();
@@ -697,7 +697,7 @@ impl Window {
let app_id_ptr = self.get_app_id();
let is_status_bar = if !app_id_ptr.is_null() {
let app_id = std::ffi::CStr::from_ptr(app_id_ptr).to_string_lossy();
- app_id == "cce-status"
+ app_id.starts_with("cce-status")
} else {
false
};
@@ -1483,7 +1483,7 @@ impl Window {
pub unsafe fn notify_app_id(&mut self) {
self.wm_scheduled.dirty_app_id = true;
- if self.get_app_id_string().as_deref() == Some("cce-status") {
+ if self.get_app_id_string().as_deref().map_or(false, |id| id.starts_with("cce-status")) {
self.tiling_mode = crate::tiling::TilingMode::Status;
}
self.try_restore();
@@ -1668,7 +1668,7 @@ impl Window {
let app_id_ptr = self.get_app_id();
let is_status_bar = if !app_id_ptr.is_null() {
let app_id = std::ffi::CStr::from_ptr(app_id_ptr).to_string_lossy();
- app_id == "cce-status"
+ app_id.starts_with("cce-status")
} else {
false
};
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index ddfd702..93345e9 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -827,7 +827,7 @@ impl WindowManager {
return crate::tiling::TilingMode::Status;
}
let app_id = (*win).get_app_id_string();
- if app_id.as_deref() == Some("cce-notification-daemon") || app_id.as_deref() == Some("clear-notification-daemon") {
+ if app_id.as_deref() == Some("cce-notifier") || app_id.as_deref() == Some("cce-notification-daemon") || app_id.as_deref() == Some("clear-notification-daemon") {
return crate::tiling::TilingMode::Popup;
}
if app_id.as_deref() == Some("cce-cloud") {
@@ -997,7 +997,7 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
}
let app_id = (*win_ptr).get_app_id_string();
- let is_status_bar = app_id.as_deref() == Some("cce-status");
+ let is_status_bar = app_id.as_deref().map_or(false, |id| id.starts_with("cce-status"));
if is_status_bar {
(*win_ptr).tiling_mode = crate::tiling::TilingMode::Status;
@@ -1442,7 +1442,7 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
for &w in self.focus_history.iter() {
if !w.is_null() && !(*w).closed && !(*w).minimized && matches!((*w).state, crate::window::WindowState::Mapped) {
let app_id = (*w).get_app_id_string();
- let is_status_bar = app_id.as_deref() == Some("cce-status");
+ let is_status_bar = app_id.as_deref().map_or(false, |id| id.starts_with("cce-status"));
if !is_status_bar {
next_focus = w;
break;
@@ -1453,7 +1453,7 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
for &w in self.windows.iter() {
if !w.is_null() && !(*w).closed && !(*w).minimized && matches!((*w).state, crate::window::WindowState::Mapped) {
let app_id = (*w).get_app_id_string();
- let is_status_bar = app_id.as_deref() == Some("cce-status");
+ let is_status_bar = app_id.as_deref().map_or(false, |id| id.starts_with("cce-status"));
if !is_status_bar {
next_focus = w;
}
@@ -1477,7 +1477,7 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
continue;
}
if let Some(app_id) = (*win_ptr).get_app_id_string() {
- if app_id == "cce-status" {
+ if app_id.starts_with("cce-status") {
status_bar_windows.push(win_ptr);
}
}
@@ -1629,7 +1629,7 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
if let crate::wm_node::WmNodeType::Window(window) = (*node).get() {
if !window.is_null() && !(*window).closed && !(*window).minimized {
let is_status_bar = (*window).get_app_id_string()
- .map_or(false, |aid| aid == "cce-status");
+ .map_or(false, |aid| aid.starts_with("cce-status"));
if !is_status_bar {
visible_windows.push(window);
}
@@ -1899,7 +1899,7 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
}
let app_id = (*win_ptr).get_app_id_string();
- let is_status_bar = app_id.as_deref() == Some("cce-status");
+ let is_status_bar = app_id.as_deref().map_or(false, |id| id.starts_with("cce-status"));
if is_status_bar {
continue;
}