Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Offset cce-cloud sub-menus by their parent status module position
src/server/cursor.rs | 8 +++----
src/server/keyboard_group.rs | 2 +-
src/server/layer_shell.rs | 52 +++++++++++++++++++++++++++++++++++++++++++-
src/server/status_server.rs | 2 +-
src/server/window_manager.rs | 2 +-
5 files changed, 58 insertions(+), 8 deletions(-)
diff --git a/src/server/cursor.rs b/src/server/cursor.rs
index 1281d30..0f5f01f 100644
--- a/src/server/cursor.rs
+++ b/src/server/cursor.rs
@@ -604,7 +604,7 @@ unsafe extern "C" fn handle_button(listener: *mut ffi::wl_listener, data: *mut s
let wlr_layer_surface = (*layer_surface).wlr_layer_surface;
if !wlr_layer_surface.is_null() && !(*wlr_layer_surface).namespace.is_null() {
let ns = std::ffi::CStr::from_ptr((*wlr_layer_surface).namespace).to_string_lossy();
- if ns == "cce-cloud" {
+ if ns.starts_with("cce-cloud") {
is_overlay_window = true;
}
}
@@ -1396,7 +1396,7 @@ unsafe extern "C" fn handle_touch_down(listener: *mut ffi::wl_listener, data: *m
let wlr_layer_surface = (*layer_surface).wlr_layer_surface;
if !wlr_layer_surface.is_null() && !(*wlr_layer_surface).namespace.is_null() {
let ns = std::ffi::CStr::from_ptr((*wlr_layer_surface).namespace).to_string_lossy();
- if ns == "cce-cloud" {
+ if ns.starts_with("cce-cloud") {
is_overlay_window = true;
}
}
@@ -1465,7 +1465,7 @@ unsafe extern "C" fn handle_touch_motion(listener: *mut ffi::wl_listener, data:
let wlr_layer_surface = (*layer_surface).wlr_layer_surface;
if !wlr_layer_surface.is_null() && !(*wlr_layer_surface).namespace.is_null() {
let ns = std::ffi::CStr::from_ptr((*wlr_layer_surface).namespace).to_string_lossy();
- if ns == "cce-cloud" {
+ if ns.starts_with("cce-cloud") {
is_overlay_window = true;
}
}
@@ -1518,7 +1518,7 @@ unsafe extern "C" fn handle_touch_up(listener: *mut ffi::wl_listener, data: *mut
let wlr_layer_surface = (*layer_surface).wlr_layer_surface;
if !wlr_layer_surface.is_null() && !(*wlr_layer_surface).namespace.is_null() {
let ns = std::ffi::CStr::from_ptr((*wlr_layer_surface).namespace).to_string_lossy();
- if ns == "cce-cloud" {
+ if ns.starts_with("cce-cloud") {
is_overlay_window = true;
}
}
diff --git a/src/server/keyboard_group.rs b/src/server/keyboard_group.rs
index 7cd2784..6a55c66 100644
--- a/src/server/keyboard_group.rs
+++ b/src/server/keyboard_group.rs
@@ -452,7 +452,7 @@ unsafe extern "C" fn handle_group_key(listener: *mut ffi::wl_listener, data: *mu
let wlr_layer_surface = crate::ffi::wlr_layer_surface_v1_try_from_wlr_surface(focused_layer);
if !wlr_layer_surface.is_null() && !(*wlr_layer_surface).namespace.is_null() {
let ns = std::ffi::CStr::from_ptr((*wlr_layer_surface).namespace).to_string_lossy();
- ns == "cce-cloud"
+ ns.starts_with("cce-cloud")
} else {
false
}
diff --git a/src/server/layer_shell.rs b/src/server/layer_shell.rs
index 90e7dfa..da7c5d3 100644
--- a/src/server/layer_shell.rs
+++ b/src/server/layer_shell.rs
@@ -304,6 +304,7 @@ pub struct LayerSurface {
pub unmap: ffi::wl_listener,
pub commit: ffi::wl_listener,
pub new_popup: ffi::wl_listener,
+ pub parent_offset_applied: bool,
}
impl LayerSurface {
@@ -336,6 +337,7 @@ impl LayerSurface {
unmap: std::mem::zeroed(),
commit: std::mem::zeroed(),
new_popup: std::mem::zeroed(),
+ parent_offset_applied: false,
}));
let key = (*server).layer_shell.surfaces.put(layer_surface);
@@ -550,7 +552,7 @@ unsafe extern "C" fn handle_layer_surface_unmap(listener: *mut ffi::wl_listener,
let mut is_cce_cloud = false;
if !(*wlr_layer_surface).namespace.is_null() {
let ns = std::ffi::CStr::from_ptr((*wlr_layer_surface).namespace).to_string_lossy();
- if ns == "cce-cloud" {
+ if ns.starts_with("cce-cloud") {
is_cce_cloud = true;
}
}
@@ -637,6 +639,54 @@ unsafe extern "C" fn handle_layer_surface_commit(listener: *mut ffi::wl_listener
let server = (*layer_surface).server;
+ // Position offset for cce-cloud sub-modules
+ if !(*layer_surface).parent_offset_applied {
+ if !(*wlr_layer_surface).namespace.is_null() {
+ let ns = std::ffi::CStr::from_ptr((*wlr_layer_surface).namespace).to_string_lossy();
+ if ns.starts_with("cce-cloud:") {
+ let parent_app_id = &ns["cce-cloud:".len()..];
+ let mut parent_x = None;
+ let mut parent_y = None;
+ let mut parent_w = 0;
+ for &win_ptr in (*server).wm.windows.iter() {
+ if win_ptr.is_null() || (*win_ptr).closed {
+ continue;
+ }
+ if let Some(win_app_id) = (*win_ptr).get_app_id_string() {
+ if win_app_id == parent_app_id {
+ parent_x = Some((*win_ptr).rendering_requested.x);
+ parent_y = Some((*win_ptr).rendering_requested.y);
+ parent_w = (*win_ptr).box_geom.width;
+ break;
+ }
+ }
+ }
+
+ if let (Some(px), Some(py)) = (parent_x, parent_y) {
+ let wlr_box = (*output).sent.box_layout();
+ let output_x = wlr_box.x;
+ let output_y = wlr_box.y;
+ let output_w = wlr_box.width;
+
+ let relative_parent_x = px - output_x;
+ let relative_parent_y = py - output_y;
+
+ let anchor = (*wlr_layer_surface).current.anchor;
+ let is_align_right = (anchor & ffi::zwlr_layer_surface_v1_anchor_ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) != 0;
+
+ if is_align_right {
+ (*wlr_layer_surface).current.margin.right = (output_w - relative_parent_x - parent_w) + (*wlr_layer_surface).current.margin.right;
+ } else {
+ (*wlr_layer_surface).current.margin.left = relative_parent_x + (*wlr_layer_surface).current.margin.left;
+ }
+ (*wlr_layer_surface).current.margin.top = relative_parent_y + (*wlr_layer_surface).current.margin.top;
+
+ (*layer_surface).parent_offset_applied = true;
+ }
+ }
+ }
+ }
+
// Check if layer was changed
if (*wlr_layer_surface).current.committed & ffi::wlr_layer_surface_v1_state_field_WLR_LAYER_SURFACE_V1_STATE_LAYER != 0 {
let tree = (*server).scene.layer_surface_tree((*wlr_layer_surface).current.layer);
diff --git a/src/server/status_server.rs b/src/server/status_server.rs
index a409618..1d4b886 100644
--- a/src/server/status_server.rs
+++ b/src/server/status_server.rs
@@ -252,7 +252,7 @@ pub unsafe fn build_status_update(wm: &crate::window_manager::WindowManager) ->
let wlr_layer_surface = crate::ffi::wlr_layer_surface_v1_try_from_wlr_surface(focused_layer);
if !wlr_layer_surface.is_null() && !(*wlr_layer_surface).namespace.is_null() {
let ns = std::ffi::CStr::from_ptr((*wlr_layer_surface).namespace).to_string_lossy();
- if ns == "cce-cloud" {
+ if ns.starts_with("cce-cloud") {
is_cce_cloud = true;
}
}
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 644a2fa..c5bd076 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -1003,7 +1003,7 @@ impl WindowManager {
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") {
+ if app_id.as_deref().map_or(false, |id| id.starts_with("cce-cloud")) {
return crate::tiling::TilingMode::Overlay;
}