@@ -3076,10 +3076,16 @@ drawarea_unrealize_cb(GtkWidget *widget UNUSED, gpointer data UNUSED)
30763076 gui .blank_pointer = NULL ;
30773077}
30783078
3079+ #if GTK_CHECK_VERSION (3 ,22 ,2 )
3080+ static void
3081+ drawarea_style_updated_cb (GtkWidget * widget UNUSED ,
3082+ gpointer data UNUSED )
3083+ #else
30793084 static void
30803085drawarea_style_set_cb (GtkWidget * widget UNUSED ,
30813086 GtkStyle * previous_style UNUSED ,
30823087 gpointer data UNUSED )
3088+ #endif
30833089{
30843090 gui_mch_new_colors ();
30853091}
@@ -3096,6 +3102,31 @@ drawarea_configure_event_cb(GtkWidget *widget,
30963102 g_return_val_if_fail (event
30973103 && event -> width >= 1 && event -> height >= 1 , TRUE);
30983104
3105+ # if GTK_CHECK_VERSION (3 ,22 ,2 )
3106+ /* As of 3.22.2, GdkWindows have started distributing configure events to
3107+ * their "native" children (https://git.gnome.org/browse/gtk+/commit/?h=gtk-3-22&id=12579fe71b3b8f79eb9c1b80e429443bcc437dd0).
3108+ *
3109+ * As can be seen from the implementation of move_native_children() and
3110+ * configure_native_child() in gdkwindow.c, those functions actually
3111+ * propagate configure events to every child, failing to distinguish
3112+ * "native" one from non-native one.
3113+ *
3114+ * Naturally, configure events propagated to here like that are fallacious
3115+ * and, as a matter of fact, they trigger a geometric collapse of
3116+ * gui.drawarea in fullscreen and miximized modes.
3117+ *
3118+ * To filter out such nuisance events, we are making use of the fact that
3119+ * the field send_event of such GdkEventConfigures is set to FALSE in
3120+ * configure_native_child().
3121+ *
3122+ * Obviously, this is a terrible hack making GVim depend on GTK's
3123+ * implementation details. Therefore, watch out any relevant internal
3124+ * changes happening in GTK in the feature (sigh).
3125+ */
3126+ if (event -> send_event == FALSE)
3127+ return TRUE;
3128+ # endif
3129+
30993130 if (event -> width == cur_width && event -> height == cur_height )
31003131 return TRUE;
31013132
@@ -3519,8 +3550,12 @@ on_tabline_menu(GtkWidget *widget, GdkEvent *event)
35193550 /* If the event was generated for 3rd button popup the menu. */
35203551 if (bevent -> button == 3 )
35213552 {
3553+ # if GTK_CHECK_VERSION (3 ,22 ,2 )
3554+ gtk_menu_popup_at_pointer (GTK_MENU (widget ), event );
3555+ # else
35223556 gtk_menu_popup (GTK_MENU (widget ), NULL , NULL , NULL , NULL ,
35233557 bevent -> button , bevent -> time );
3558+ # endif
35243559 /* We handled the event. */
35253560 return TRUE;
35263561 }
@@ -4116,6 +4151,9 @@ gui_mch_init(void)
41164151#endif
41174152
41184153 gui .drawarea = gtk_drawing_area_new ();
4154+ #if GTK_CHECK_VERSION (3 ,22 ,2 )
4155+ gtk_widget_set_name (gui .drawarea , "vim-gui-drawarea" );
4156+ #endif
41194157#if GTK_CHECK_VERSION (3 ,0 ,0 )
41204158 gui .surface = NULL ;
41214159 gui .by_signal = FALSE;
@@ -4167,8 +4205,13 @@ gui_mch_init(void)
41674205 G_CALLBACK (drawarea_unrealize_cb ), NULL );
41684206 g_signal_connect (G_OBJECT (gui .drawarea ), "configure-event" ,
41694207 G_CALLBACK (drawarea_configure_event_cb ), NULL );
4208+ # if GTK_CHECK_VERSION (3 ,22 ,2 )
4209+ g_signal_connect_after (G_OBJECT (gui .drawarea ), "style-updated" ,
4210+ G_CALLBACK (& drawarea_style_updated_cb ), NULL );
4211+ # else
41704212 g_signal_connect_after (G_OBJECT (gui .drawarea ), "style-set" ,
41714213 G_CALLBACK (& drawarea_style_set_cb ), NULL );
4214+ # endif
41724215#else
41734216 gtk_signal_connect (GTK_OBJECT (gui .drawarea ), "realize" ,
41744217 GTK_SIGNAL_FUNC (drawarea_realize_cb ), NULL );
@@ -4384,14 +4427,34 @@ set_cairo_source_rgba_from_color(cairo_t *cr, guicolor_T color)
43844427gui_mch_new_colors (void )
43854428{
43864429#if GTK_CHECK_VERSION (3 ,0 ,0 )
4430+ # if !GTK_CHECK_VERSION (3 ,22 ,2 )
43874431 GdkWindow * const da_win = gtk_widget_get_window (gui .drawarea );
4432+ # endif
43884433
43894434 if (gui .drawarea != NULL && gtk_widget_get_window (gui .drawarea ) != NULL )
43904435#else
43914436 if (gui .drawarea != NULL && gui .drawarea -> window != NULL )
43924437#endif
43934438 {
4394- #if GTK_CHECK_VERSION (3 ,4 ,0 )
4439+ #if GTK_CHECK_VERSION (3 ,22 ,2 )
4440+ GtkStyleContext * const context
4441+ = gtk_widget_get_style_context (gui .drawarea );
4442+ GtkCssProvider * const provider = gtk_css_provider_new ();
4443+ gchar * const css = g_strdup_printf (
4444+ "widget#vim-gui-drawarea {\n"
4445+ " background-color: #%.2lx%.2lx%.2lx;\n"
4446+ "}\n" ,
4447+ (gui .back_pixel >> 16 ) & 0xff ,
4448+ (gui .back_pixel >> 8 ) & 0xff ,
4449+ gui .back_pixel & 0xff );
4450+
4451+ gtk_css_provider_load_from_data (provider , css , -1 , NULL );
4452+ gtk_style_context_add_provider (context ,
4453+ GTK_STYLE_PROVIDER (provider ), G_MAXUINT );
4454+
4455+ g_free (css );
4456+ g_object_unref (provider );
4457+ #elif GTK_CHECK_VERSION (3 ,4 ,0 ) /* !GTK_CHECK_VERSION(3,22,2) */
43954458 GdkRGBA rgba ;
43964459
43974460 rgba = color_to_rgba (gui .back_pixel );
@@ -4415,7 +4478,7 @@ gui_mch_new_colors(void)
44154478# else
44164479 gdk_window_set_background (gui .drawarea -> window , & color );
44174480# endif
4418- #endif /* !GTK_CHECK_VERSION(3,4,0 ) */
4481+ #endif /* !GTK_CHECK_VERSION(3,22,2 ) */
44194482 }
44204483}
44214484
@@ -4429,6 +4492,26 @@ form_configure_event(GtkWidget *widget UNUSED,
44294492{
44304493 int usable_height = event -> height ;
44314494
4495+ #if GTK_CHECK_VERSION (3 ,22 ,2 )
4496+ /* As of 3.22.2, GdkWindows have started distributing configure events to
4497+ * their "native" children (https://git.gnome.org/browse/gtk+/commit/?h=gtk-3-22&id=12579fe71b3b8f79eb9c1b80e429443bcc437dd0).
4498+ *
4499+ * As can be seen from the implementation of move_native_children() and
4500+ * configure_native_child() in gdkwindow.c, those functions actually
4501+ * propagate configure events to every child, failing to distinguish
4502+ * "native" one from non-native one.
4503+ *
4504+ * Naturally, configure events propagated to here like that are fallacious
4505+ * and, as a matter of fact, they trigger a geometric collapse of
4506+ * gui.formwin.
4507+ *
4508+ * To filter out such fallacious events, check if the given event is the
4509+ * one that was sent out to the right place. Ignore it if not.
4510+ */
4511+ if (event -> window != gtk_widget_get_window (gui .formwin ))
4512+ return TRUE;
4513+ #endif
4514+
44324515 /* When in a GtkPlug, we can't guarantee valid heights (as a round
44334516 * no. of char-heights), so we have to manually sanitise them.
44344517 * Widths seem to sort themselves out, don't ask me why.
@@ -4890,6 +4973,16 @@ gui_mch_set_shellsize(int width, int height,
48904973gui_mch_get_screen_dimensions (int * screen_w , int * screen_h )
48914974{
48924975#ifdef HAVE_GTK_MULTIHEAD
4976+ # if GTK_CHECK_VERSION (3 ,22 ,2 )
4977+ GdkRectangle rect ;
4978+ GdkMonitor * const mon = gdk_display_get_monitor_at_window (
4979+ gtk_widget_get_display (gui .mainwin ),
4980+ gtk_widget_get_window (gui .mainwin ));
4981+ gdk_monitor_get_geometry (mon , & rect );
4982+
4983+ * screen_w = rect .width ;
4984+ * screen_h = rect .height - p_ghr ;
4985+ # else
48934986 GdkScreen * screen ;
48944987
48954988 if (gui .mainwin != NULL && gtk_widget_has_screen (gui .mainwin ))
@@ -4899,6 +4992,7 @@ gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
48994992
49004993 * screen_w = gdk_screen_get_width (screen );
49014994 * screen_h = gdk_screen_get_height (screen ) - p_ghr ;
4995+ # endif
49024996#else
49034997 * screen_w = gdk_screen_width ();
49044998 /* Subtract 'guiheadroom' from the height to allow some room for the
@@ -6626,11 +6720,15 @@ gui_mch_clear_block(int row1, int col1, int row2, int col2)
66266720 };
66276721 GdkWindow * const win = gtk_widget_get_window (gui .drawarea );
66286722 cairo_t * const cr = cairo_create (gui .surface );
6723+ # if GTK_CHECK_VERSION (3 ,22 ,2 )
6724+ set_cairo_source_rgba_from_color (cr , gui .back_pixel );
6725+ # else
66296726 cairo_pattern_t * const pat = gdk_window_get_background_pattern (win );
66306727 if (pat != NULL )
66316728 cairo_set_source (cr , pat );
66326729 else
66336730 set_cairo_source_rgba_from_color (cr , gui .back_pixel );
6731+ # endif
66346732 gdk_cairo_rectangle (cr , & rect );
66356733 cairo_fill (cr );
66366734 cairo_destroy (cr );
@@ -6659,11 +6757,15 @@ gui_gtk_window_clear(GdkWindow *win)
66596757 0 , 0 , gdk_window_get_width (win ), gdk_window_get_height (win )
66606758 };
66616759 cairo_t * const cr = cairo_create (gui .surface );
6760+ # if GTK_CHECK_VERSION (3 ,22 ,2 )
6761+ set_cairo_source_rgba_from_color (cr , gui .back_pixel );
6762+ # else
66626763 cairo_pattern_t * const pat = gdk_window_get_background_pattern (win );
66636764 if (pat != NULL )
66646765 cairo_set_source (cr , pat );
66656766 else
66666767 set_cairo_source_rgba_from_color (cr , gui .back_pixel );
6768+ # endif
66676769 gdk_cairo_rectangle (cr , & rect );
66686770 cairo_fill (cr );
66696771 cairo_destroy (cr );
0 commit comments