[gtksourceview] completion: use gdk_window_move_to_rect()



commit 675a1bff6578a120b1e692f97366d7b49ff751ad
Author: Baschdel <baschdel gmx net>
Date:   Mon Jul 20 16:35:04 2020 +0000

    completion: use gdk_window_move_to_rect()
    
    A number of issues have been found when dealing with placement of the
    completion window with multiple monitors as well as coordinate systems
    outside of X11.
    
    This switches GtkSourceCompletionInfo to use gdk_window_move_to_rect()
    which has more robust implementations for platforms like Wayland.
    
    Additionally, this requires a bump to GTK 3.24 for the necessary API as
    it was removed from the private GDK vtable.
    
    Signed-off-by: Christian Hergert <chergert redhat com>

 gtksourceview/gtksourcecompletioncontainer.c |   6 +-
 gtksourceview/gtksourcecompletioninfo.c      | 158 ++++-----------------------
 meson.build                                  |   2 +-
 3 files changed, 30 insertions(+), 136 deletions(-)
---
diff --git a/gtksourceview/gtksourcecompletioncontainer.c b/gtksourceview/gtksourcecompletioncontainer.c
index 06a90a3d5..0e28adc5c 100644
--- a/gtksourceview/gtksourcecompletioncontainer.c
+++ b/gtksourceview/gtksourcecompletioncontainer.c
@@ -62,7 +62,11 @@ get_max_width (GtkSourceCompletionContainer *container)
                gdk_monitor_get_geometry (monitor, &geom);
 
                gdk_window_get_origin (window, &xorigin, NULL);
-               max_width = geom.width - xorigin;
+
+                /* Just in case xorigin is not the global coordinate limit the max
+                 * size to the monitor width.
+                 */
+               max_width = MIN (geom.width + geom.x - xorigin, geom.width);
 
                return MAX (max_width, UNREALIZED_WIDTH);
        }
diff --git a/gtksourceview/gtksourcecompletioninfo.c b/gtksourceview/gtksourcecompletioninfo.c
index 957d6a5cb..714c13275 100644
--- a/gtksourceview/gtksourcecompletioninfo.c
+++ b/gtksourceview/gtksourcecompletioninfo.c
@@ -356,12 +356,7 @@ get_iter_pos (GtkTextView *text_view,
               gint        *y,
               gint        *height)
 {
-       GdkWindow *win;
        GdkRectangle location;
-       gint win_x;
-       gint win_y;
-       gint xx;
-       gint yy;
 
        gtk_text_view_get_iter_location (text_view, iter, &location);
 
@@ -369,151 +364,46 @@ get_iter_pos (GtkTextView *text_view,
                                               GTK_TEXT_WINDOW_WIDGET,
                                               location.x,
                                               location.y,
-                                              &win_x,
-                                              &win_y);
+                                              x,
+                                              y);
 
-       win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_WIDGET);
-       gdk_window_get_origin (win, &xx, &yy);
-
-       *x = win_x + xx;
-       *y = win_y + yy + location.height;
        *height = location.height;
 }
 
-static void
-compensate_for_gravity (GtkSourceCompletionInfo *window,
-                        gint                    *x,
-                        gint                    *y,
-                        gint                     w,
-                        gint                     h)
-{
-       GdkGravity gravity = gtk_window_get_gravity (GTK_WINDOW (window));
-
-       /* Horizontal */
-       switch (gravity)
-       {
-               case GDK_GRAVITY_NORTH:
-               case GDK_GRAVITY_SOUTH:
-               case GDK_GRAVITY_CENTER:
-                       *x = w / 2;
-                       break;
-               case GDK_GRAVITY_NORTH_EAST:
-               case GDK_GRAVITY_SOUTH_EAST:
-               case GDK_GRAVITY_EAST:
-                       *x = w;
-                       break;
-               case GDK_GRAVITY_NORTH_WEST:
-               case GDK_GRAVITY_WEST:
-               case GDK_GRAVITY_SOUTH_WEST:
-               case GDK_GRAVITY_STATIC:
-               default:
-                       *x = 0;
-                       break;
-       }
-
-       /* Vertical */
-       switch (gravity)
-       {
-               case GDK_GRAVITY_WEST:
-               case GDK_GRAVITY_CENTER:
-               case GDK_GRAVITY_EAST:
-                       *y = w / 2;
-                       break;
-               case GDK_GRAVITY_SOUTH_EAST:
-               case GDK_GRAVITY_SOUTH:
-               case GDK_GRAVITY_SOUTH_WEST:
-                       *y = w;
-                       break;
-               case GDK_GRAVITY_NORTH:
-               case GDK_GRAVITY_NORTH_EAST:
-               case GDK_GRAVITY_NORTH_WEST:
-               case GDK_GRAVITY_STATIC:
-               default:
-                       *y = 0;
-                       break;
-       }
-}
-
-static void
-move_overlap (gint     *y,
-              gint      h,
-              gint      oy,
-              gint      cy,
-              gint      line_height,
-              gboolean  move_up)
-{
-       /* Test if there is overlap */
-       if (*y - cy < oy && *y - cy + h > oy - line_height)
-       {
-               if (move_up)
-               {
-                       *y = oy - line_height - h + cy;
-               }
-               else
-               {
-                       *y = oy + cy;
-               }
-       }
-}
-
 static void
 move_to_iter (GtkSourceCompletionInfo *window,
-             GtkTextView             *view,
-             GtkTextIter             *iter)
+              GtkTextView             *view,
+              GtkTextIter             *iter)
 {
-       GdkDisplay *display;
+       GdkRectangle position;
        GdkWindow *gdk_window;
-       GdkMonitor *monitor;
-       GdkRectangle geom;
        gint x, y;
-       gint w, h;
-       gint cx, cy;
-       gint oy;
-       gint height;
-       gboolean overlapup;
-
-       display = gtk_widget_get_display (GTK_WIDGET (view));
-       gdk_window = gtk_widget_get_window (GTK_WIDGET (view));
-       monitor = gdk_display_get_monitor_at_window (display, gdk_window);
-       gdk_monitor_get_geometry (monitor, &geom);
-
-       get_iter_pos (view, iter, &x, &y, &height);
-       gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+       gint line_height;
 
-       x += window->priv->xoffset;
+       gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
 
-       oy = y;
-       compensate_for_gravity (window, &cx, &cy, w, h);
-
-       /* Push window inside screen */
-       if (x - cx + w > geom.width)
-       {
-               x = (geom.width - w) + cx;
-       }
-       else if (x - cx < 0)
+       if (gdk_window == NULL)
        {
-               x = cx;
+               return;
        }
 
-       if (y - cy + h > geom.height)
-       {
-               y = (geom.height - h) + cy;
-               overlapup = TRUE;
-       }
-       else if (y - cy < 0)
-       {
-               y = cy;
-               overlapup = FALSE;
-       }
-       else
-       {
-               overlapup = TRUE;
-       }
+       get_iter_pos (view, iter, &x, &y, &line_height);
+
+       gtk_widget_translate_coordinates (GTK_WIDGET (view),
+                                         gtk_widget_get_toplevel (GTK_WIDGET (view)),
+                                         x, y, &x, &y);
 
-       /* Make sure that text is still readable */
-       move_overlap (&y, h, oy, cy, height, overlapup);
+       position.x = x;
+       position.y = y;
+       position.height = line_height;
+       position.width = 0;
 
-       gtk_window_move (GTK_WINDOW (window), x, y);
+       gdk_window_move_to_rect (gdk_window,
+                                &position,
+                                GDK_GRAVITY_SOUTH_WEST,
+                                GDK_GRAVITY_NORTH_WEST,
+                                GDK_ANCHOR_SLIDE | GDK_ANCHOR_FLIP_Y | GDK_ANCHOR_RESIZE,
+                                window->priv->xoffset, 0);
 }
 
 static void
diff --git a/meson.build b/meson.build
index 5a8499590..1f0ffdcdb 100644
--- a/meson.build
+++ b/meson.build
@@ -68,7 +68,7 @@ build_gtk_doc = get_option('gtk_doc')
 cc = meson.get_compiler('c')
 
 glib_req_version = '2.48'
-gtk_req_version = '3.22'
+gtk_req_version = '3.24'
 
 libm_dep = cc.find_library('m', required: false)
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]