diff options
Diffstat (limited to 'mate-dictionary/src/gdict-aligned-window.c')
-rw-r--r-- | mate-dictionary/src/gdict-aligned-window.c | 144 |
1 files changed, 123 insertions, 21 deletions
diff --git a/mate-dictionary/src/gdict-aligned-window.c b/mate-dictionary/src/gdict-aligned-window.c index 3384840a..c4a7bca1 100644 --- a/mate-dictionary/src/gdict-aligned-window.c +++ b/mate-dictionary/src/gdict-aligned-window.c @@ -1,27 +1,27 @@ -/* gdict-aligned-window.c - Popup window aligned to a widget +/* Copyright (C) 2005-2006 Emmanuele Bassi <[email protected]> + * Copyright (C) 2012-2021 MATE Developers * - * Copyright (c) 2005-2006 Emmanuele Bassi <[email protected]> + * Ported from Seth Nickell's Python class. + * Copyright (C) 2003 Seth Nickell * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. + * This file is part of MATE Utils. * - * This program is distributed in the hope that it will be useful, + * MATE Utils is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * MATE Utils is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU Library General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Ported from Seth Nickell's Python class: - * Copyright (c) 2003 Seth Nickell + * You should have received a copy of the GNU General Public License + * along with MATE Utils. If not, see <https://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include <config.h> #endif #include <stdio.h> @@ -33,6 +33,11 @@ #include "gdict-aligned-window.h" +#if defined (ENABLE_WAYLAND) && defined (GDK_WINDOWING_WAYLAND) +#include <gdk/gdkwayland.h> +#include <gtk-layer-shell/gtk-layer-shell.h> +#endif + struct _GdictAlignedWindowPrivate { GtkWidget *align_widget; @@ -64,11 +69,8 @@ static gboolean gdict_aligned_window_motion_notify_cb (GtkWidget *widget, GdkEventMotion *event, GdictAlignedWindow *aligned_window); - G_DEFINE_TYPE_WITH_PRIVATE (GdictAlignedWindow, gdict_aligned_window, GTK_TYPE_WINDOW); - - static void gdict_aligned_window_class_init (GdictAlignedWindowClass *klass) { @@ -157,8 +159,10 @@ gdict_aligned_window_position (GdictAlignedWindow *window) gint entry_x, entry_y, entry_width, entry_height; gint x, y; GdkGravity gravity = GDK_GRAVITY_NORTH_WEST; - GdkWindow *gdk_window; + GdkWindow *gdk_window; GdkDisplay *display; + GdkMonitor *monitor; + GdkRectangle geometry = {0}; g_assert (GDICT_IS_ALIGNED_WINDOW (window)); priv = window->priv; @@ -188,7 +192,12 @@ gdict_aligned_window_position (GdictAlignedWindow *window) &entry_y); gdk_window_get_geometry (gdk_window, NULL, NULL, &entry_width, &entry_height); - if (entry_x + our_width < WidthOfScreen (gdk_x11_screen_get_xscreen (gdk_screen_get_default ()))) + /*Get the monitor dimensions*/ + display= gdk_screen_get_display (gdk_screen_get_default ()); + monitor = gdk_display_get_monitor (display, 0); + gdk_monitor_get_geometry (monitor, &geometry); + + if (entry_x + our_width < geometry.width) x = entry_x + 1; else { @@ -197,7 +206,7 @@ gdict_aligned_window_position (GdictAlignedWindow *window) gravity = GDK_GRAVITY_NORTH_EAST; } - if (entry_y + entry_height + our_height < HeightOfScreen (gdk_x11_screen_get_xscreen (gdk_screen_get_default ()))) + if (entry_y + entry_height + our_height < geometry.height) y = entry_y + entry_height - 1; else { @@ -211,6 +220,100 @@ gdict_aligned_window_position (GdictAlignedWindow *window) gtk_window_set_gravity (GTK_WINDOW (window), gravity); gtk_window_move (GTK_WINDOW (window), x, y); + +#if defined (ENABLE_WAYLAND) && defined (GDK_WINDOWING_WAYLAND) + if (GDK_IS_WAYLAND_DISPLAY (display)) + { + gboolean top, bottom, left, right; + GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET(priv->align_widget)); + + top = gtk_layer_get_anchor (GTK_WINDOW (toplevel), GTK_LAYER_SHELL_EDGE_TOP); + bottom = gtk_layer_get_anchor (GTK_WINDOW (toplevel), GTK_LAYER_SHELL_EDGE_BOTTOM); + left = gtk_layer_get_anchor (GTK_WINDOW (toplevel), GTK_LAYER_SHELL_EDGE_LEFT); + right = gtk_layer_get_anchor (GTK_WINDOW (toplevel), GTK_LAYER_SHELL_EDGE_RIGHT); + + /*Set anchors to the edges (will hold to panel edge) and position along the panel + *Confine the dialog to the screen dimensions if the applet is near right or bottom + *Unset margins and anchors from any other position so as to avoid rendering issues + *when orientation changes as when the panel is moved + */ + if (top && left && right) + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, TRUE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_BOTTOM, FALSE); + if (entry_x + our_width >= geometry.width) + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, FALSE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_RIGHT,TRUE); + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, 0); + } + else + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, TRUE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_RIGHT, FALSE); + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, entry_x); + } + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, 0); + } + + if (bottom && left && right) + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, FALSE); + if (entry_x + our_width >= geometry.width) + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, FALSE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_RIGHT,TRUE); + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, 0); + } + else + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, TRUE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_RIGHT, FALSE); + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, entry_x); + } + + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, 0); + } + if (left && bottom && top && !right) + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, TRUE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_RIGHT, FALSE); + if (entry_y + our_height >= geometry.height) + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, FALSE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE); + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, 0); + } + else + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, TRUE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_BOTTOM, FALSE); + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, entry_y); + } + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, 0); + } + if (right && bottom && top && !left) + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_RIGHT, TRUE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, FALSE); + if (entry_y + our_height >= geometry.height) + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, FALSE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE); + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, 0); + } + else + { + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, TRUE); + gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_BOTTOM, FALSE); + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, entry_y); + } + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, entry_y); + gtk_layer_set_margin (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, 0); + } + } +#endif } static void @@ -257,7 +360,6 @@ gdict_aligned_window_motion_notify_cb (GtkWidget *widget, return FALSE; } - /** * gdict_aligned_window_new: * @align_widget: a #GtkWidget to which the window should align |