diff options
| author | Yuuki Harano | 2019-08-01 01:26:55 +0900 |
|---|---|---|
| committer | Jeff Walsh | 2020-11-22 14:46:56 +1100 |
| commit | bc35a1e1d5dbee82391d08c4fca361c7fc77d558 (patch) | |
| tree | 37d8cb8f338ca89c45be7f9642e968acfb2826d4 /src/pgtkselect.c | |
| parent | 24d82638bc674d0c258ed95649fe98b22113d42f (diff) | |
| download | emacs-bc35a1e1d5dbee82391d08c4fca361c7fc77d558.tar.gz emacs-bc35a1e1d5dbee82391d08c4fca361c7fc77d558.zip | |
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 を使えないようにした。
Diffstat (limited to 'src/pgtkselect.c')
| -rw-r--r-- | src/pgtkselect.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/pgtkselect.c b/src/pgtkselect.c index b8854256802..4f4a43da8be 100644 --- a/src/pgtkselect.c +++ b/src/pgtkselect.c | |||
| @@ -200,6 +200,93 @@ void pgtk_selection_lost(GtkWidget *widget, GdkEventSelection *event, gpointer u | |||
| 200 | g_object_set_qdata(G_OBJECT(widget), quark_size, 0); | 200 | g_object_set_qdata(G_OBJECT(widget), quark_size, 0); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | static bool | ||
| 204 | pgtk_selection_usable (void) | ||
| 205 | { | ||
| 206 | /* | ||
| 207 | * https://github.com/GNOME/gtk/blob/gtk-3-24/gdk/wayland/gdkselection-wayland.c#L1033 | ||
| 208 | * | ||
| 209 | * Gdk uses gdk_display_get_default() when handling selections, so | ||
| 210 | * selections don't work properly on multi-display environment. | ||
| 211 | * | ||
| 212 | * ---------------- | ||
| 213 | * #include <gtk/gtk.h> | ||
| 214 | * | ||
| 215 | * static GtkWidget *top1, *top2; | ||
| 216 | * | ||
| 217 | * int main(int argc, char **argv) | ||
| 218 | * { | ||
| 219 | * GtkWidget *w; | ||
| 220 | * GtkTextBuffer *buf; | ||
| 221 | * | ||
| 222 | * gtk_init(&argc, &argv); | ||
| 223 | * | ||
| 224 | * static char *text = "\ | ||
| 225 | * It is fine today.\n\ | ||
| 226 | * It will be fine tomorrow too.\n\ | ||
| 227 | * It is too hot."; | ||
| 228 | * | ||
| 229 | * top1 = gtk_window_new(GTK_WINDOW_TOPLEVEL); | ||
| 230 | * gtk_window_set_title(GTK_WINDOW(top1), "default"); | ||
| 231 | * gtk_widget_show(top1); | ||
| 232 | * w = gtk_text_view_new(); | ||
| 233 | * gtk_container_add(GTK_CONTAINER(top1), w); | ||
| 234 | * gtk_widget_show(w); | ||
| 235 | * buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)); | ||
| 236 | * gtk_text_buffer_insert_at_cursor(buf, text, strlen(text)); | ||
| 237 | * gtk_text_buffer_add_selection_clipboard(buf, gtk_widget_get_clipboard(w, GDK_SELECTION_PRIMARY)); | ||
| 238 | * | ||
| 239 | * unsetenv("GDK_BACKEND"); | ||
| 240 | * GdkDisplay *gdpy; | ||
| 241 | * const char *dpyname2; | ||
| 242 | * if (strcmp(G_OBJECT_TYPE_NAME(gtk_widget_get_window(top1)), "GdkWaylandWindow") == 0) | ||
| 243 | * dpyname2 = ":0"; | ||
| 244 | * else | ||
| 245 | * dpyname2 = "wayland-0"; | ||
| 246 | * gdpy = gdk_display_open (dpyname2); | ||
| 247 | * top2 = gtk_window_new (GTK_WINDOW_TOPLEVEL); | ||
| 248 | * gtk_window_set_title(GTK_WINDOW(top2), dpyname2); | ||
| 249 | * gtk_window_set_screen (GTK_WINDOW (top2), gdk_display_get_default_screen(gdpy)); | ||
| 250 | * gtk_widget_show (top2); | ||
| 251 | * w = gtk_text_view_new(); | ||
| 252 | * gtk_container_add(GTK_CONTAINER(top2), w); | ||
| 253 | * gtk_widget_show(w); | ||
| 254 | * buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)); | ||
| 255 | * gtk_text_buffer_insert_at_cursor(buf, text, strlen(text)); | ||
| 256 | * gtk_text_buffer_add_selection_clipboard(buf, gtk_widget_get_clipboard(w, GDK_SELECTION_PRIMARY)); | ||
| 257 | * | ||
| 258 | * gtk_main(); | ||
| 259 | * | ||
| 260 | * return 0; | ||
| 261 | * } | ||
| 262 | * ---------------- | ||
| 263 | * | ||
| 264 | * This code fails if | ||
| 265 | * GDK_BACKEND=x11 ./test | ||
| 266 | * and select on both of windows. | ||
| 267 | * | ||
| 268 | * ---------------- | ||
| 269 | * (test:15345): GLib-GObject-CRITICAL **: 01:56:38.041: g_object_ref: assertion 'G_IS_OBJECT (object)' failed | ||
| 270 | * | ||
| 271 | * (test:15345): GLib-GObject-CRITICAL **: 01:56:38.042: g_object_ref: assertion 'G_IS_OBJECT (object)' failed | ||
| 272 | * | ||
| 273 | * (test:15345): GLib-GObject-CRITICAL **: 01:56:39.113: g_object_ref: assertion 'G_IS_OBJECT (object)' failed | ||
| 274 | * | ||
| 275 | * (test:15345): GLib-GObject-CRITICAL **: 01:56:39.113: g_object_ref: assertion 'G_IS_OBJECT (object)' failed | ||
| 276 | * ---------------- | ||
| 277 | * (gtk-3.24.10) | ||
| 278 | * | ||
| 279 | * This function checks whether selections work by the number of displays. | ||
| 280 | * If you use more than 2 displays, then selection is disabled. | ||
| 281 | */ | ||
| 282 | |||
| 283 | GdkDisplayManager *dpyman = gdk_display_manager_get (); | ||
| 284 | GSList *list = gdk_display_manager_list_displays (dpyman); | ||
| 285 | int len = g_slist_length (list); | ||
| 286 | g_slist_free (list); | ||
| 287 | return len < 2; | ||
| 288 | } | ||
| 289 | |||
| 203 | /* ========================================================================== | 290 | /* ========================================================================== |
| 204 | 291 | ||
| 205 | Lisp Defuns | 292 | Lisp Defuns |
| @@ -228,6 +315,9 @@ nil, it defaults to the selected frame.*/) | |||
| 228 | 315 | ||
| 229 | check_window_system (NULL); | 316 | check_window_system (NULL); |
| 230 | 317 | ||
| 318 | if (!pgtk_selection_usable ()) | ||
| 319 | return Qnil; | ||
| 320 | |||
| 231 | if (NILP (frame)) frame = selected_frame; | 321 | if (NILP (frame)) frame = selected_frame; |
| 232 | if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_PGTK_P (XFRAME (frame))) | 322 | if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_PGTK_P (XFRAME (frame))) |
| 233 | error ("pgtk selection unavailable for this frame"); | 323 | error ("pgtk selection unavailable for this frame"); |
| @@ -308,6 +398,9 @@ On PGTK, the TIME-OBJECT is unused. */) | |||
| 308 | struct frame *f = frame_for_pgtk_selection (terminal); | 398 | struct frame *f = frame_for_pgtk_selection (terminal); |
| 309 | GtkClipboard *cb; | 399 | GtkClipboard *cb; |
| 310 | 400 | ||
| 401 | if (!pgtk_selection_usable ()) | ||
| 402 | return Qnil; | ||
| 403 | |||
| 311 | if (!f) | 404 | if (!f) |
| 312 | return Qnil; | 405 | return Qnil; |
| 313 | 406 | ||
| @@ -337,6 +430,9 @@ On Nextstep, TERMINAL is unused. */) | |||
| 337 | struct frame *f = frame_for_pgtk_selection (terminal); | 430 | struct frame *f = frame_for_pgtk_selection (terminal); |
| 338 | GtkClipboard *cb; | 431 | GtkClipboard *cb; |
| 339 | 432 | ||
| 433 | if (!pgtk_selection_usable ()) | ||
| 434 | return Qnil; | ||
| 435 | |||
| 340 | if (!f) | 436 | if (!f) |
| 341 | return Qnil; | 437 | return Qnil; |
| 342 | 438 | ||
| @@ -368,6 +464,9 @@ On Nextstep, TERMINAL is unused. */) | |||
| 368 | GObject *obj; | 464 | GObject *obj; |
| 369 | GQuark quark_data, quark_size; | 465 | GQuark quark_data, quark_size; |
| 370 | 466 | ||
| 467 | if (!pgtk_selection_usable ()) | ||
| 468 | return Qnil; | ||
| 469 | |||
| 371 | cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection); | 470 | cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection); |
| 372 | selection_type_to_quarks(gtk_clipboard_get_selection(cb), &quark_data, &quark_size); | 471 | selection_type_to_quarks(gtk_clipboard_get_selection(cb), &quark_data, &quark_size); |
| 373 | 472 | ||
| @@ -406,6 +505,9 @@ On PGTK, TIME-STAMP is unused. */) | |||
| 406 | if (!f) | 505 | if (!f) |
| 407 | error ("PGTK selection unavailable for this frame"); | 506 | error ("PGTK selection unavailable for this frame"); |
| 408 | 507 | ||
| 508 | if (!pgtk_selection_usable ()) | ||
| 509 | return Qnil; | ||
| 510 | |||
| 409 | cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection_symbol); | 511 | cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection_symbol); |
| 410 | 512 | ||
| 411 | gchar *s = gtk_clipboard_wait_for_text(cb); | 513 | gchar *s = gtk_clipboard_wait_for_text(cb); |