diff options
author | Luke from DC <[email protected]> | 2023-07-11 10:02:50 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2023-07-11 12:02:50 +0200 |
commit | e8cd95789810bc9efb7961f553e99f0c2eaa0cd0 (patch) | |
tree | 4db4ceaaee315f1cd9bf68cb84c6ad8aeb8bf1ba /applets | |
parent | 5a7f770082568453f3a5f271a274156f08352101 (diff) | |
download | mate-panel-e8cd95789810bc9efb7961f553e99f0c2eaa0cd0.tar.bz2 mate-panel-e8cd95789810bc9efb7961f553e99f0c2eaa0cd0.tar.xz |
Clock applet/wayland: position calendar window same as in x11
* Clock applet/wayland: position calendar window same as in x11
- Wayland/clock: fix calendar window rendering when moved
Ensure the calendar window cannot be "stretched" across the screen
if the panel or the applet is moved while the calendar is showing
Diffstat (limited to 'applets')
-rw-r--r-- | applets/clock/Makefile.am | 8 | ||||
-rw-r--r-- | applets/clock/clock.c | 270 |
2 files changed, 195 insertions, 83 deletions
diff --git a/applets/clock/Makefile.am b/applets/clock/Makefile.am index c452fab9..e145dd5f 100644 --- a/applets/clock/Makefile.am +++ b/applets/clock/Makefile.am @@ -67,6 +67,14 @@ libclock_applet_la_LIBADD = $(CLOCK_LDADD) libclock_applet_la_LDFLAGS = -module -avoid-version libclock_applet_la_CFLAGS = $(AM_CFLAGS) $(libclock_applet_la_OBJECTS): $(BUILT_SOURCES) + +if ENABLE_WAYLAND +libclock_applet_la_LIBADD += \ + $(WAYLAND_LIBS) + +AM_CPPFLAGS += \ + $(WAYLAND_CFLAGS) +endif else APPLET_IN_PROCESS = false APPLET_LOCATION = $(libexecdir)/clock-applet diff --git a/applets/clock/clock.c b/applets/clock/clock.c index 7a11f0e9..840a45f7 100644 --- a/applets/clock/clock.c +++ b/applets/clock/clock.c @@ -51,6 +51,11 @@ #include <gdk/gdkkeysyms.h> #include <gio/gio.h> +#if defined (CLOCK_INPROCESS) && defined (HAVE_WAYLAND) +#include <gdk/gdkwayland.h> +#include <gtk-layer-shell/gtk-layer-shell.h> +#endif + #ifdef HAVE_X11 #include <gdk/gdkx.h> #endif @@ -888,105 +893,204 @@ create_calendar (ClockData *cd) static void position_calendar_popup (ClockData *cd) { -#ifdef HAVE_X11 - GtkRequisition req; - GtkAllocation allocation; - GdkDisplay *display; - GdkScreen *screen; - GdkRectangle monitor; - GdkGravity gravity = GDK_GRAVITY_NORTH_WEST; - int button_w, button_h; - int x, y; - int w, h; - int i, n; - gboolean found_monitor = FALSE; - - if (!GDK_IS_X11_DISPLAY (gdk_display_get_default ())) - return; +#if defined(HAVE_X11) && defined(GDK_WINDOWING_X11) + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) + { + GtkRequisition req; + GtkAllocation allocation; + GdkDisplay *display; + GdkScreen *screen; + GdkRectangle monitor; + GdkGravity gravity = GDK_GRAVITY_NORTH_WEST; + int button_w, button_h; + int x, y; + int w, h; + int i, n; + gboolean found_monitor = FALSE; + + + /* Get root origin of the toggle button, and position above that. */ + gdk_window_get_origin (gtk_widget_get_window (cd->panel_button), + &x, &y); + + gtk_window_get_size (GTK_WINDOW (cd->calendar_popup), &w, &h); + gtk_widget_get_preferred_size (cd->calendar_popup, &req, NULL); + w = req.width; + h = req.height; + + gtk_widget_get_allocation (cd->panel_button, &allocation); + button_w = allocation.width; + button_h = allocation.height; + + screen = gtk_window_get_screen (GTK_WINDOW (cd->calendar_popup)); + display = gdk_screen_get_display (screen); + + n = gdk_display_get_n_monitors (display); + for (i = 0; i < n; i++) { + gdk_monitor_get_geometry (gdk_display_get_monitor (display, i), &monitor); + if (x >= monitor.x && x <= monitor.x + monitor.width && + y >= monitor.y && y <= monitor.y + monitor.height) { + found_monitor = TRUE; + break; + } + } - /* Get root origin of the toggle button, and position above that. */ - gdk_window_get_origin (gtk_widget_get_window (cd->panel_button), - &x, &y); + if (!found_monitor) { + /* eek, we should be on one of those xinerama + monitors */ + monitor.x = 0; + monitor.y = 0; + monitor.width = WidthOfScreen (gdk_x11_screen_get_xscreen (screen)); + monitor.height = HeightOfScreen (gdk_x11_screen_get_xscreen (screen)); + } - gtk_window_get_size (GTK_WINDOW (cd->calendar_popup), &w, &h); - gtk_widget_get_preferred_size (cd->calendar_popup, &req, NULL); - w = req.width; - h = req.height; + /* Based on panel orientation, position the popup. + * Ignore window gravity since the window is undecorated. + * The orientations are all named backward from what + * I expected. + */ + switch (cd->orient) { + case MATE_PANEL_APPLET_ORIENT_RIGHT: + x += button_w; + if ((y + h) > monitor.y + monitor.height) + y -= (y + h) - (monitor.y + monitor.height); + + if ((y + h) > (monitor.height / 2)) + gravity = GDK_GRAVITY_SOUTH_WEST; + else + gravity = GDK_GRAVITY_NORTH_WEST; - gtk_widget_get_allocation (cd->panel_button, &allocation); - button_w = allocation.width; - button_h = allocation.height; - - screen = gtk_window_get_screen (GTK_WINDOW (cd->calendar_popup)); - display = gdk_screen_get_display (screen); - - n = gdk_display_get_n_monitors (display); - for (i = 0; i < n; i++) { - gdk_monitor_get_geometry (gdk_display_get_monitor (display, i), &monitor); - if (x >= monitor.x && x <= monitor.x + monitor.width && - y >= monitor.y && y <= monitor.y + monitor.height) { - found_monitor = TRUE; break; - } - } + case MATE_PANEL_APPLET_ORIENT_LEFT: + x -= w; + if ((y + h) > monitor.y + monitor.height) + y -= (y + h) - (monitor.y + monitor.height); - if (!found_monitor) { - /* eek, we should be on one of those xinerama - monitors */ - monitor.x = 0; - monitor.y = 0; - monitor.width = WidthOfScreen (gdk_x11_screen_get_xscreen (screen)); - monitor.height = HeightOfScreen (gdk_x11_screen_get_xscreen (screen)); - } + if ((y + h) > (monitor.height / 2)) + gravity = GDK_GRAVITY_SOUTH_EAST; + else + gravity = GDK_GRAVITY_NORTH_EAST; - /* Based on panel orientation, position the popup. - * Ignore window gravity since the window is undecorated. - * The orientations are all named backward from what - * I expected. - */ - switch (cd->orient) { - case MATE_PANEL_APPLET_ORIENT_RIGHT: - x += button_w; - if ((y + h) > monitor.y + monitor.height) - y -= (y + h) - (monitor.y + monitor.height); + break; + case MATE_PANEL_APPLET_ORIENT_DOWN: + y += button_h; + if ((x + w) > monitor.x + monitor.width) + x -= (x + w) - (monitor.x + monitor.width); - if ((y + h) > (monitor.height / 2)) - gravity = GDK_GRAVITY_SOUTH_WEST; - else gravity = GDK_GRAVITY_NORTH_WEST; - break; - case MATE_PANEL_APPLET_ORIENT_LEFT: - x -= w; - if ((y + h) > monitor.y + monitor.height) - y -= (y + h) - (monitor.y + monitor.height); + break; + case MATE_PANEL_APPLET_ORIENT_UP: + y -= h; + if ((x + w) > monitor.x + monitor.width) + x -= (x + w) - (monitor.x + monitor.width); - if ((y + h) > (monitor.height / 2)) - gravity = GDK_GRAVITY_SOUTH_EAST; - else - gravity = GDK_GRAVITY_NORTH_EAST; + gravity = GDK_GRAVITY_SOUTH_WEST; - break; - case MATE_PANEL_APPLET_ORIENT_DOWN: - y += button_h; - if ((x + w) > monitor.x + monitor.width) - x -= (x + w) - (monitor.x + monitor.width); + break; + } - gravity = GDK_GRAVITY_NORTH_WEST; + gtk_window_move (GTK_WINDOW (cd->calendar_popup), x, y); + gtk_window_set_gravity (GTK_WINDOW (cd->calendar_popup), gravity); + } +#endif - break; - case MATE_PANEL_APPLET_ORIENT_UP: - y -= h; - if ((x + w) > monitor.x + monitor.width) - x -= (x + w) - (monitor.x + monitor.width); + /*Only build wayland support when building in process*/ +#if defined(CLOCK_INPROCESS) && defined(HAVE_WAYLAND) && defined(GDK_WINDOWING_WAYLAND) + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) + { + GtkWindow *window; + GdkWindow *panelwin; + GtkWidget *toplevel; + int x, y, w, h, panel_w, panel_h; + + /*Get the calendar window dimensions*/ + window = (GTK_WINDOW (cd->calendar_popup)); + gtk_window_get_size (window, &w, &h); + /*Find the position of the applet*/ + gdk_window_get_origin (gtk_widget_get_window (cd->panel_button), + &x, &y); + + /*Get the panel dimensions*/ + toplevel = gtk_widget_get_toplevel (cd->applet); + panelwin = gtk_widget_get_window (toplevel); + gdk_window_get_geometry (panelwin, NULL, NULL, &panel_w, &panel_h); + + /*Set up GTK Layer Shell*/ + gtk_layer_init_for_window (window); + gtk_layer_set_layer (window, GTK_LAYER_SHELL_LAYER_TOP); + + switch (cd->orient) { + case MATE_PANEL_APPLET_ORIENT_RIGHT: + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, TRUE); + gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_LEFT, 0); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_RIGHT, FALSE); + if (y < (panel_h - h)) + { + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, TRUE); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, FALSE); + gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_TOP, y); + } + else + { + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, FALSE); + } + break; + + case MATE_PANEL_APPLET_ORIENT_LEFT: + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_RIGHT, TRUE); + gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_RIGHT, 0); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, FALSE); + if (y < (panel_h - h)) + { + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, TRUE); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, FALSE); + gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_TOP, y); + } + else + { + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, FALSE); + } + break; - gravity = GDK_GRAVITY_SOUTH_WEST; + case MATE_PANEL_APPLET_ORIENT_DOWN: + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, TRUE); + gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_TOP, 0); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, FALSE); + if (x < (panel_w - w)) + { + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, TRUE); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_RIGHT, FALSE); + gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_LEFT, x); + } + else + { + gtk_layer_set_anchor(window, GTK_LAYER_SHELL_EDGE_RIGHT, TRUE); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, FALSE); + } + break; - break; + case MATE_PANEL_APPLET_ORIENT_UP: + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE); + gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_BOTTOM, 0); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, FALSE); + if (x < (panel_w - w)) + { + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, TRUE); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_RIGHT, FALSE); + gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_LEFT, x); + } + else + { + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_RIGHT, TRUE); + gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, FALSE); + } + break; + } + return; } - - gtk_window_move (GTK_WINDOW (cd->calendar_popup), x, y); - gtk_window_set_gravity (GTK_WINDOW (cd->calendar_popup), gravity); #endif } |