mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-09 05:01:02 -08:00
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 を使えないようにした。
This commit is contained in:
parent
24d82638bc
commit
bc35a1e1d5
2 changed files with 121 additions and 16 deletions
102
src/pgtkselect.c
102
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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue