all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#57224: 29.0.50; PGTK: scroll-bar obscures child-frame
@ 2022-08-15 15:15 Florian Rommel
  2022-08-16  1:00 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 2+ messages in thread
From: Florian Rommel @ 2022-08-15 15:15 UTC (permalink / raw)
  To: 57224

[-- Attachment #1: Type: text/plain, Size: 1673 bytes --]

In PGTK, child frames may be obscured by scroll-bars. This happens when
the scrollbar is added after the child frame is created (e.g. by
creating new windows, etc.). The bug may in particular affect people
using child-frame-based completion packages, such as corfu, company-
box, or company-posframe.

From what I could see in the code, in contrast to X, PGTK adds child
frames to the parent frame's edit_widget which is a GtkFixed (see "x-
create-frame"). A GtkFixed doesn't have any defined z-order behavior.
However, widgets seem to get drawn in the order of the internal child
list. Unfortunately, there is no direct way to insert widgets at the
front of this list or otherwise manipulate the list apart from pushing
children to the end or removing them. So a (dirty) workaround would be
to remove all children, add the scrollbar and then add all the removed
widgets again, see the patch.
A better solution may involve something like a GtKOverlay but I don't
know if that's practical in the current implementation.

To replicate the bug in 'emacs -Q':
(progn
  (make-frame
   `((title . "childframe")
     (parent-frame . ,(selected-frame))
     (border-width . 3)
     (internal-border-width . 3)
     (child-frame-border-width . 3)
     (vertical-scroll-bars . nil)
     (horizontal-scroll-bars . nil)
     (menu-bar-lines . 0)
     (tool-bar-lines . 0)
     (tab-bar-lines . 0)
     (minibuffer . nil)
     (undecorated . t)
     (left . 0.5)
     (top . 0.5)
     (width . 20)
     (height . 20)
     (left-fringe . 0)
     (right-fringe . 0)
     (background-color . "blue")))
(split-window-right)
(split-window-right))


[-- Attachment #2: 0001-Fix-scroll-bars-obscuring-child-frames-in-PGTK.patch --]
[-- Type: text/x-patch, Size: 2594 bytes --]

From cb820ad1f0bd8d6827d05ec04b7b226fffdab7d8 Mon Sep 17 00:00:00 2001
From: Florian Rommel <mail@florommel.de>
Date: Mon, 15 Aug 2022 16:53:35 +0200
Subject: [PATCH] Fix scroll-bars obscuring child-frames in PGTK

* src/gtkutil.c (xg_finish_scroll_bar_creation, xg_xp_insert_widget):
Insert scroll-bar widget as the first child of the container.
---
 src/gtkutil.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/src/gtkutil.c b/src/gtkutil.c
index a6bba096a4..ac232fccd4 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -4495,6 +4495,50 @@ xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data)
 }
 #endif
 
+/* Workaround: Insert a widget at the front of the edit_widget (GtkFixed).
+   This is necessary for scrollbars to not obscure any child frames. */
+
+#ifdef HAVE_PGTK
+static void
+xg_xp_insert_widget (xp_output *output, GtkWidget *widget)
+{
+  struct widget_pos {
+    gint x;
+    gint y;
+  };
+
+  struct widget_pos *pos;
+  GList *list, *elem;
+  unsigned int idx;
+
+  list = gtk_container_get_children (GTK_CONTAINER (output->edit_widget));
+  pos = xmalloc (sizeof (struct widget_pos) * g_list_length (list));
+
+  for (elem = list, idx = 0; elem; elem = elem->next, idx++)
+    {
+      GtkWidget *w = elem->data;
+      struct widget_pos *p = &pos[idx];
+      gtk_container_child_get (GTK_CONTAINER (output->edit_widget), w,
+                               "x", &p->x, "y", &p->y, NULL);
+      g_object_ref (w);
+      gtk_container_remove (GTK_CONTAINER (output->edit_widget), w);
+    }
+
+  gtk_fixed_put (GTK_FIXED (output->edit_widget), widget, -1, -1);
+
+  for (elem = list, idx = 0; elem; elem = elem->next, idx++)
+    {
+      GtkWidget *w = elem->data;
+      struct widget_pos *p = &pos[idx];
+      gtk_fixed_put (GTK_FIXED (output->edit_widget), w, p->x, p->y);
+      g_object_unref (w);
+    }
+
+  xfree (pos);
+  g_list_free (list);
+}
+#endif
+
 #if defined HAVE_GTK3 && !defined HAVE_PGTK
 static void
 xg_scroll_bar_size_allocate_cb (GtkWidget *widget,
@@ -4571,7 +4615,11 @@ xg_finish_scroll_bar_creation (struct frame *f,
      also, which causes flicker.  Put an event box between the edit widget
      and the scroll bar, so the scroll bar instead draws itself on the
      event box window.  */
+#ifdef HAVE_PGTK
+  xg_xp_insert_widget (f->output_data.xp, webox);
+#else
   gtk_fixed_put (GTK_FIXED (f->output_data.xp->edit_widget), webox, -1, -1);
+#endif
   gtk_container_add (GTK_CONTAINER (webox), wscroll);
 
   xg_set_widget_bg (f, webox, FRAME_BACKGROUND_PIXEL (f));
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* bug#57224: 29.0.50; PGTK: scroll-bar obscures child-frame
  2022-08-15 15:15 bug#57224: 29.0.50; PGTK: scroll-bar obscures child-frame Florian Rommel
@ 2022-08-16  1:00 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 2+ messages in thread
From: Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-08-16  1:00 UTC (permalink / raw)
  To: Florian Rommel; +Cc: 57224

Florian Rommel <mail@florommel.de> writes:

> In PGTK, child frames may be obscured by scroll-bars. This happens when
> the scrollbar is added after the child frame is created (e.g. by
> creating new windows, etc.). The bug may in particular affect people
> using child-frame-based completion packages, such as corfu, company-
> box, or company-posframe.
>
>>From what I could see in the code, in contrast to X, PGTK adds child
> frames to the parent frame's edit_widget which is a GtkFixed (see "x-
> create-frame"). A GtkFixed doesn't have any defined z-order behavior.
> However, widgets seem to get drawn in the order of the internal child
> list. Unfortunately, there is no direct way to insert widgets at the
> front of this list or otherwise manipulate the list apart from pushing
> children to the end or removing them. So a (dirty) workaround would be
> to remove all children, add the scrollbar and then add all the removed
> widgets again, see the patch.
> A better solution may involve something like a GtKOverlay but I don't
> know if that's practical in the current implementation.
>
> To replicate the bug in 'emacs -Q':
> (progn
>   (make-frame
>    `((title . "childframe")
>      (parent-frame . ,(selected-frame))
>      (border-width . 3)
>      (internal-border-width . 3)
>      (child-frame-border-width . 3)
>      (vertical-scroll-bars . nil)
>      (horizontal-scroll-bars . nil)
>      (menu-bar-lines . 0)
>      (tool-bar-lines . 0)
>      (tab-bar-lines . 0)
>      (minibuffer . nil)
>      (undecorated . t)
>      (left . 0.5)
>      (top . 0.5)
>      (width . 20)
>      (height . 20)
>      (left-fringe . 0)
>      (right-fringe . 0)
>      (background-color . "blue")))
> (split-window-right)
> (split-window-right))

Thanks.  I don't think working around the problem by removing GTK
widgets is a particularly good idea, since we could always go down to
the GDK level and use gdk_window_lower (all children of a GtkFixed are
children of its GDK window, like most other GTK container widgets.)

I will look into that, because I think the same problem also exists on
X.





^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-08-16  1:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-15 15:15 bug#57224: 29.0.50; PGTK: scroll-bar obscures child-frame Florian Rommel
2022-08-16  1:00 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.