GtkWindow: better app menu fallback for CSD
Do the menubutton for app menu fallback ourselves in GtkWindow for the csd, non-custom titlebar case. This fits better with the way we handle other title buttons. Themes have control over the placement of this button by placing menu in the decoration-button-layout style property.
This commit is contained in:
		@ -297,12 +297,10 @@ gtk_application_window_update_shell_shows_app_menu (GtkApplicationWindow *window
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  gboolean shown_by_shell;
 | 
					  gboolean shown_by_shell;
 | 
				
			||||||
  gboolean shown_by_titlebar;
 | 
					  gboolean shown_by_titlebar;
 | 
				
			||||||
  GtkWidget *titlebar;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_object_get (settings, "gtk-shell-shows-app-menu", &shown_by_shell, NULL);
 | 
					  g_object_get (settings, "gtk-shell-shows-app-menu", &shown_by_shell, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  titlebar = _gtk_window_get_titlebar (GTK_WINDOW (window));
 | 
					  shown_by_titlebar = _gtk_window_titlebar_shows_app_menu (GTK_WINDOW (window));
 | 
				
			||||||
  shown_by_titlebar = GTK_IS_HEADER_BAR (titlebar) && gtk_header_bar_get_show_fallback_app_menu (GTK_HEADER_BAR (titlebar));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (shown_by_shell || shown_by_titlebar)
 | 
					  if (shown_by_shell || shown_by_titlebar)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -632,13 +630,12 @@ gtk_application_window_real_realize (GtkWidget *widget)
 | 
				
			|||||||
  g_signal_connect (settings, "notify::gtk-shell-shows-menubar",
 | 
					  g_signal_connect (settings, "notify::gtk-shell-shows-menubar",
 | 
				
			||||||
                    G_CALLBACK (gtk_application_window_shell_shows_menubar_changed), window);
 | 
					                    G_CALLBACK (gtk_application_window_shell_shows_menubar_changed), window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GTK_WIDGET_CLASS (gtk_application_window_parent_class)->realize (widget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  gtk_application_window_update_shell_shows_app_menu (window, settings);
 | 
					  gtk_application_window_update_shell_shows_app_menu (window, settings);
 | 
				
			||||||
  gtk_application_window_update_shell_shows_menubar (window, settings);
 | 
					  gtk_application_window_update_shell_shows_menubar (window, settings);
 | 
				
			||||||
  gtk_application_window_update_menubar (window);
 | 
					  gtk_application_window_update_menubar (window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GTK_WIDGET_CLASS (gtk_application_window_parent_class)
 | 
					 | 
				
			||||||
    ->realize (widget);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef GDK_WINDOWING_X11
 | 
					#ifdef GDK_WINDOWING_X11
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    GdkWindow *gdkwindow;
 | 
					    GdkWindow *gdkwindow;
 | 
				
			||||||
@ -679,8 +676,7 @@ gtk_application_window_real_unrealize (GtkWidget *widget)
 | 
				
			|||||||
  g_signal_handlers_disconnect_by_func (settings, gtk_application_window_shell_shows_app_menu_changed, widget);
 | 
					  g_signal_handlers_disconnect_by_func (settings, gtk_application_window_shell_shows_app_menu_changed, widget);
 | 
				
			||||||
  g_signal_handlers_disconnect_by_func (settings, gtk_application_window_shell_shows_menubar_changed, widget);
 | 
					  g_signal_handlers_disconnect_by_func (settings, gtk_application_window_shell_shows_menubar_changed, widget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GTK_WIDGET_CLASS (gtk_application_window_parent_class)
 | 
					  GTK_WIDGET_CLASS (gtk_application_window_parent_class)->unrealize (widget);
 | 
				
			||||||
    ->unrealize (widget);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gboolean
 | 
					gboolean
 | 
				
			||||||
 | 
				
			|||||||
@ -157,6 +157,7 @@ struct _GtkWindowPrivate
 | 
				
			|||||||
  GtkWidget *title_box;
 | 
					  GtkWidget *title_box;
 | 
				
			||||||
  GtkWidget *titlebar;
 | 
					  GtkWidget *titlebar;
 | 
				
			||||||
  GtkWidget *titlebar_icon;
 | 
					  GtkWidget *titlebar_icon;
 | 
				
			||||||
 | 
					  GtkWidget *titlebar_menu_button;
 | 
				
			||||||
  GtkWidget *titlebar_min_button;
 | 
					  GtkWidget *titlebar_min_button;
 | 
				
			||||||
  GtkWidget *titlebar_max_button;
 | 
					  GtkWidget *titlebar_max_button;
 | 
				
			||||||
  GtkWidget *titlebar_close_button;
 | 
					  GtkWidget *titlebar_close_button;
 | 
				
			||||||
@ -1068,7 +1069,7 @@ gtk_window_class_init (GtkWindowClass *klass)
 | 
				
			|||||||
                                           g_param_spec_string ("decoration-button-layout",
 | 
					                                           g_param_spec_string ("decoration-button-layout",
 | 
				
			||||||
                                                                P_("Decorated button layout"),
 | 
					                                                                P_("Decorated button layout"),
 | 
				
			||||||
                                                                P_("Decorated button layout"),
 | 
					                                                                P_("Decorated button layout"),
 | 
				
			||||||
                                                                ":close",
 | 
					                                                                "menu:close",
 | 
				
			||||||
                                                                GTK_PARAM_READABLE));
 | 
					                                                                GTK_PARAM_READABLE));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  gtk_widget_class_install_style_property (widget_class,
 | 
					  gtk_widget_class_install_style_property (widget_class,
 | 
				
			||||||
@ -3473,6 +3474,7 @@ unset_titlebar (GtkWindow *window)
 | 
				
			|||||||
      priv->title_box = NULL;
 | 
					      priv->title_box = NULL;
 | 
				
			||||||
      priv->titlebar = NULL;
 | 
					      priv->titlebar = NULL;
 | 
				
			||||||
      priv->titlebar_icon = NULL;
 | 
					      priv->titlebar_icon = NULL;
 | 
				
			||||||
 | 
					      priv->titlebar_menu_button = NULL;
 | 
				
			||||||
      priv->titlebar_min_button = NULL;
 | 
					      priv->titlebar_min_button = NULL;
 | 
				
			||||||
      priv->titlebar_max_button = NULL;
 | 
					      priv->titlebar_max_button = NULL;
 | 
				
			||||||
      priv->titlebar_close_button = NULL;
 | 
					      priv->titlebar_close_button = NULL;
 | 
				
			||||||
@ -3579,10 +3581,18 @@ gtk_window_set_titlebar (GtkWindow *window,
 | 
				
			|||||||
  gtk_widget_queue_resize (widget);
 | 
					  gtk_widget_queue_resize (widget);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GtkWidget *
 | 
					gboolean
 | 
				
			||||||
_gtk_window_get_titlebar (GtkWindow *window)
 | 
					_gtk_window_titlebar_shows_app_menu (GtkWindow *window)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  return window->priv->title_box;
 | 
					  GtkWindowPrivate *priv = window->priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (priv->titlebar_menu_button)
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (GTK_IS_HEADER_BAR (priv->title_box))
 | 
				
			||||||
 | 
					    return gtk_header_bar_get_show_fallback_app_menu (GTK_HEADER_BAR (priv->title_box));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -3811,12 +3821,18 @@ set_titlebar_icon (GtkWindow *window, GList *list)
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
      GdkPixbuf *pixbuf, *best;
 | 
					      GdkPixbuf *pixbuf, *best;
 | 
				
			||||||
      GList *l;
 | 
					      GList *l;
 | 
				
			||||||
 | 
					      gint size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (GTK_IS_BUTTON (gtk_widget_get_parent (priv->titlebar_icon)))
 | 
				
			||||||
 | 
					        size = 16;
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        size = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      best = NULL;
 | 
					      best = NULL;
 | 
				
			||||||
      for (l = list; l; l = l->next)
 | 
					      for (l = list; l; l = l->next)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          pixbuf = list->data;
 | 
					          pixbuf = list->data;
 | 
				
			||||||
          if (gdk_pixbuf_get_width (pixbuf) <= 20)
 | 
					          if (gdk_pixbuf_get_width (pixbuf) <= size)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              best = g_object_ref (pixbuf);
 | 
					              best = g_object_ref (pixbuf);
 | 
				
			||||||
              break;
 | 
					              break;
 | 
				
			||||||
@ -3824,7 +3840,7 @@ set_titlebar_icon (GtkWindow *window, GList *list)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (best == NULL)
 | 
					      if (best == NULL)
 | 
				
			||||||
        best = gdk_pixbuf_scale_simple (GDK_PIXBUF (list->data), 20, 20, GDK_INTERP_BILINEAR);
 | 
					        best = gdk_pixbuf_scale_simple (GDK_PIXBUF (list->data), size, size, GDK_INTERP_BILINEAR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      gtk_image_set_from_pixbuf (GTK_IMAGE (priv->titlebar_icon), best);
 | 
					      gtk_image_set_from_pixbuf (GTK_IMAGE (priv->titlebar_icon), best);
 | 
				
			||||||
      g_object_unref (best);
 | 
					      g_object_unref (best);
 | 
				
			||||||
@ -5127,6 +5143,8 @@ update_window_buttons (GtkWindow *window)
 | 
				
			|||||||
  gchar **tokens, **t;
 | 
					  gchar **tokens, **t;
 | 
				
			||||||
  gint i, j;
 | 
					  gint i, j;
 | 
				
			||||||
  GdkPixbuf *icon = NULL;
 | 
					  GdkPixbuf *icon = NULL;
 | 
				
			||||||
 | 
					  GMenuModel *menu;
 | 
				
			||||||
 | 
					  gboolean shown_by_shell;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (priv->title_box == NULL)
 | 
					  if (priv->title_box == NULL)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
@ -5155,6 +5173,11 @@ update_window_buttons (GtkWindow *window)
 | 
				
			|||||||
      gtk_widget_destroy (priv->titlebar_icon);
 | 
					      gtk_widget_destroy (priv->titlebar_icon);
 | 
				
			||||||
      priv->titlebar_icon = NULL;
 | 
					      priv->titlebar_icon = NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  if (priv->titlebar_menu_button)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      gtk_widget_destroy (priv->titlebar_menu_button);
 | 
				
			||||||
 | 
					      priv->titlebar_menu_button = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  if (priv->titlebar_min_button)
 | 
					  if (priv->titlebar_min_button)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      gtk_widget_destroy (priv->titlebar_min_button);
 | 
					      gtk_widget_destroy (priv->titlebar_min_button);
 | 
				
			||||||
@ -5175,6 +5198,14 @@ update_window_buttons (GtkWindow *window)
 | 
				
			|||||||
                        "decoration-button-layout", &layout_desc,
 | 
					                        "decoration-button-layout", &layout_desc,
 | 
				
			||||||
                        NULL);
 | 
					                        NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
 | 
				
			||||||
 | 
					                "gtk-shell-shows-app-menu", &shown_by_shell, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!shown_by_shell && priv->application)
 | 
				
			||||||
 | 
					    menu = gtk_application_get_app_menu (priv->application);
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    menu = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  tokens = g_strsplit (layout_desc, ":", 2);
 | 
					  tokens = g_strsplit (layout_desc, ":", 2);
 | 
				
			||||||
  if (tokens)
 | 
					  if (tokens)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -5211,15 +5242,30 @@ update_window_buttons (GtkWindow *window)
 | 
				
			|||||||
                  gtk_widget_set_size_request (button, 20, 20);
 | 
					                  gtk_widget_set_size_request (button, 20, 20);
 | 
				
			||||||
                  gtk_widget_show (button);
 | 
					                  gtk_widget_show (button);
 | 
				
			||||||
                  if (icon != NULL)
 | 
					                  if (icon != NULL)
 | 
				
			||||||
                    {
 | 
					                    gtk_image_set_from_pixbuf (GTK_IMAGE (button), icon);
 | 
				
			||||||
                      gtk_image_set_from_pixbuf (GTK_IMAGE (button), icon);
 | 
					 | 
				
			||||||
                      g_object_unref (icon);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                  else
 | 
					                  else
 | 
				
			||||||
                    gtk_widget_hide (button);
 | 
					                    gtk_widget_hide (button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  priv->titlebar_icon = button;
 | 
					                  priv->titlebar_icon = button;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					              else if (strcmp (t[j], "menu") == 0 && menu != NULL)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  button = gtk_menu_button_new ();
 | 
				
			||||||
 | 
					                  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu);
 | 
				
			||||||
 | 
					                  gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton");
 | 
				
			||||||
 | 
					                  if (icon != NULL)
 | 
				
			||||||
 | 
					                    image = gtk_image_new_from_pixbuf (icon);
 | 
				
			||||||
 | 
					                  else
 | 
				
			||||||
 | 
					                    image = gtk_image_new_from_icon_name ("process-stop-symbolic", GTK_ICON_SIZE_MENU);
 | 
				
			||||||
 | 
					                  gtk_container_add (GTK_CONTAINER (button), image);
 | 
				
			||||||
 | 
					                  gtk_widget_set_can_focus (button, FALSE);
 | 
				
			||||||
 | 
					                  gtk_widget_show_all (button);
 | 
				
			||||||
 | 
					                  accessible = gtk_widget_get_accessible (button);
 | 
				
			||||||
 | 
					                  if (GTK_IS_ACCESSIBLE (accessible))
 | 
				
			||||||
 | 
					                    atk_object_set_name (accessible, _("Application menu"));
 | 
				
			||||||
 | 
							  priv->titlebar_icon = image;
 | 
				
			||||||
 | 
					                  priv->titlebar_menu_button = button;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
              else if (strcmp (t[j], "minimize") == 0 &&
 | 
					              else if (strcmp (t[j], "minimize") == 0 &&
 | 
				
			||||||
                       priv->gdk_type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
 | 
					                       priv->gdk_type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@ -5285,6 +5331,8 @@ update_window_buttons (GtkWindow *window)
 | 
				
			|||||||
      g_strfreev (tokens);
 | 
					      g_strfreev (tokens);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  g_free (layout_desc);
 | 
					  g_free (layout_desc);
 | 
				
			||||||
 | 
					  if (icon)
 | 
				
			||||||
 | 
					    g_object_unref (icon);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static GtkWidget *
 | 
					static GtkWidget *
 | 
				
			||||||
@ -5297,7 +5345,9 @@ create_titlebar (GtkWindow *window)
 | 
				
			|||||||
  gchar *title;
 | 
					  gchar *title;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  titlebar = gtk_header_bar_new ();
 | 
					  titlebar = gtk_header_bar_new ();
 | 
				
			||||||
  g_object_set (titlebar, "spacing", 0, NULL);
 | 
					  g_object_set (titlebar,
 | 
				
			||||||
 | 
					                "spacing", 0,
 | 
				
			||||||
 | 
					                NULL);
 | 
				
			||||||
  context = gtk_widget_get_style_context (titlebar);
 | 
					  context = gtk_widget_get_style_context (titlebar);
 | 
				
			||||||
  gtk_style_context_add_class (context, GTK_STYLE_CLASS_TITLEBAR);
 | 
					  gtk_style_context_add_class (context, GTK_STYLE_CLASS_TITLEBAR);
 | 
				
			||||||
  gtk_style_context_add_class (context, "default-decoration");
 | 
					  gtk_style_context_add_class (context, "default-decoration");
 | 
				
			||||||
@ -11687,3 +11737,10 @@ _gtk_window_handle_button_press_for_widget (GtkWidget      *widget,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return FALSE;
 | 
					  return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					_gtk_window_get_decoration_size (GtkWindow *window,
 | 
				
			||||||
 | 
					                                 GtkBorder *border)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  get_decoration_size (window, border);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -87,7 +87,10 @@ void            _gtk_window_schedule_mnemonics_visible (GtkWindow *window);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void            _gtk_window_notify_keys_changed (GtkWindow *window);
 | 
					void            _gtk_window_notify_keys_changed (GtkWindow *window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GtkWidget      *_gtk_window_get_titlebar (GtkWindow *window);
 | 
					gboolean        _gtk_window_titlebar_shows_app_menu (GtkWindow *window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void            _gtk_window_get_decoration_size (GtkWindow *window,
 | 
				
			||||||
 | 
					                                                 GtkBorder *border);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user