From a96a0a16fdee53e4b60e8f4195c56aab8196125c Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Sun, 28 Jul 2024 12:40:02 +0200 Subject: [PATCH 1/3] PanelWindow/X11: Use pantheon protocol for positioning, struts, etc. --- meson.build | 1 + src/PanelWindow.vala | 100 +++++++++---------------------------------- src/meson.build | 1 + 3 files changed, 23 insertions(+), 79 deletions(-) diff --git a/meson.build b/meson.build index 8d4d5e7f..8effd585 100644 --- a/meson.build +++ b/meson.build @@ -32,6 +32,7 @@ gdk_wl_dep = dependency('gdk-wayland-3.0') # GDK X11 dep is for detecting whether we're on Wayland or not ONLY, we don't actually have # a hard X11 dependency here gdk_x11_dep = dependency('gdk-x11-3.0') +x11_dep = dependency('x11') gtk_dep = dependency('gtk+-3.0', version: '>=3.10') gee_dep = dependency('gee-0.8') granite_dep = dependency('granite', version: '>=5.4.0') diff --git a/src/PanelWindow.vala b/src/PanelWindow.vala index 9eca83c4..143c9a28 100644 --- a/src/PanelWindow.vala +++ b/src/PanelWindow.vala @@ -27,8 +27,6 @@ public class Wingpanel.PanelWindow : Gtk.Window { private int monitor_number; private int monitor_width; private int monitor_height; - private int monitor_x; - private int monitor_y; private int panel_height; private bool expanded = false; @@ -43,7 +41,6 @@ public class Wingpanel.PanelWindow : Gtk.Window { resizable: false, skip_pager_hint: true, skip_taskbar_hint: true, - type_hint: Gdk.WindowTypeHint.DOCK, vexpand: false ); @@ -100,19 +97,15 @@ public class Wingpanel.PanelWindow : Gtk.Window { } private void on_realize () { - // realize isn't called when reveal_child is false, so we set true, then - // false, then true again to animate. On wayland we are animated in by gala - // so we just want the revealer to always reveal. - if (!Utils.is_wayland ()) { - revealer.reveal_child = false; - } update_panel_dimensions (); Services.BackgroundManager.initialize (this.monitor_number, panel_height); - revealer.transition_type = SLIDE_DOWN; - revealer.reveal_child = true; - // We have to wrap in Idle otherwise the Meta.Window of the WaylandSurface in Gala is still null - Idle.add_once (init_wl); + if (Utils.is_wayland ()) { + // We have to wrap in Idle otherwise the Meta.Window of the WaylandSurface in Gala is still null + Idle.add_once (init_wl); + } else { + init_x (); + } } private void update_panel_dimensions () { @@ -135,13 +128,6 @@ public class Wingpanel.PanelWindow : Gtk.Window { monitor_height = monitor_dimensions.height; this.set_size_request (monitor_width, (popover_manager.current_indicator != null ? monitor_height : -1)); - - monitor_x = monitor_dimensions.x; - monitor_y = monitor_dimensions.y; - - move (monitor_x, monitor_y); - - update_struts (); } private void update_visual () { @@ -162,65 +148,6 @@ public class Wingpanel.PanelWindow : Gtk.Window { return Gdk.EVENT_PROPAGATE; } - private void update_struts () { - if (!this.get_realized () || panel == null) { - return; - } - - /** - * https://specifications.freedesktop.org/wm-spec/wm-spec-1.5.html#NETWMSTRUT - * The _NET_WM_STRUCT_PARTICAL specification does not allow to reserve space for arbitrary rectangles - * on the screen. Instead it only allows to reserve space at the borders of screen. - * As for multi-monitor layouts the wingpanel can be at the within the screen (and not at the border) - * this makes it impossible to reserve the correct space for all possible multi-monitor layouts. - * Fortunately for up to 3 monitors there is always a possiblity to reserve the right space by also - * using the struct-left and struct-right cardinals. - */ - - var display = get_display (); - var n_monitors = display.get_n_monitors (); - int screen_width = 0; - bool no_monitor_left = true; - bool no_monitor_right = true; - bool no_monitor_above = true; - for (var i = 0; i < n_monitors; i++) { - var rect = display.get_monitor (i).get_geometry (); - screen_width = int.max (screen_width, rect.x + rect.width); - if (i == monitor_number) { - continue; - } - - var is_left = rect.x + rect.width <= monitor_x; - var is_right = rect.x >= monitor_x + monitor_width; - var is_above = rect.y + rect.height <= monitor_y; - var is_below = rect.y >= monitor_y + panel_height; - no_monitor_left &= !is_left || is_above || is_below; - no_monitor_right &= !is_right || is_above || is_below; - no_monitor_above &= !is_above || is_left || is_right; - } - - long struts[12] = { 0 }; - var scale_factor = this.get_scale_factor (); - if (no_monitor_left) { - struts [0] = (monitor_x + monitor_width) * scale_factor; - struts [4] = monitor_y * scale_factor; - struts [5] = (monitor_y + panel_height) * scale_factor - 1; - } else if (no_monitor_right) { - struts [1] = (screen_width - monitor_x) * scale_factor; - struts [6] = monitor_y * scale_factor; - struts [7] = (monitor_y + panel_height) * scale_factor - 1; - } else if (no_monitor_above) { - struts [2] = (monitor_y + panel_height) * scale_factor; - struts [8] = monitor_x * scale_factor; - struts [9] = (monitor_x + monitor_width) * scale_factor - 1; - } else { - warning ("Unable to set struts, because Wingpanel is not at the edge of the Gdk.Screen area."); - } - - Gdk.property_change (this.get_window (), Gdk.Atom.intern ("_NET_WM_STRUT_PARTIAL", false), - Gdk.Atom.intern ("CARDINAL", false), 32, Gdk.PropMode.REPLACE, (uint8[])struts, 12); - } - public void set_expanded (bool expand) { if (expand && !this.expanded) { Services.BackgroundManager.get_default ().remember_window (); @@ -244,6 +171,21 @@ public class Wingpanel.PanelWindow : Gtk.Window { } } + private void init_x () { + var display = Gdk.Display.get_default (); + if (display is Gdk.X11.Display) { + unowned var xdisplay = ((Gdk.X11.Display) display).get_xdisplay (); + + var window = ((Gdk.X11.Window) get_window ()).get_xid (); + + var prop = xdisplay.intern_atom ("_MUTTER_HINTS", false); + + var value = "anchor=4:hide-mode=0:size=-1,%d".printf (get_allocated_height () * get_scale_factor ()); + + xdisplay.change_property (window, prop, X.XA_STRING, 8, 0, (uchar[]) value, value.length); + } + } + public void registry_handle_global (Wl.Registry wl_registry, uint32 name, string @interface, uint32 version) { if (@interface == "io_elementary_pantheon_shell_v1") { desktop_shell = wl_registry.bind (name, ref Pantheon.Desktop.Shell.iface, uint32.min (version, 1)); diff --git a/src/meson.build b/src/meson.build index d9ca1250..1b694eed 100644 --- a/src/meson.build +++ b/src/meson.build @@ -17,6 +17,7 @@ wingpanel_deps = [ granite_dep, gdk_wl_dep, gdk_x11_dep, + dependency('x11'), posix_dep, wl_client_dep, pantheon_desktop_shell_dep From dfac75217a94cde25c90a7e5c94153465d77eb51 Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Sun, 28 Jul 2024 12:41:46 +0200 Subject: [PATCH 2/3] Cleanup --- src/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meson.build b/src/meson.build index 1b694eed..9f84c13d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -17,7 +17,7 @@ wingpanel_deps = [ granite_dep, gdk_wl_dep, gdk_x11_dep, - dependency('x11'), + x11_dep, posix_dep, wl_client_dep, pantheon_desktop_shell_dep From bb0d4eb3a1c566b957f67124426c001a42014070 Mon Sep 17 00:00:00 2001 From: lenemter Date: Sun, 11 Aug 2024 22:43:53 +0900 Subject: [PATCH 3/3] Fix lint --- src/PanelWindow.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PanelWindow.vala b/src/PanelWindow.vala index 143c9a28..3c389802 100644 --- a/src/PanelWindow.vala +++ b/src/PanelWindow.vala @@ -176,7 +176,7 @@ public class Wingpanel.PanelWindow : Gtk.Window { if (display is Gdk.X11.Display) { unowned var xdisplay = ((Gdk.X11.Display) display).get_xdisplay (); - var window = ((Gdk.X11.Window) get_window ()).get_xid (); + var window = ((Gdk.X11.Window) get_window ()).get_xid (); var prop = xdisplay.intern_atom ("_MUTTER_HINTS", false);