From e8cd95789810bc9efb7961f553e99f0c2eaa0cd0 Mon Sep 17 00:00:00 2001 From: Luke from DC Date: Tue, 11 Jul 2023 10:02:50 +0000 Subject: 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 --- applets/clock/Makefile.am | 8 ++ applets/clock/clock.c | 270 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 195 insertions(+), 83 deletions(-) (limited to 'applets') 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 #include +#if defined (CLOCK_INPROCESS) && defined (HAVE_WAYLAND) +#include +#include +#endif + #ifdef HAVE_X11 #include #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 } -- cgit v1.2.1