summaryrefslogtreecommitdiff
path: root/mate-dictionary/src/gdict-aligned-window.c
diff options
context:
space:
mode:
Diffstat (limited to 'mate-dictionary/src/gdict-aligned-window.c')
-rw-r--r--mate-dictionary/src/gdict-aligned-window.c144
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