Patch 8.0.0089
Problem:    Various problems with GTK 3.22.2.
Solution:   Fix the problems, add #ifdefs. (Kazunobu Kuriyama)
Files:      src/gui_beval.c, src/gui_gtk.c, src/gui_gtk_x11.c


*** ../vim-8.0.0088/src/gui_beval.c     2016-11-10 20:01:41.189582944 +0100
--- src/gui_beval.c     2016-11-17 19:09:58.650122624 +0100
***************
*** 1178,1189 ****
--- 1178,1200 ----
        int             y_offset = EVAL_OFFSET_Y;
        PangoLayout     *layout;
  # ifdef HAVE_GTK_MULTIHEAD
+ #  if GTK_CHECK_VERSION(3,22,2)
+       GdkRectangle rect;
+       GdkMonitor * const mon = gdk_display_get_monitor_at_window(
+               gtk_widget_get_display(beval->balloonShell),
+               gtk_widget_get_window(beval->balloonShell));
+       gdk_monitor_get_geometry(mon, &rect);
+ 
+       screen_w = rect.width;
+       screen_h = rect.height;
+ #  else
        GdkScreen       *screen;
  
        screen = gtk_widget_get_screen(beval->target);
        gtk_window_set_screen(GTK_WINDOW(beval->balloonShell), screen);
        screen_w = gdk_screen_get_width(screen);
        screen_h = gdk_screen_get_height(screen);
+ #  endif
  # else
        screen_w = gdk_screen_width();
        screen_h = gdk_screen_height();
*** ../vim-8.0.0088/src/gui_gtk.c       2016-08-29 22:42:20.000000000 +0200
--- src/gui_gtk.c       2016-11-17 19:09:58.650122624 +0100
***************
*** 1881,1890 ****
--- 1881,1916 ----
  #  endif
  # endif /* FEAT_XIM */
  
+ # if GTK_CHECK_VERSION(3,22,2)
+     {
+       GdkEventButton trigger;
+ 
+       /* A pseudo event to have gtk_menu_popup_at_pointer() work. Since the
+        * function calculates the popup menu position on the basis of the
+        * actual pointer position when it is invoked, the fields x, y, x_root
+        * and y_root are set to zero for convenience. */
+       trigger.type       = GDK_BUTTON_PRESS;
+       trigger.window     = gtk_widget_get_window(gui.drawarea);
+       trigger.send_event = FALSE;
+       trigger.time       = gui.event_time;
+       trigger.x          = 0.0;
+       trigger.y          = 0.0;
+       trigger.axes       = NULL;
+       trigger.state      = 0;
+       trigger.button     = 3;
+       trigger.device     = NULL;
+       trigger.x_root     = 0.0;
+       trigger.y_root     = 0.0;
+ 
+       gtk_menu_popup_at_pointer(GTK_MENU(menu->submenu_id),
+                                 (GdkEvent *)&trigger);
+     }
+ #else
      gtk_menu_popup(GTK_MENU(menu->submenu_id),
                   NULL, NULL,
                   (GtkMenuPositionFunc)NULL, NULL,
                   3U, gui.event_time);
+ #endif
  }
  
  /* Ugly global variable to pass "mouse_pos" flag from gui_make_popup() to
***************
*** 1942,1951 ****
--- 1968,2022 ----
  
      if (menu != NULL && menu->submenu_id != NULL)
      {
+ # if GTK_CHECK_VERSION(3,22,2)
+       GdkWindow * const win = gtk_widget_get_window(gui.drawarea);
+       GdkEventButton trigger;
+ 
+       /* A pseudo event to have gtk_menu_popup_at_*() functions work. Since
+        * the position where the menu pops up is automatically adjusted by
+        * the functions, none of the fields x, y, x_root and y_root has to be
+        * set to a specific value here; therefore, they are set to zero for
+        * convenience.*/
+       trigger.type       = GDK_BUTTON_PRESS;
+       trigger.window     = win;
+       trigger.send_event = FALSE;
+       trigger.time       = GDK_CURRENT_TIME;
+       trigger.x          = 0.0;
+       trigger.y          = 0.0;
+       trigger.axes       = NULL;
+       trigger.state      = 0;
+       trigger.button     = 0;
+       trigger.device     = NULL;
+       trigger.x_root     = 0.0;
+       trigger.y_root     = 0.0;
+ 
+       if (mouse_pos)
+           gtk_menu_popup_at_pointer(GTK_MENU(menu->submenu_id),
+                                     (GdkEvent *)&trigger);
+       else
+       {
+           gint origin_x, origin_y;
+           GdkRectangle rect = { 0, 0, 0, 0 };
+ 
+           gdk_window_get_origin(win, &origin_x, &origin_y);
+           popup_menu_position_func(NULL, &rect.x, &rect.y, NULL, NULL);
+ 
+           rect.x -= origin_x;
+           rect.y -= origin_y;
+ 
+           gtk_menu_popup_at_rect(GTK_MENU(menu->submenu_id),
+                                  win,
+                                  &rect,
+                                  GDK_GRAVITY_SOUTH_EAST,
+                                  GDK_GRAVITY_NORTH_WEST,
+                                  (GdkEvent *)&trigger);
+       }
+ # else
        gtk_menu_popup(GTK_MENU(menu->submenu_id),
                       NULL, NULL,
                       &popup_menu_position_func, NULL,
                       0U, (guint32)GDK_CURRENT_TIME);
+ # endif
      }
  }
  
*** ../vim-8.0.0088/src/gui_gtk_x11.c   2016-08-29 22:42:20.000000000 +0200
--- src/gui_gtk_x11.c   2016-11-17 19:09:58.650122624 +0100
***************
*** 3076,3085 ****
--- 3076,3091 ----
      gui.blank_pointer = NULL;
  }
  
+ #if GTK_CHECK_VERSION(3,22,2)
+     static void
+ drawarea_style_updated_cb(GtkWidget *widget UNUSED,
+                        gpointer data UNUSED)
+ #else
      static void
  drawarea_style_set_cb(GtkWidget       *widget UNUSED,
                      GtkStyle  *previous_style UNUSED,
                      gpointer  data UNUSED)
+ #endif
  {
      gui_mch_new_colors();
  }
***************
*** 3096,3101 ****
--- 3102,3132 ----
      g_return_val_if_fail(event
            && event->width >= 1 && event->height >= 1, TRUE);
  
+ # if GTK_CHECK_VERSION(3,22,2)
+     /* As of 3.22.2, GdkWindows have started distributing configure events to
+      * their "native" children 
(https://git.gnome.org/browse/gtk+/commit/?h=gtk-3-22&id=12579fe71b3b8f79eb9c1b80e429443bcc437dd0).
+      *
+      * As can be seen from the implementation of move_native_children() and
+      * configure_native_child() in gdkwindow.c, those functions actually
+      * propagate configure events to every child, failing to distinguish
+      * "native" one from non-native one.
+      *
+      * Naturally, configure events propagated to here like that are fallacious
+      * and, as a matter of fact, they trigger a geometric collapse of
+      * gui.drawarea in fullscreen and miximized modes.
+      *
+      * To filter out such nuisance events, we are making use of the fact that
+      * the field send_event of such GdkEventConfigures is set to FALSE in
+      * configure_native_child().
+      *
+      * Obviously, this is a terrible hack making GVim depend on GTK's
+      * implementation details.  Therefore, watch out any relevant internal
+      * changes happening in GTK in the feature (sigh).
+      */
+     if (event->send_event == FALSE)
+       return TRUE;
+ # endif
+ 
      if (event->width == cur_width && event->height == cur_height)
        return TRUE;
  
***************
*** 3519,3526 ****
--- 3550,3561 ----
        /* If the event was generated for 3rd button popup the menu. */
        if (bevent->button == 3)
        {
+ # if GTK_CHECK_VERSION(3,22,2)
+           gtk_menu_popup_at_pointer(GTK_MENU(widget), event);
+ # else
            gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL,
                                                bevent->button, bevent->time);
+ # endif
            /* We handled the event. */
            return TRUE;
        }
***************
*** 4116,4121 ****
--- 4151,4159 ----
  #endif
  
      gui.drawarea = gtk_drawing_area_new();
+ #if GTK_CHECK_VERSION(3,22,2)
+     gtk_widget_set_name(gui.drawarea, "vim-gui-drawarea");
+ #endif
  #if GTK_CHECK_VERSION(3,0,0)
      gui.surface = NULL;
      gui.by_signal = FALSE;
***************
*** 4167,4174 ****
--- 4205,4217 ----
                     G_CALLBACK(drawarea_unrealize_cb), NULL);
      g_signal_connect(G_OBJECT(gui.drawarea), "configure-event",
            G_CALLBACK(drawarea_configure_event_cb), NULL);
+ # if GTK_CHECK_VERSION(3,22,2)
+     g_signal_connect_after(G_OBJECT(gui.drawarea), "style-updated",
+                          G_CALLBACK(&drawarea_style_updated_cb), NULL);
+ # else
      g_signal_connect_after(G_OBJECT(gui.drawarea), "style-set",
                           G_CALLBACK(&drawarea_style_set_cb), NULL);
+ # endif
  #else
      gtk_signal_connect(GTK_OBJECT(gui.drawarea), "realize",
                       GTK_SIGNAL_FUNC(drawarea_realize_cb), NULL);
***************
*** 4384,4397 ****
  gui_mch_new_colors(void)
  {
  #if GTK_CHECK_VERSION(3,0,0)
      GdkWindow * const da_win = gtk_widget_get_window(gui.drawarea);
  
      if (gui.drawarea != NULL && gtk_widget_get_window(gui.drawarea) != NULL)
  #else
      if (gui.drawarea != NULL && gui.drawarea->window != NULL)
  #endif
      {
! #if GTK_CHECK_VERSION(3,4,0)
        GdkRGBA rgba;
  
        rgba = color_to_rgba(gui.back_pixel);
--- 4427,4460 ----
  gui_mch_new_colors(void)
  {
  #if GTK_CHECK_VERSION(3,0,0)
+ # if !GTK_CHECK_VERSION(3,22,2)
      GdkWindow * const da_win = gtk_widget_get_window(gui.drawarea);
+ # endif
  
      if (gui.drawarea != NULL && gtk_widget_get_window(gui.drawarea) != NULL)
  #else
      if (gui.drawarea != NULL && gui.drawarea->window != NULL)
  #endif
      {
! #if GTK_CHECK_VERSION(3,22,2)
!       GtkStyleContext * const context
!           = gtk_widget_get_style_context(gui.drawarea);
!       GtkCssProvider * const provider = gtk_css_provider_new();
!       gchar * const css = g_strdup_printf(
!               "widget#vim-gui-drawarea {\n"
!               "  background-color: #%.2lx%.2lx%.2lx;\n"
!               "}\n",
!                (gui.back_pixel >> 16) & 0xff,
!                (gui.back_pixel >> 8) & 0xff,
!                gui.back_pixel & 0xff);
! 
!       gtk_css_provider_load_from_data(provider, css, -1, NULL);
!       gtk_style_context_add_provider(context,
!               GTK_STYLE_PROVIDER(provider), G_MAXUINT);
! 
!       g_free(css);
!       g_object_unref(provider);
! #elif GTK_CHECK_VERSION(3,4,0) /* !GTK_CHECK_VERSION(3,22,2) */
        GdkRGBA rgba;
  
        rgba = color_to_rgba(gui.back_pixel);
***************
*** 4415,4421 ****
  # else
        gdk_window_set_background(gui.drawarea->window, &color);
  # endif
! #endif /* !GTK_CHECK_VERSION(3,4,0) */
      }
  }
  
--- 4478,4484 ----
  # else
        gdk_window_set_background(gui.drawarea->window, &color);
  # endif
! #endif /* !GTK_CHECK_VERSION(3,22,2) */
      }
  }
  
