comparison src/gui_gtk_x11.c @ 10390:6c8a4d21b873 v8.0.0089

commit https://github.com/vim/vim/commit/a859f04b4db651860c07db3587f29906517c552b Author: Bram Moolenaar <Bram@vim.org> Date: Thu Nov 17 19:11:55 2016 +0100 patch 8.0.0089 Problem: Various problems with GTK 3.22.2. Solution: Fix the problems, add #ifdefs. (Kazunobu Kuriyama)
author Christian Brabandt <cb@256bit.org>
date Thu, 17 Nov 2016 19:15:04 +0100
parents 4aead6a9b7a9
children 65646e5652df
comparison
equal deleted inserted replaced
10389:31c0537eab4e 10390:6c8a4d21b873
3074 gdk_cursor_unref(gui.blank_pointer); 3074 gdk_cursor_unref(gui.blank_pointer);
3075 #endif 3075 #endif
3076 gui.blank_pointer = NULL; 3076 gui.blank_pointer = NULL;
3077 } 3077 }
3078 3078
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
3079 static void 3084 static void
3080 drawarea_style_set_cb(GtkWidget *widget UNUSED, 3085 drawarea_style_set_cb(GtkWidget *widget UNUSED,
3081 GtkStyle *previous_style UNUSED, 3086 GtkStyle *previous_style UNUSED,
3082 gpointer data UNUSED) 3087 gpointer data UNUSED)
3088 #endif
3083 { 3089 {
3084 gui_mch_new_colors(); 3090 gui_mch_new_colors();
3085 } 3091 }
3086 3092
3087 #if GTK_CHECK_VERSION(3,0,0) 3093 #if GTK_CHECK_VERSION(3,0,0)
3093 static int cur_width = 0; 3099 static int cur_width = 0;
3094 static int cur_height = 0; 3100 static int cur_height = 0;
3095 3101
3096 g_return_val_if_fail(event 3102 g_return_val_if_fail(event
3097 && event->width >= 1 && event->height >= 1, TRUE); 3103 && event->width >= 1 && event->height >= 1, TRUE);
3104
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
3098 3129
3099 if (event->width == cur_width && event->height == cur_height) 3130 if (event->width == cur_width && event->height == cur_height)
3100 return TRUE; 3131 return TRUE;
3101 3132
3102 cur_width = event->width; 3133 cur_width = event->width;
3517 # endif 3548 # endif
3518 3549
3519 /* If the event was generated for 3rd button popup the menu. */ 3550 /* If the event was generated for 3rd button popup the menu. */
3520 if (bevent->button == 3) 3551 if (bevent->button == 3)
3521 { 3552 {
3553 # if GTK_CHECK_VERSION(3,22,2)
3554 gtk_menu_popup_at_pointer(GTK_MENU(widget), event);
3555 # else
3522 gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL, 3556 gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL,
3523 bevent->button, bevent->time); 3557 bevent->button, bevent->time);
3558 # endif
3524 /* We handled the event. */ 3559 /* We handled the event. */
3525 return TRUE; 3560 return TRUE;
3526 } 3561 }
3527 else if (bevent->button == 1) 3562 else if (bevent->button == 1)
3528 { 3563 {
4114 #if !GTK_CHECK_VERSION(3,0,0) 4149 #if !GTK_CHECK_VERSION(3,0,0)
4115 gtk_widget_set_events(gui.formwin, GDK_EXPOSURE_MASK); 4150 gtk_widget_set_events(gui.formwin, GDK_EXPOSURE_MASK);
4116 #endif 4151 #endif
4117 4152
4118 gui.drawarea = gtk_drawing_area_new(); 4153 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
4119 #if GTK_CHECK_VERSION(3,0,0) 4157 #if GTK_CHECK_VERSION(3,0,0)
4120 gui.surface = NULL; 4158 gui.surface = NULL;
4121 gui.by_signal = FALSE; 4159 gui.by_signal = FALSE;
4122 #endif 4160 #endif
4123 4161
4165 G_CALLBACK(drawarea_realize_cb), NULL); 4203 G_CALLBACK(drawarea_realize_cb), NULL);
4166 g_signal_connect(G_OBJECT(gui.drawarea), "unrealize", 4204 g_signal_connect(G_OBJECT(gui.drawarea), "unrealize",
4167 G_CALLBACK(drawarea_unrealize_cb), NULL); 4205 G_CALLBACK(drawarea_unrealize_cb), NULL);
4168 g_signal_connect(G_OBJECT(gui.drawarea), "configure-event", 4206 g_signal_connect(G_OBJECT(gui.drawarea), "configure-event",
4169 G_CALLBACK(drawarea_configure_event_cb), NULL); 4207 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
4170 g_signal_connect_after(G_OBJECT(gui.drawarea), "style-set", 4212 g_signal_connect_after(G_OBJECT(gui.drawarea), "style-set",
4171 G_CALLBACK(&drawarea_style_set_cb), NULL); 4213 G_CALLBACK(&drawarea_style_set_cb), NULL);
4214 # endif
4172 #else 4215 #else
4173 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "realize", 4216 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "realize",
4174 GTK_SIGNAL_FUNC(drawarea_realize_cb), NULL); 4217 GTK_SIGNAL_FUNC(drawarea_realize_cb), NULL);
4175 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "unrealize", 4218 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "unrealize",
4176 GTK_SIGNAL_FUNC(drawarea_unrealize_cb), NULL); 4219 GTK_SIGNAL_FUNC(drawarea_unrealize_cb), NULL);
4382 */ 4425 */
4383 void 4426 void
4384 gui_mch_new_colors(void) 4427 gui_mch_new_colors(void)
4385 { 4428 {
4386 #if GTK_CHECK_VERSION(3,0,0) 4429 #if GTK_CHECK_VERSION(3,0,0)
4430 # if !GTK_CHECK_VERSION(3,22,2)
4387 GdkWindow * const da_win = gtk_widget_get_window(gui.drawarea); 4431 GdkWindow * const da_win = gtk_widget_get_window(gui.drawarea);
4432 # endif
4388 4433
4389 if (gui.drawarea != NULL && gtk_widget_get_window(gui.drawarea) != NULL) 4434 if (gui.drawarea != NULL && gtk_widget_get_window(gui.drawarea) != NULL)
4390 #else 4435 #else
4391 if (gui.drawarea != NULL && gui.drawarea->window != NULL) 4436 if (gui.drawarea != NULL && gui.drawarea->window != NULL)
4392 #endif 4437 #endif
4393 { 4438 {
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) */
4395 GdkRGBA rgba; 4458 GdkRGBA rgba;
4396 4459
4397 rgba = color_to_rgba(gui.back_pixel); 4460 rgba = color_to_rgba(gui.back_pixel);
4398 { 4461 {
4399 cairo_pattern_t * const pat = cairo_pattern_create_rgba( 4462 cairo_pattern_t * const pat = cairo_pattern_create_rgba(
4413 # if GTK_CHECK_VERSION(3,0,0) 4476 # if GTK_CHECK_VERSION(3,0,0)
4414 gdk_window_set_background(da_win, &color); 4477 gdk_window_set_background(da_win, &color);
4415 # else 4478 # else
4416 gdk_window_set_background(gui.drawarea->window, &color); 4479 gdk_window_set_background(gui.drawarea->window, &color);
4417 # endif 4480 # endif
4418 #endif /* !GTK_CHECK_VERSION(3,4,0) */ 4481 #endif /* !GTK_CHECK_VERSION(3,22,2) */
4419 } 4482 }
4420 } 4483 }
4421 4484
4422 /* 4485 /*
4423 * This signal informs us about the need to rearrange our sub-widgets. 4486 * This signal informs us about the need to rearrange our sub-widgets.
4426 form_configure_event(GtkWidget *widget UNUSED, 4489 form_configure_event(GtkWidget *widget UNUSED,
4427 GdkEventConfigure *event, 4490 GdkEventConfigure *event,
4428 gpointer data UNUSED) 4491 gpointer data UNUSED)
4429 { 4492 {
4430 int usable_height = event->height; 4493 int usable_height = event->height;
4494
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
4431 4514
4432 /* When in a GtkPlug, we can't guarantee valid heights (as a round 4515 /* When in a GtkPlug, we can't guarantee valid heights (as a round
4433 * no. of char-heights), so we have to manually sanitise them. 4516 * no. of char-heights), so we have to manually sanitise them.
4434 * Widths seem to sort themselves out, don't ask me why. 4517 * Widths seem to sort themselves out, don't ask me why.
4435 */ 4518 */
4888 */ 4971 */
4889 void 4972 void
4890 gui_mch_get_screen_dimensions(int *screen_w, int *screen_h) 4973 gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
4891 { 4974 {
4892 #ifdef HAVE_GTK_MULTIHEAD 4975 #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
4893 GdkScreen* screen; 4986 GdkScreen* screen;
4894 4987
4895 if (gui.mainwin != NULL && gtk_widget_has_screen(gui.mainwin)) 4988 if (gui.mainwin != NULL && gtk_widget_has_screen(gui.mainwin))
4896 screen = gtk_widget_get_screen(gui.mainwin); 4989 screen = gtk_widget_get_screen(gui.mainwin);
4897 else 4990 else
4898 screen = gdk_screen_get_default(); 4991 screen = gdk_screen_get_default();
4899 4992
4900 *screen_w = gdk_screen_get_width(screen); 4993 *screen_w = gdk_screen_get_width(screen);
4901 *screen_h = gdk_screen_get_height(screen) - p_ghr; 4994 *screen_h = gdk_screen_get_height(screen) - p_ghr;
4995 # endif
4902 #else 4996 #else
4903 *screen_w = gdk_screen_width(); 4997 *screen_w = gdk_screen_width();
4904 /* Subtract 'guiheadroom' from the height to allow some room for the 4998 /* Subtract 'guiheadroom' from the height to allow some room for the
4905 * window manager (task list and window title bar). */ 4999 * window manager (task list and window title bar). */
4906 *screen_h = gdk_screen_height() - p_ghr; 5000 *screen_h = gdk_screen_height() - p_ghr;
6624 (col2 - col1 + 1) * gui.char_width + (col2 == Columns - 1), 6718 (col2 - col1 + 1) * gui.char_width + (col2 == Columns - 1),
6625 (row2 - row1 + 1) * gui.char_height 6719 (row2 - row1 + 1) * gui.char_height
6626 }; 6720 };
6627 GdkWindow * const win = gtk_widget_get_window(gui.drawarea); 6721 GdkWindow * const win = gtk_widget_get_window(gui.drawarea);
6628 cairo_t * const cr = cairo_create(gui.surface); 6722 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
6629 cairo_pattern_t * const pat = gdk_window_get_background_pattern(win); 6726 cairo_pattern_t * const pat = gdk_window_get_background_pattern(win);
6630 if (pat != NULL) 6727 if (pat != NULL)
6631 cairo_set_source(cr, pat); 6728 cairo_set_source(cr, pat);
6632 else 6729 else
6633 set_cairo_source_rgba_from_color(cr, gui.back_pixel); 6730 set_cairo_source_rgba_from_color(cr, gui.back_pixel);
6731 # endif
6634 gdk_cairo_rectangle(cr, &rect); 6732 gdk_cairo_rectangle(cr, &rect);
6635 cairo_fill(cr); 6733 cairo_fill(cr);
6636 cairo_destroy(cr); 6734 cairo_destroy(cr);
6637 6735
6638 if (!gui.by_signal) 6736 if (!gui.by_signal)
6657 { 6755 {
6658 const GdkRectangle rect = { 6756 const GdkRectangle rect = {
6659 0, 0, gdk_window_get_width(win), gdk_window_get_height(win) 6757 0, 0, gdk_window_get_width(win), gdk_window_get_height(win)
6660 }; 6758 };
6661 cairo_t * const cr = cairo_create(gui.surface); 6759 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
6662 cairo_pattern_t * const pat = gdk_window_get_background_pattern(win); 6763 cairo_pattern_t * const pat = gdk_window_get_background_pattern(win);
6663 if (pat != NULL) 6764 if (pat != NULL)
6664 cairo_set_source(cr, pat); 6765 cairo_set_source(cr, pat);
6665 else 6766 else
6666 set_cairo_source_rgba_from_color(cr, gui.back_pixel); 6767 set_cairo_source_rgba_from_color(cr, gui.back_pixel);
6768 # endif
6667 gdk_cairo_rectangle(cr, &rect); 6769 gdk_cairo_rectangle(cr, &rect);
6668 cairo_fill(cr); 6770 cairo_fill(cr);
6669 cairo_destroy(cr); 6771 cairo_destroy(cr);
6670 6772
6671 if (!gui.by_signal) 6773 if (!gui.by_signal)