unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Po Lu via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: 51736@debbugs.gnu.org
Subject: bug#51736: 29.0.50; [PATCH] Fix context menus appearing in the wrong location in xwidgets
Date: Wed, 10 Nov 2021 09:24:54 +0800	[thread overview]
Message-ID: <8735o4yf89.fsf@yahoo.com> (raw)
In-Reply-To: 8735o4yf89.fsf.ref@yahoo.com

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

Thanks.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Set-embedder-correctly-to-fix-menus-appearing-in-the.patch --]
[-- Type: text/x-patch, Size: 6221 bytes --]

From 6b6628065b18b1df313465f423b45fb516426811 Mon Sep 17 00:00:00 2001
From: Po Lu <luangruo@yahoo.com>
Date: Wed, 10 Nov 2021 09:22:38 +0800
Subject: [PATCH] Set embedder correctly to fix menus appearing in the wrong
 location

* src/xwidget.c (record_osr_embedder, from_embedder, to_embedder): New
functions.
(Fmake_xwidget): Attach from-embedder and to-embedder signals.
(find_widget_for_offscreen_window): New function.
(xwidget_button, xwidget_motion_or_crossing): Set embedder on event.
(Fdelete_xwidget_view): Remove embedder status if applicable.

* src/xwidget.h (struct xwidget): New fields `embedder' and
`embedder-view'.
---
 src/xwidget.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/xwidget.h |   2 +
 2 files changed, 127 insertions(+)

diff --git a/src/xwidget.c b/src/xwidget.c
index 2587b658e7..d5a0a7879d 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -52,6 +52,9 @@ Copyright (C) 2011-2021 Free Software Foundation, Inc.
 static GdkDevice *find_suitable_keyboard (struct frame *);
 static gboolean webkit_script_dialog_cb (WebKitWebView *, WebKitScriptDialog *,
 					 gpointer);
+static void record_osr_embedder (struct xwidget_view *);
+static void from_embedder (GdkWindow *, double, double, gpointer, gpointer, gpointer);
+static void to_embedder (GdkWindow *, double, double, gpointer, gpointer, gpointer);
 #endif
 
 static struct xwidget *
@@ -215,6 +218,12 @@ DEFUN ("make-xwidget",
       gtk_widget_show (xw->widgetwindow_osr);
       synthesize_focus_in_event (xw->widgetwindow_osr);
 
+
+      g_signal_connect (G_OBJECT (gtk_widget_get_window (xw->widgetwindow_osr)),
+			"from-embedder", G_CALLBACK (from_embedder), NULL);
+      g_signal_connect (G_OBJECT (gtk_widget_get_window (xw->widgetwindow_osr)),
+			"to-embedder", G_CALLBACK (to_embedder), NULL);
+
       /* Store some xwidget data in the gtk widgets for convenient
          retrieval in the event handlers.  */
       g_object_set_data (G_OBJECT (xw->widget_osr), XG_XWIDGET, xw);
@@ -457,6 +466,106 @@ xwidget_from_id (uint32_t id)
 }
 
 #ifdef USE_GTK
+static void
+record_osr_embedder (struct xwidget_view *view)
+{
+  struct xwidget *xw;
+  GdkWindow *window, *embedder;
+
+  xw = XXWIDGET (view->model);
+  window = gtk_widget_get_window (xw->widgetwindow_osr);
+  embedder = gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (view->frame));
+
+  gdk_offscreen_window_set_embedder (window, embedder);
+  xw->embedder = view->frame;
+  xw->embedder_view = view;
+}
+
+static struct xwidget *
+find_xwidget_for_offscreen_window (GdkWindow *window)
+{
+  Lisp_Object tem;
+  struct xwidget *xw;
+  GdkWindow *w;
+
+  for (tem = Vxwidget_list; CONSP (tem); tem = XCDR (tem))
+    {
+      if (XWIDGETP (XCAR (tem)))
+	{
+	  xw = XXWIDGET (XCAR (tem));
+	  w = gtk_widget_get_window (xw->widgetwindow_osr);
+
+	  if (w == window)
+	    return xw;
+	}
+    }
+
+  return NULL;
+}
+
+static void
+from_embedder (GdkWindow *window, double x, double y,
+	       gpointer x_out_ptr, gpointer y_out_ptr,
+	       gpointer user_data)
+{
+  double *xout = x_out_ptr;
+  double *yout = y_out_ptr;
+  struct xwidget *xw = find_xwidget_for_offscreen_window (window);
+  struct xwidget_view *xvw;
+  gint xoff, yoff;
+
+  if (!xw)
+    emacs_abort ();
+
+  xvw = xw->embedder_view;
+
+  if (!xvw)
+    {
+      *xout = x;
+      *yout = y;
+    }
+  else
+    {
+      gtk_widget_translate_coordinates (FRAME_GTK_WIDGET (xvw->frame),
+					FRAME_GTK_OUTER_WIDGET (xvw->frame),
+					0, 0, &xoff, &yoff);
+
+      *xout = x - (xvw->x + xvw->clip_left) - xoff;
+      *yout = y - (xvw->y + xvw->clip_top) - yoff;
+    }
+}
+
+static void
+to_embedder (GdkWindow *window, double x, double y,
+	     gpointer x_out_ptr, gpointer y_out_ptr,
+	     gpointer user_data)
+{
+  double *xout = x_out_ptr;
+  double *yout = y_out_ptr;
+  struct xwidget *xw = find_xwidget_for_offscreen_window (window);
+  struct xwidget_view *xvw;
+  gint xoff, yoff;
+
+  if (!xw)
+    emacs_abort ();
+
+  xvw = xw->embedder_view;
+
+  if (!xvw)
+    {
+      *xout = x;
+      *yout = y;
+    }
+  else
+    {
+      gtk_widget_translate_coordinates (FRAME_GTK_WIDGET (xvw->frame),
+					FRAME_GTK_OUTER_WIDGET (xvw->frame),
+					0, 0, &xoff, &yoff);
+
+      *xout = x + xvw->x + xvw->clip_left + xoff;
+      *yout = y + xvw->y + xvw->clip_top + yoff;
+    }
+}
 
 static GdkDevice *
 find_suitable_pointer (struct frame *f)
@@ -697,6 +806,8 @@ xwidget_button (struct xwidget_view *view,
 		bool down_p, int x, int y, int button,
 		int modifier_state, Time time)
 {
+  record_osr_embedder (view);
+
   if (button < 4 || button > 8)
     xwidget_button_1 (view, down_p, x, y, button, modifier_state, time);
   else
@@ -765,6 +876,7 @@ xwidget_motion_or_crossing (struct xwidget_view *view, const XEvent *event)
   if (!target)
     target = model->widget_osr;
 
+  record_osr_embedder (view);
   xg_event->any.window = gtk_widget_get_window (target);
   g_object_ref (xg_event->any.window); /* The window will be unrefed
 					  later by gdk_event_free.  */
@@ -1865,6 +1977,9 @@ DEFUN ("delete-xwidget-view",
   CHECK_XWIDGET_VIEW (xwidget_view);
   struct xwidget_view *xv = XXWIDGET_VIEW (xwidget_view);
 #ifdef USE_GTK
+  struct xwidget *xw = XXWIDGET (xv->model);
+  GdkWindow *w;
+
   if (xv->wdesc != None)
     {
       block_input ();
@@ -1874,6 +1989,16 @@ DEFUN ("delete-xwidget-view",
       Fremhash (make_fixnum (xv->wdesc), x_window_to_xwv_map);
       unblock_input ();
     }
+
+  if (xw->embedder_view == xv)
+    {
+      w = gtk_widget_get_window (xw->widgetwindow_osr);
+
+      XXWIDGET (xv->model)->embedder_view = NULL;
+      XXWIDGET (xv->model)->embedder = NULL;
+
+      gdk_offscreen_window_set_embedder (w, NULL);
+    }
 #elif defined NS_IMPL_COCOA
   nsxwidget_delete_view (xv);
 #endif
diff --git a/src/xwidget.h b/src/xwidget.h
index ad8b7c039c..6e6b39c8b4 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -68,6 +68,8 @@ #define XWIDGET_H_INCLUDED
   /* For offscreen widgets, unused if not osr.  */
   GtkWidget *widget_osr;
   GtkWidget *widgetwindow_osr;
+  struct frame *embedder;
+  struct xwidget_view *embedder_view;
   guint hit_result;
 #elif defined (NS_IMPL_COCOA)
 # ifdef __OBJC__
-- 
2.31.1


       reply	other threads:[~2021-11-10  1:24 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <8735o4yf89.fsf.ref@yahoo.com>
2021-11-10  1:24 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2021-11-10  5:30   ` bug#51736: Re: 29.0.50; [PATCH] Fix context menus appearing in the wrong location in xwidgets Po Lu
2021-11-10  5:57     ` Lars Ingebrigtsen
2021-11-10  5:59       ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-11-10  6:01         ` Lars Ingebrigtsen
2021-11-10  6:02           ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-11-10  6:04             ` Lars Ingebrigtsen
2021-11-10  5:57     ` bug#51736: " Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8735o4yf89.fsf@yahoo.com \
    --to=bug-gnu-emacs@gnu.org \
    --cc=51736@debbugs.gnu.org \
    --cc=luangruo@yahoo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).