***************
*** 4429,4434 ****
--- 4492,4517 ----
  {
      int usable_height = event->height;
  
+ #if GTK_CHECK_VERSION(3,22,2)
+     /* As of 3.22.2, GdkWindows have started distributing configure events to
+      * their "native" children 
(https://git.gnome.org/browse/gtk+/commit/?h=gtk-3-22&id=12579fe71b3b8f79eb9c1b80e429443bcc437dd0).
+      *
+      * As can be seen from the implementation of move_native_children() and
+      * configure_native_child() in gdkwindow.c, those functions actually
+      * propagate configure events to every child, failing to distinguish
+      * "native" one from non-native one.
+      *
+      * Naturally, configure events propagated to here like that are fallacious
+      * and, as a matter of fact, they trigger a geometric collapse of
+      * gui.formwin.
+      *
+      * To filter out such fallacious events, check if the given event is the
+      * one that was sent out to the right place. Ignore it if not.
+      */
+     if (event->window != gtk_widget_get_window(gui.formwin))
+       return TRUE;
+ #endif
+ 
      /* When in a GtkPlug, we can't guarantee valid heights (as a round
       * no. of char-heights), so we have to manually sanitise them.
       * Widths seem to sort themselves out, don't ask me why.
***************
*** 4890,4895 ****
--- 4973,4988 ----
  gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
  {
  #ifdef HAVE_GTK_MULTIHEAD
+ # if GTK_CHECK_VERSION(3,22,2)
+     GdkRectangle rect;
+     GdkMonitor * const mon = gdk_display_get_monitor_at_window(
+           gtk_widget_get_display(gui.mainwin),
+           gtk_widget_get_window(gui.mainwin));
+     gdk_monitor_get_geometry(mon, &rect);
+ 
+     *screen_w = rect.width;
+     *screen_h = rect.height - p_ghr;
+ # else
      GdkScreen* screen;
  
      if (gui.mainwin != NULL && gtk_widget_has_screen(gui.mainwin))
***************
*** 4899,4904 ****
--- 4992,4998 ----
  
      *screen_w = gdk_screen_get_width(screen);
      *screen_h = gdk_screen_get_height(screen) - p_ghr;
+ # endif
  #else
      *screen_w = gdk_screen_width();
      /* Subtract 'guiheadroom' from the height to allow some room for the
***************
*** 6626,6636 ****
--- 6720,6734 ----
        };
        GdkWindow * const win = gtk_widget_get_window(gui.drawarea);
        cairo_t * const cr = cairo_create(gui.surface);
+ # if GTK_CHECK_VERSION(3,22,2)
+       set_cairo_source_rgba_from_color(cr, gui.back_pixel);
+ # else
        cairo_pattern_t * const pat = gdk_window_get_background_pattern(win);
        if (pat != NULL)
            cairo_set_source(cr, pat);
        else
            set_cairo_source_rgba_from_color(cr, gui.back_pixel);
+ # endif
        gdk_cairo_rectangle(cr, &rect);
        cairo_fill(cr);
        cairo_destroy(cr);
***************
*** 6659,6669 ****
--- 6757,6771 ----
        0, 0, gdk_window_get_width(win), gdk_window_get_height(win)
      };
      cairo_t * const cr = cairo_create(gui.surface);
+ # if GTK_CHECK_VERSION(3,22,2)
+     set_cairo_source_rgba_from_color(cr, gui.back_pixel);
+ # else
      cairo_pattern_t * const pat = gdk_window_get_background_pattern(win);
      if (pat != NULL)
        cairo_set_source(cr, pat);
      else
        set_cairo_source_rgba_from_color(cr, gui.back_pixel);
+ # endif
      gdk_cairo_rectangle(cr, &rect);
      cairo_fill(cr);
      cairo_destroy(cr);
*** ../vim-8.0.0088/src/version.c       2016-11-17 17:56:10.103449001 +0100
--- src/version.c       2016-11-17 19:10:50.549780930 +0100
***************
*** 766,767 ****
--- 766,769 ----
  {   /* Add new patch number below this line */
+ /**/
+     89,
  /**/

-- 
What a wonderfully exciting cough!  Do you mind if I join you?
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui