# HG changeset patch # User Christian Brabandt # Date 1706559303 -3600 # Node ID fdc8a179c79e7533b3a102ab2e8f31f74d6ed125 # Parent 0c1f955375c4981d57de39ed54673e6e0c64c858 patch 9.1.0063: GTK code can be improved Commit: https://github.com/vim/vim/commit/94ff09a0935bc78fd81e9c79f099d42c94e3c218 Author: lilydjwg Date: Mon Jan 29 20:14:01 2024 +0100 patch 9.1.0063: GTK code can be improved Problem: GTK code can be improved Solution: Improve GTK code for initial Wayland support (lilydjwg) related: #9639 Signed-off-by: lilydjwg Signed-off-by: Christian Brabandt diff --git a/src/clipboard.c b/src/clipboard.c --- a/src/clipboard.c +++ b/src/clipboard.c @@ -1334,7 +1334,8 @@ did_set_clipboard(optset_T *args UNUSED) #ifdef FEAT_GUI_GTK if (gui.in_use) { - gui_gtk_set_selection_targets(); + gui_gtk_set_selection_targets((GdkAtom)GDK_SELECTION_PRIMARY); + gui_gtk_set_selection_targets((GdkAtom)clip_plus.gtk_sel_atom); gui_gtk_set_dnd_targets(); } #endif diff --git a/src/gui_beval.c b/src/gui_beval.c --- a/src/gui_beval.c +++ b/src/gui_beval.c @@ -1011,6 +1011,7 @@ cancelBalloon(BalloonEval *beval) createBalloonEvalWindow(BalloonEval *beval) { beval->balloonShell = gtk_window_new(GTK_WINDOW_POPUP); + gtk_window_set_transient_for(GTK_WINDOW(beval->balloonShell), GTK_WINDOW(gui.mainwin)); gtk_widget_set_app_paintable(beval->balloonShell, TRUE); gtk_window_set_resizable(GTK_WINDOW(beval->balloonShell), FALSE); diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -116,6 +116,7 @@ enum TARGET_TEXT, TARGET_TEXT_URI_LIST, TARGET_TEXT_PLAIN, + TARGET_TEXT_PLAIN_UTF8, TARGET_VIM, TARGET_VIMENC }; @@ -132,7 +133,9 @@ static const GtkTargetEntry selection_ta {"UTF8_STRING", 0, TARGET_UTF8_STRING}, {"COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT}, {"TEXT", 0, TARGET_TEXT}, - {"STRING", 0, TARGET_STRING} + {"STRING", 0, TARGET_STRING}, + {"text/plain;charset=utf-8", 0, TARGET_TEXT_PLAIN_UTF8}, + {"text/plain", 0, TARGET_TEXT_PLAIN} }; #define N_SELECTION_TARGETS ARRAY_LENGTH(selection_targets) @@ -1531,6 +1534,8 @@ selection_get_cb(GtkWidget *widget U && info != (guint)TARGET_VIMENC && info != (guint)TARGET_VIM && info != (guint)TARGET_COMPOUND_TEXT + && info != (guint)TARGET_TEXT_PLAIN + && info != (guint)TARGET_TEXT_PLAIN_UTF8 && info != (guint)TARGET_TEXT) return; @@ -3536,30 +3541,28 @@ gui_mch_set_curtab(int nr) * Add selection targets for PRIMARY and CLIPBOARD selections. */ void -gui_gtk_set_selection_targets(void) +gui_gtk_set_selection_targets(GdkAtom selection) { int i, j = 0; - int n_targets = N_SELECTION_TARGETS; - GtkTargetEntry targets[N_SELECTION_TARGETS]; - - for (i = 0; i < (int)N_SELECTION_TARGETS; ++i) - { - // OpenOffice tries to use TARGET_HTML and fails when we don't - // return something, instead of trying another target. Therefore only - // offer TARGET_HTML when it works. - if (!clip_html && selection_targets[i].info == TARGET_HTML) - n_targets--; - else - targets[j++] = selection_targets[i]; - } - - gtk_selection_clear_targets(gui.drawarea, (GdkAtom)GDK_SELECTION_PRIMARY); - gtk_selection_clear_targets(gui.drawarea, (GdkAtom)clip_plus.gtk_sel_atom); - gtk_selection_add_targets(gui.drawarea, - (GdkAtom)GDK_SELECTION_PRIMARY, - targets, n_targets); - gtk_selection_add_targets(gui.drawarea, - (GdkAtom)clip_plus.gtk_sel_atom, + static int n_targets = N_SELECTION_TARGETS; + static GtkTargetEntry targets[N_SELECTION_TARGETS]; + + if (targets[0].target == NULL) + { + for (i = 0; i < (int)N_SELECTION_TARGETS; ++i) + { + // OpenOffice tries to use TARGET_HTML and fails when we don't + // return something, instead of trying another target. Therefore only + // offer TARGET_HTML when it works. + if (!clip_html && selection_targets[i].info == TARGET_HTML) + n_targets--; + else + targets[j++] = selection_targets[i]; + } + } + + gtk_selection_clear_targets(gui.drawarea, selection); + gtk_selection_add_targets(gui.drawarea, selection, targets, n_targets); } @@ -4035,20 +4038,7 @@ gui_mch_init(void) g_signal_connect(G_OBJECT(gui.drawarea), "button-release-event", G_CALLBACK(button_release_event), NULL); g_signal_connect(G_OBJECT(gui.drawarea), "scroll-event", - G_CALLBACK(&scroll_event), NULL); - - /* - * Add selection handler functions. - */ - g_signal_connect(G_OBJECT(gui.drawarea), "selection-clear-event", - G_CALLBACK(selection_clear_event), NULL); - g_signal_connect(G_OBJECT(gui.drawarea), "selection-received", - G_CALLBACK(selection_received_cb), NULL); - - gui_gtk_set_selection_targets(); - - g_signal_connect(G_OBJECT(gui.drawarea), "selection-get", - G_CALLBACK(selection_get_cb), NULL); + G_CALLBACK(scroll_event), NULL); // Pretend we don't have input focus, we will get an event if we do. gui.in_focus = FALSE; @@ -4582,6 +4572,17 @@ gui_mch_open(void) #endif } + /* + * Add selection handler functions. + */ + g_signal_connect(G_OBJECT(gui.drawarea), "selection-clear-event", + G_CALLBACK(selection_clear_event), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "selection-received", + G_CALLBACK(selection_received_cb), NULL); + + g_signal_connect(G_OBJECT(gui.drawarea), "selection-get", + G_CALLBACK(selection_get_cb), NULL); + return OK; } @@ -6938,10 +6939,18 @@ clip_mch_lose_selection(Clipboard_T *cbd int clip_mch_own_selection(Clipboard_T *cbd) { + // If we're blocking autocmds, we are filling the register to offer the + // selection (inside selection-get) + if (is_autocmd_blocked()) + return OK; + int success; success = gtk_selection_owner_set(gui.drawarea, cbd->gtk_sel_atom, gui.event_time); + // don't update on every visual selection change + if (!(cbd->owned && VIsual_active)) + gui_gtk_set_selection_targets(cbd->gtk_sel_atom); gui_mch_update(); return (success) ? OK : FAIL; } diff --git a/src/proto/gui_gtk_x11.pro b/src/proto/gui_gtk_x11.pro --- a/src/proto/gui_gtk_x11.pro +++ b/src/proto/gui_gtk_x11.pro @@ -13,7 +13,7 @@ void gui_mch_show_tabline(int showit); int gui_mch_showing_tabline(void); void gui_mch_update_tabline(void); void gui_mch_set_curtab(int nr); -void gui_gtk_set_selection_targets(void); +void gui_gtk_set_selection_targets(GdkAtom); void gui_gtk_set_dnd_targets(void); int gui_mch_init(void); void gui_mch_forked(void); diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -526,7 +526,9 @@ func Test_geometry() " might be a bit different, allow for some tolerance. Tuned based on " actual failures. call assert_inrange(31, 35, str2nr(lines[0])) - call assert_equal('13', lines[1]) + " for some reason, the window may contain fewer lines than requested + " for GTK, so allow some tolerance + call assert_inrange(8, 13, str2nr(lines[1])) call assert_equal('41', lines[2]) call assert_equal('150', lines[3]) call assert_equal('[41, 150]', lines[4]) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -705,6 +705,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 63, +/**/ 62, /**/ 61,