Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Window: send river_window_v1.show_window_menu_requested
river/Window.zig | 6 +++++-
river/XdgToplevel.zig | 15 +++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/river/Window.zig b/river/Window.zig
index 50c5e52..a2dc489 100644
--- a/river/Window.zig
+++ b/river/Window.zig
@@ -149,6 +149,7 @@ popup_tree: *wlr.SceneTree,
wm_scheduled: struct {
dimensions_hint: DimensionsHint = .{},
decoration_hint: river.WindowV1.DecorationHint = .only_supports_csd,
+ show_window_menu_requested: ?struct { x: i32, y: i32 } = null,
/// Set back to no_request at the end of each update sequence
fullscreen_requested: FullscreenRequest = .no_request,
maximize_requested: enum {
@@ -382,7 +383,6 @@ pub fn manageStart(window: *Window) void {
const scheduled = &window.wm_scheduled;
const sent = &window.wm_sent;
- // XXX send all dirty scheduled state
if (new or !meta.eql(scheduled.dimensions_hint, sent.dimensions_hint)) {
window_v1.sendDimensionsHint(
scheduled.dimensions_hint.min_width,
@@ -397,6 +397,10 @@ pub fn manageStart(window: *Window) void {
sent.decoration_hint = scheduled.decoration_hint;
}
+ if (scheduled.show_window_menu_requested) |offset| {
+ window_v1.sendShowWindowMenuRequested(offset.x, offset.y);
+ scheduled.show_window_menu_requested = null;
+ }
switch (scheduled.fullscreen_requested) {
.no_request => {},
.fullscreen => |output_hint| {
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index a90d3ab..dbe43d6 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -65,6 +65,7 @@ map: wl.Listener(void) = .init(handleMap),
unmap: wl.Listener(void) = .init(handleUnmap),
commit: wl.Listener(*wlr.Surface) = .init(handleCommit),
new_popup: wl.Listener(*wlr.XdgPopup) = .init(handleNewPopup),
+request_show_window_menu: wl.Listener(*wlr.XdgToplevel.event.ShowWindowMenu) = .init(handleRequestShowWindowMenu),
request_fullscreen: wl.Listener(void) = .init(handleRequestFullscreen),
request_maximize: wl.Listener(void) = .init(handleRequestMaximize),
request_minimize: wl.Listener(void) = .init(handleRequestMinimize),
@@ -108,6 +109,7 @@ pub fn create(wlr_toplevel: *wlr.XdgToplevel) error{OutOfMemory}!void {
wlr_toplevel.base.surface.events.map.add(&toplevel.map);
wlr_toplevel.base.surface.events.commit.add(&toplevel.commit);
wlr_toplevel.base.events.new_popup.add(&toplevel.new_popup);
+ wlr_toplevel.events.request_show_window_menu.add(&toplevel.request_show_window_menu);
wlr_toplevel.events.request_fullscreen.add(&toplevel.request_fullscreen);
wlr_toplevel.events.request_maximize.add(&toplevel.request_maximize);
wlr_toplevel.events.request_minimize.add(&toplevel.request_minimize);
@@ -234,6 +236,7 @@ fn handleDestroy(listener: *wl.Listener(void)) void {
toplevel.unmap.link.remove();
toplevel.commit.link.remove();
toplevel.new_popup.link.remove();
+ toplevel.request_show_window_menu.link.remove();
toplevel.request_fullscreen.link.remove();
toplevel.request_maximize.link.remove();
toplevel.request_minimize.link.remove();
@@ -372,6 +375,18 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
}
}
+fn handleRequestShowWindowMenu(
+ listener: *wl.Listener(*wlr.XdgToplevel.event.ShowWindowMenu),
+ event: *wlr.XdgToplevel.event.ShowWindowMenu,
+) void {
+ const toplevel: *XdgToplevel = @fieldParentPtr("request_show_window_menu", listener);
+ toplevel.window.wm_scheduled.show_window_menu_requested = .{
+ .x = event.x - toplevel.geometry.x,
+ .y = event.y - toplevel.geometry.y,
+ };
+ server.wm.dirtyWindowing();
+}
+
fn handleRequestFullscreen(listener: *wl.Listener(void)) void {
const toplevel: *XdgToplevel = @fieldParentPtr("request_fullscreen", listener);
if (toplevel.wlr_toplevel.requested.fullscreen) {