[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/pgtk bc35a1e 032/100: Make multipdisplay work by limiting select
From: |
Yuuki Harano |
Subject: |
feature/pgtk bc35a1e 032/100: Make multipdisplay work by limiting selection while enabed |
Date: |
Tue, 24 Nov 2020 08:02:31 -0500 (EST) |
branch: feature/pgtk
commit bc35a1e1d5dbee82391d08c4fca361c7fc77d558
Author: Yuuki Harano <masm+github@masm11.me>
Commit: Jeff Walsh <fejfighter@gmail.com>
Make multipdisplay work by limiting selection while enabed
* src/pgtkterm.c (pgtk_mouse_position):
* src/pgtkselect.c (pgtk_selection_usable): new function
(Fpgtk_own_selection_internal, Fpgtk_disown_selection_internal)
(Fpgtk_selection_exists_p, Fpgtk_selection_owner_p)
(Fpgtk_get_selection_internal): check usable selection
multi-display で落ちる理由を一つ潰した。
まだまだありそう。
multi-display 時は selection を使えないようにした。
---
src/pgtkselect.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/pgtkterm.c | 35 ++++++++++---------
2 files changed, 121 insertions(+), 16 deletions(-)
diff --git a/src/pgtkselect.c b/src/pgtkselect.c
index b885425..4f4a43d 100644
--- a/src/pgtkselect.c
+++ b/src/pgtkselect.c
@@ -200,6 +200,93 @@ void pgtk_selection_lost(GtkWidget *widget,
GdkEventSelection *event, gpointer u
g_object_set_qdata(G_OBJECT(widget), quark_size, 0);
}
+static bool
+pgtk_selection_usable (void)
+{
+ /*
+ *
https://github.com/GNOME/gtk/blob/gtk-3-24/gdk/wayland/gdkselection-wayland.c#L1033
+ *
+ * Gdk uses gdk_display_get_default() when handling selections, so
+ * selections don't work properly on multi-display environment.
+ *
+ * ----------------
+ * #include <gtk/gtk.h>
+ *
+ * static GtkWidget *top1, *top2;
+ *
+ * int main(int argc, char **argv)
+ * {
+ * GtkWidget *w;
+ * GtkTextBuffer *buf;
+ *
+ * gtk_init(&argc, &argv);
+ *
+ * static char *text = "\
+ * It is fine today.\n\
+ * It will be fine tomorrow too.\n\
+ * It is too hot.";
+ *
+ * top1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ * gtk_window_set_title(GTK_WINDOW(top1), "default");
+ * gtk_widget_show(top1);
+ * w = gtk_text_view_new();
+ * gtk_container_add(GTK_CONTAINER(top1), w);
+ * gtk_widget_show(w);
+ * buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
+ * gtk_text_buffer_insert_at_cursor(buf, text, strlen(text));
+ * gtk_text_buffer_add_selection_clipboard(buf,
gtk_widget_get_clipboard(w, GDK_SELECTION_PRIMARY));
+ *
+ * unsetenv("GDK_BACKEND");
+ * GdkDisplay *gdpy;
+ * const char *dpyname2;
+ * if (strcmp(G_OBJECT_TYPE_NAME(gtk_widget_get_window(top1)),
"GdkWaylandWindow") == 0)
+ * dpyname2 = ":0";
+ * else
+ * dpyname2 = "wayland-0";
+ * gdpy = gdk_display_open (dpyname2);
+ * top2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ * gtk_window_set_title(GTK_WINDOW(top2), dpyname2);
+ * gtk_window_set_screen (GTK_WINDOW (top2),
gdk_display_get_default_screen(gdpy));
+ * gtk_widget_show (top2);
+ * w = gtk_text_view_new();
+ * gtk_container_add(GTK_CONTAINER(top2), w);
+ * gtk_widget_show(w);
+ * buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
+ * gtk_text_buffer_insert_at_cursor(buf, text, strlen(text));
+ * gtk_text_buffer_add_selection_clipboard(buf,
gtk_widget_get_clipboard(w, GDK_SELECTION_PRIMARY));
+ *
+ * gtk_main();
+ *
+ * return 0;
+ * }
+ * ----------------
+ *
+ * This code fails if
+ * GDK_BACKEND=x11 ./test
+ * and select on both of windows.
+ *
+ * ----------------
+ * (test:15345): GLib-GObject-CRITICAL **: 01:56:38.041: g_object_ref:
assertion 'G_IS_OBJECT (object)' failed
+ *
+ * (test:15345): GLib-GObject-CRITICAL **: 01:56:38.042: g_object_ref:
assertion 'G_IS_OBJECT (object)' failed
+ *
+ * (test:15345): GLib-GObject-CRITICAL **: 01:56:39.113: g_object_ref:
assertion 'G_IS_OBJECT (object)' failed
+ *
+ * (test:15345): GLib-GObject-CRITICAL **: 01:56:39.113: g_object_ref:
assertion 'G_IS_OBJECT (object)' failed
+ * ----------------
+ * (gtk-3.24.10)
+ *
+ * This function checks whether selections work by the number of displays.
+ * If you use more than 2 displays, then selection is disabled.
+ */
+
+ GdkDisplayManager *dpyman = gdk_display_manager_get ();
+ GSList *list = gdk_display_manager_list_displays (dpyman);
+ int len = g_slist_length (list);
+ g_slist_free (list);
+ return len < 2;
+}
+
/* ==========================================================================
Lisp Defuns
@@ -228,6 +315,9 @@ nil, it defaults to the selected frame.*/)
check_window_system (NULL);
+ if (!pgtk_selection_usable ())
+ return Qnil;
+
if (NILP (frame)) frame = selected_frame;
if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_PGTK_P (XFRAME (frame)))
error ("pgtk selection unavailable for this frame");
@@ -308,6 +398,9 @@ On PGTK, the TIME-OBJECT is unused. */)
struct frame *f = frame_for_pgtk_selection (terminal);
GtkClipboard *cb;
+ if (!pgtk_selection_usable ())
+ return Qnil;
+
if (!f)
return Qnil;
@@ -337,6 +430,9 @@ On Nextstep, TERMINAL is unused. */)
struct frame *f = frame_for_pgtk_selection (terminal);
GtkClipboard *cb;
+ if (!pgtk_selection_usable ())
+ return Qnil;
+
if (!f)
return Qnil;
@@ -368,6 +464,9 @@ On Nextstep, TERMINAL is unused. */)
GObject *obj;
GQuark quark_data, quark_size;
+ if (!pgtk_selection_usable ())
+ return Qnil;
+
cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection);
selection_type_to_quarks(gtk_clipboard_get_selection(cb), &quark_data,
&quark_size);
@@ -406,6 +505,9 @@ On PGTK, TIME-STAMP is unused. */)
if (!f)
error ("PGTK selection unavailable for this frame");
+ if (!pgtk_selection_usable ())
+ return Qnil;
+
cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection_symbol);
gchar *s = gtk_clipboard_wait_for_text(cb);
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 50ee31e..92f1409 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -2975,6 +2975,8 @@ pgtk_mouse_position (struct frame **fp, int insist,
Lisp_Object *bar_window,
int win_x, win_y;
GdkSeat *seat;
GdkDevice *device;
+ GdkModifierType mask;
+ GdkWindow *win;
block_input ();
@@ -2988,32 +2990,33 @@ pgtk_mouse_position (struct frame **fp, int insist,
Lisp_Object *bar_window,
dpyinfo->last_mouse_scroll_bar = NULL;
- seat = gdk_display_get_default_seat(dpyinfo->gdpy);
- device = gdk_seat_get_pointer(seat);
-
if (gui_mouse_grabbed (dpyinfo)) {
- GdkWindow *win;
- GdkModifierType mask;
- /* get x, y relative to edit window of f1. */
+ /* 1.1. use last_mouse_frame as frame where the pointer is on. */
f1 = dpyinfo->last_mouse_frame;
- win = gtk_widget_get_window(FRAME_GTK_WIDGET(f1));
- win = gdk_window_get_device_position(win, device, &win_x, &win_y, &mask);
} else {
- GdkWindow *win;
- GdkModifierType mask;
- /* 1. get frame where the pointer is on. */
+ f1 = *fp;
+ /* 1.2. get frame where the pointer is on. */
win = gtk_widget_get_window(FRAME_GTK_WIDGET(*fp));
+ seat = gdk_display_get_default_seat(dpyinfo->gdpy);
+ device = gdk_seat_get_pointer(seat);
win = gdk_window_get_device_position(win, device, &win_x, &win_y, &mask);
if (win != NULL)
f1 = pgtk_any_window_to_frame(win);
- else
+ else {
+ // crossing display server?
f1 = SELECTED_FRAME();
-
- /* 2. get x, y relative to edit window of the frame. */
- win = gtk_widget_get_window(FRAME_GTK_WIDGET(f1));
- win = gdk_window_get_device_position(win, device, &win_x, &win_y, &mask);
+ }
}
+ /* 2. get the display and the device. */
+ win = gtk_widget_get_window(FRAME_GTK_WIDGET(f1));
+ GdkDisplay *gdpy = gdk_window_get_display (win);
+ seat = gdk_display_get_default_seat(gdpy);
+ device = gdk_seat_get_pointer(seat);
+
+ /* 3. get x, y relative to edit window of the frame. */
+ win = gdk_window_get_device_position(win, device, &win_x, &win_y, &mask);
+
if (f1 != NULL) {
dpyinfo = FRAME_DISPLAY_INFO (f1);
remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
- feature/pgtk 640f770 088/100: Fix mouse cursor doesn't appear on motion events on xwidgets, (continued)
- feature/pgtk 640f770 088/100: Fix mouse cursor doesn't appear on motion events on xwidgets, Yuuki Harano, 2020/11/24
- feature/pgtk d437aab 092/100: Avoid gtk warnings on X, Yuuki Harano, 2020/11/24
- feature/pgtk 886fcb2 096/100: Update copyright dates for PGTK files, Yuuki Harano, 2020/11/24
- feature/pgtk d6ef9af 100/100: Fix crash when .schema.xml is not installed, Yuuki Harano, 2020/11/24
- feature/pgtk 12cc104 009/100: Cleanup x_* to gui_ to match upstream work, Yuuki Harano, 2020/11/24
- feature/pgtk fde74fa 028/100: implement pgtk-frame-list-z-order same as frame-list., Yuuki Harano, 2020/11/24
- feature/pgtk c9e6b44 044/100: Some work toward posframe on wayland, Yuuki Harano, 2020/11/24
- feature/pgtk 964dfcf 062/100: * src/pgtkgui.h: change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk da3c351 019/100: border_color/pixel width, Yuuki Harano, 2020/11/24
- feature/pgtk 014d56f 052/100: * src/pgtkterm.c: Remove incorrect mark_object call., Yuuki Harano, 2020/11/24
- feature/pgtk bc35a1e 032/100: Make multipdisplay work by limiting selection while enabed,
Yuuki Harano <=
- feature/pgtk d68633b 056/100: * src/pgtkterm.c (pgtk_defined_color): support gtk special colors, Yuuki Harano, 2020/11/24
- feature/pgtk 6957f94 024/100: Add PGTK support for fullscreen, Yuuki Harano, 2020/11/24
- feature/pgtk ae3bb14 029/100: implement restacking and cleanup frame z order, Yuuki Harano, 2020/11/24
- feature/pgtk 49645df 047/100: minimize gtkutil.c differences., Yuuki Harano, 2020/11/24
- feature/pgtk d2a29e8 040/100: emacsclient should use both of DISPLAY and WAYLAND_DISPLAY., Yuuki Harano, 2020/11/24
- feature/pgtk be47e34 077/100: Re-port image drawing code from X, Yuuki Harano, 2020/11/24
- feature/pgtk 0b69b73 085/100: Fix crash when child frame updates toolbar, Yuuki Harano, 2020/11/24
- feature/pgtk 1d549fa 015/100: Add support for make-frame-(in)visible, Yuuki Harano, 2020/11/24
- feature/pgtk 19da22e 018/100: Add support for handing the internal border, Yuuki Harano, 2020/11/24
- feature/pgtk e021e23 043/100: End Resize flickering by copying surface rather than just clearing, Yuuki Harano, 2020/11/24