Good afternoon!
I am port the GtkToolbar to GtkHeaderBar in Nautilus (attached patch).
I could not to expand the patch-bar (child of header_bar).
The relevant code from patch (src/nautilus-header-bar.c):
...
GtkWidget *box, *hbox, *header_bar;
...
header_bar = gtk_header_bar_new ();
self->priv->header_bar = header_bar;
...
/* regular path bar */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_show (hbox);
self->priv->path_bar = g_object_new (NAUTILUS_TYPE_PATH_BAR, NULL);
gtk_widget_set_hexpand (self->priv->path_bar, TRUE);
gtk_box_pack_start (GTK_BOX (hbox), self->priv->path_bar, TRUE, TRUE,
0);
/* entry-like location bar */
self->priv->location_entry = nautilus_location_entry_new ();
gtk_widget_set_hexpand (self->priv->location_entry, TRUE);
gtk_box_pack_start (GTK_BOX (hbox), self->priv->location_entry, TRUE,
TRUE, 0);
gtk_widget_set_hexpand (hbox, TRUE);
gtk_header_bar_pack_start (GTK_HEADER_BAR (self->priv->header_bar),
hbox);
gtk_widget_show (GTK_WIDGET (hbox));
...
The gtk_widget_set_hexpand function it does not affect.
Screenshost:
patch-bar:
https://bitbucket.org/yoseforb/expand-header-bar/raw/e95d5c963051d781c7c029751c8e1fbebbabd49b/patch-bar.png
location-bar:
https://bitbucket.org/yoseforb/expand-header-bar/raw/e95d5c963051d781c7c029751c8e1fbebbabd49b/location-bar.png
Regards,
ā€¸Yosef Or Boczko
>From 9b0ed3f2e6d1c4e65f2706de4cd338515aa1de02 Mon Sep 17 00:00:00 2001
From: Yosef Or Boczko <yosef...@gmail.com>
Date: Sun, 30 Jun 2013 13:48:44 +0300
Subject: Port GtkToolbar to GtkHeaderBar
---
src/Makefile.am | 4 +-
src/nautilus-header-bar.c | 628 +++++++++++++++++++++++++++++++++++++++++
src/nautilus-header-bar.h | 75 +++++
src/nautilus-toolbar.c | 642 ------------------------------------------
src/nautilus-toolbar.h | 77 -----
src/nautilus-window-private.h | 2 +-
src/nautilus-window-slot.c | 2 +-
src/nautilus-window.c | 40 +--
8 files changed, 727 insertions(+), 743 deletions(-)
create mode 100644 src/nautilus-header-bar.c
create mode 100644 src/nautilus-header-bar.h
delete mode 100644 src/nautilus-toolbar.c
delete mode 100644 src/nautilus-toolbar.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 651fccc..61909e5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -185,8 +185,8 @@ nautilus_SOURCES = \
nautilus-shell-search-provider.c \
nautilus-special-location-bar.c \
nautilus-special-location-bar.h \
- nautilus-toolbar.c \
- nautilus-toolbar.h \
+ nautilus-header-bar.c \
+ nautilus-header-bar.h \
nautilus-trash-bar.c \
nautilus-trash-bar.h \
nautilus-view.c \
diff --git a/src/nautilus-header-bar.c b/src/nautilus-header-bar.c
new file mode 100644
index 0000000..2eadbd7
--- /dev/null
+++ b/src/nautilus-header-bar.c
@@ -0,0 +1,628 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/*
+ * Nautilus
+ *
+ * Copyright (C) 2011, Red Hat, Inc.
+ *
+ * Nautilus is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * Nautilus is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Cosimo Cecchi <cosi...@redhat.com>
+ *
+ */
+
+#include <config.h>
+
+#include "nautilus-header-bar.h"
+
+#include "nautilus-location-entry.h"
+#include "nautilus-pathbar.h"
+#include "nautilus-actions.h"
+
+#include <libnautilus-private/nautilus-global-preferences.h>
+#include <libnautilus-private/nautilus-ui-utilities.h>
+
+#include <glib/gi18n.h>
+#include <math.h>
+
+typedef enum {
+ NAUTILUS_NAVIGATION_DIRECTION_NONE,
+ NAUTILUS_NAVIGATION_DIRECTION_BACK,
+ NAUTILUS_NAVIGATION_DIRECTION_FORWARD
+} NautilusNavigationDirection;
+
+struct _NautilusHeaderBarPriv {
+ GtkWidget *header_bar;
+ NautilusWindow *window;
+
+ GtkWidget *path_bar;
+ GtkWidget *location_entry;
+
+ GtkToolItem *back_forward;
+
+ gboolean show_location_entry;
+
+ guint popup_timeout_id;
+};
+
+enum {
+ PROP_WINDOW = 1,
+ PROP_SHOW_LOCATION_ENTRY,
+ NUM_PROPERTIES
+};
+
+static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
+
+G_DEFINE_TYPE (NautilusHeaderBar, nautilus_header_bar, GTK_TYPE_BOX);
+
+static void unschedule_menu_popup_timeout (NautilusHeaderBar *self);
+
+static void
+header_bar_update_appearance (NautilusHeaderBar *self)
+{
+ gboolean show_location_entry;
+
+ show_location_entry = self->priv->show_location_entry ||
+ g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY);
+
+ gtk_widget_set_visible (self->priv->location_entry,
+ show_location_entry);
+ gtk_widget_set_visible (self->priv->path_bar,
+ !show_location_entry);
+}
+
+static gint
+get_icon_margin (NautilusHeaderBar *self)
+{
+ GtkIconSize toolbar_size;
+ gint toolbar_size_px, menu_size_px;
+
+ g_object_get (gtk_settings_get_default (), "gtk-toolbar-icon-size", &toolbar_size, NULL);
+ /* toolbar_size = GTK_ICON_SIZE_SMALL_TOOLBAR; */
+
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &menu_size_px, NULL);
+ gtk_icon_size_lookup (toolbar_size, &toolbar_size_px, NULL);
+
+ return (gint) floor ((toolbar_size_px - menu_size_px) / 2.0);
+}
+
+static GtkWidget *
+header_bar_create_toolbutton (NautilusHeaderBar *self,
+ gboolean create_menu,
+ gboolean create_toggle,
+ const gchar *name,
+ const gchar *tooltip)
+{
+ GtkWidget *button, *image;
+ GtkActionGroup *action_group;
+ GtkAction *action;
+
+ action_group = nautilus_window_get_main_action_group (self->priv->window);
+
+ if (create_menu) {
+ button = gtk_menu_button_new ();
+ } else if (create_toggle) {
+ button = gtk_toggle_button_new ();
+ } else {
+ button = gtk_button_new ();
+ }
+
+ image = gtk_image_new ();
+ g_object_set (image, "margin", get_icon_margin (self), NULL);
+
+ gtk_button_set_image (GTK_BUTTON (button), image);
+
+ if (create_menu) {
+ gtk_image_set_from_icon_name (GTK_IMAGE (image), name,
+ GTK_ICON_SIZE_MENU);
+ gtk_widget_set_tooltip_text (button, tooltip);
+ } else {
+ action = gtk_action_group_get_action (action_group, name);
+ gtk_activatable_set_related_action (GTK_ACTIVATABLE (button), action);
+ gtk_button_set_label (GTK_BUTTON (button), NULL);
+ gtk_widget_set_tooltip_text (button, gtk_action_get_tooltip (action));
+ }
+
+ return button;
+}
+
+static void
+activate_back_or_forward_menu_item (GtkMenuItem *menu_item,
+ NautilusWindow *window,
+ gboolean back)
+{
+ int index;
+
+ g_assert (GTK_IS_MENU_ITEM (menu_item));
+
+ index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "user_data"));
+
+ nautilus_window_back_or_forward (window, back, index, nautilus_event_get_window_open_flags ());
+}
+
+static void
+activate_back_menu_item_callback (GtkMenuItem *menu_item,
+ NautilusWindow *window)
+{
+ activate_back_or_forward_menu_item (menu_item, window, TRUE);
+}
+
+static void
+activate_forward_menu_item_callback (GtkMenuItem *menu_item, NautilusWindow *window)
+{
+ activate_back_or_forward_menu_item (menu_item, window, FALSE);
+}
+
+static void
+fill_menu (NautilusWindow *window,
+ GtkWidget *menu,
+ gboolean back)
+{
+ NautilusWindowSlot *slot;
+ GtkWidget *menu_item;
+ int index;
+ GList *list;
+
+ slot = nautilus_window_get_active_slot (window);
+ list = back ? nautilus_window_slot_get_back_history (slot) :
+ nautilus_window_slot_get_forward_history (slot);
+
+ index = 0;
+ while (list != NULL) {
+ menu_item = nautilus_bookmark_menu_item_new (NAUTILUS_BOOKMARK (list->data));
+ g_object_set_data (G_OBJECT (menu_item), "user_data", GINT_TO_POINTER (index));
+ gtk_widget_show (GTK_WIDGET (menu_item));
+ g_signal_connect_object (menu_item, "activate",
+ back
+ ? G_CALLBACK (activate_back_menu_item_callback)
+ : G_CALLBACK (activate_forward_menu_item_callback),
+ window, 0);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+ list = g_list_next (list);
+ ++index;
+ }
+}
+
+/* adapted from gtk/gtkmenubutton.c */
+static void
+menu_position_func (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ GtkWidget *widget)
+{
+ GtkWidget *toplevel;
+ GtkRequisition menu_req;
+ GdkRectangle monitor;
+ gint monitor_num;
+ GdkScreen *screen;
+ GdkWindow *window;
+ GtkAllocation allocation;
+
+ /* Set the dropdown menu hint on the toplevel, so the WM can omit the top side
+ * of the shadows.
+ */
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (menu));
+ gtk_window_set_type_hint (GTK_WINDOW (toplevel), GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU);
+
+ window = gtk_widget_get_window (widget);
+ screen = gtk_widget_get_screen (GTK_WIDGET (menu));
+ monitor_num = gdk_screen_get_monitor_at_window (screen, window);
+ if (monitor_num < 0) {
+ monitor_num = 0;
+ }
+
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
+ gtk_widget_get_preferred_size (GTK_WIDGET (menu), &menu_req, NULL);
+ gtk_widget_get_allocation (widget, &allocation);
+ gdk_window_get_origin (window, x, y);
+
+ *x += allocation.x;
+ *y += allocation.y;
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) {
+ *x -= MAX (menu_req.width - allocation.width, 0);
+ } else {
+ *x += MAX (allocation.width - menu_req.width, 0);
+ }
+
+ if ((*y + allocation.height + menu_req.height) <= monitor.y + monitor.height) {
+ *y += allocation.height;
+ } else if ((*y - menu_req.height) >= monitor.y) {
+ *y -= menu_req.height;
+ } else if (monitor.y + monitor.height - (*y + allocation.height) > *y) {
+ *y += allocation.height;
+ } else {
+ *y -= menu_req.height;
+ }
+
+ *push_in = FALSE;
+}
+
+static void
+show_menu (NautilusHeaderBar *self,
+ GtkWidget *widget,
+ guint button,
+ guint32 event_time)
+{
+ NautilusWindow *window;
+ GtkWidget *menu;
+ NautilusNavigationDirection direction;
+
+ window = self->priv->window;
+ menu = gtk_menu_new ();
+
+ direction = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
+ "nav-direction"));
+
+ switch (direction) {
+ case NAUTILUS_NAVIGATION_DIRECTION_FORWARD:
+ fill_menu (window, menu, FALSE);
+ break;
+ case NAUTILUS_NAVIGATION_DIRECTION_BACK:
+ fill_menu (window, menu, TRUE);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
+ (GtkMenuPositionFunc) menu_position_func, widget,
+ button, event_time);
+}
+
+#define MENU_POPUP_TIMEOUT 1200
+
+typedef struct {
+ NautilusHeaderBar *self;
+ GtkWidget *widget;
+} ScheduleMenuData;
+
+static void
+schedule_menu_data_free (ScheduleMenuData *data)
+{
+ g_slice_free (ScheduleMenuData, data);
+}
+
+static gboolean
+popup_menu_timeout_cb (gpointer user_data)
+{
+ ScheduleMenuData *data = user_data;
+
+ show_menu (data->self, data->widget,
+ 1, gtk_get_current_event_time ());
+
+ return FALSE;
+}
+
+static void
+unschedule_menu_popup_timeout (NautilusHeaderBar *self)
+{
+ if (self->priv->popup_timeout_id != 0) {
+ g_source_remove (self->priv->popup_timeout_id);
+ self->priv->popup_timeout_id = 0;
+ }
+}
+
+static void
+schedule_menu_popup_timeout (NautilusHeaderBar *self,
+ GtkWidget *widget)
+{
+ ScheduleMenuData *data;
+
+ /* unschedule any previous timeouts */
+ unschedule_menu_popup_timeout (self);
+
+ data = g_slice_new0 (ScheduleMenuData);
+ data->self = self;
+ data->widget = widget;
+
+ self->priv->popup_timeout_id =
+ g_timeout_add_full (G_PRIORITY_DEFAULT, MENU_POPUP_TIMEOUT,
+ popup_menu_timeout_cb, data,
+ (GDestroyNotify) schedule_menu_data_free);
+}
+
+static gboolean
+tool_button_press_cb (GtkButton *button,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ NautilusHeaderBar *self = user_data;
+
+ if (event->button == 3) {
+ /* right click */
+ show_menu (self, GTK_WIDGET (button), event->button, event->time);
+ return TRUE;
+ }
+
+ if (event->button == 1) {
+ schedule_menu_popup_timeout (self, GTK_WIDGET (button));
+ }
+
+ return FALSE;
+}
+
+static gboolean
+tool_button_release_cb (GtkButton *button,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ NautilusHeaderBar *self = user_data;
+
+ unschedule_menu_popup_timeout (self);
+
+ return FALSE;
+}
+
+static void
+navigation_button_setup_menu (NautilusHeaderBar *self,
+ GtkWidget *button,
+ NautilusNavigationDirection direction)
+{
+ g_object_set_data (G_OBJECT (button), "nav-direction", GUINT_TO_POINTER (direction));
+
+ g_signal_connect (button, "button-press-event",
+ G_CALLBACK (tool_button_press_cb), self);
+ g_signal_connect (button, "button-release-event",
+ G_CALLBACK (tool_button_release_cb), self);
+}
+
+static gboolean
+gear_menu_key_press (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ GdkModifierType mask = gtk_accelerator_get_default_mod_mask ();
+
+ if ((event->state & mask) == 0 && (event->keyval == GDK_KEY_F10)) {
+ gtk_menu_shell_deactivate (GTK_MENU_SHELL (widget));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+nautilus_header_bar_constructed (GObject *obj)
+{
+ NautilusHeaderBar *self = NAUTILUS_HEADER_BAR (obj);
+ GtkWidget *box, *hbox, *header_bar;
+ GtkWidget *tool_button;
+ GtkWidget *menu;
+ GtkWidget *back_forward;
+ GtkUIManager *ui_manager;
+
+ G_OBJECT_CLASS (nautilus_header_bar_parent_class)->constructed (obj);
+
+ ui_manager = nautilus_window_get_ui_manager (self->priv->window);
+
+ gtk_style_context_set_junction_sides (gtk_widget_get_style_context (GTK_WIDGET (self)),
+ GTK_JUNCTION_BOTTOM);
+
+ header_bar = gtk_header_bar_new ();
+ self->priv->header_bar = header_bar;
+
+ gtk_box_pack_start (GTK_BOX (self), self->priv->header_bar, TRUE, TRUE, 0);
+ //~ gtk_window_set_titlebar (GTK_WINDOW (self->priv->window), self->priv->header_bar);
+ gtk_widget_show_all (self->priv->header_bar);
+
+ /* Back and Forward */
+ back_forward = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+
+ /* Back */
+ tool_button = header_bar_create_toolbutton (self, FALSE, FALSE, NAUTILUS_ACTION_BACK, NULL);
+ navigation_button_setup_menu (self, tool_button, NAUTILUS_NAVIGATION_DIRECTION_BACK);
+ gtk_container_add (GTK_CONTAINER (back_forward), GTK_WIDGET (tool_button));
+
+ /* Forward */
+ tool_button = header_bar_create_toolbutton (self, FALSE, FALSE, NAUTILUS_ACTION_FORWARD, NULL);
+ navigation_button_setup_menu (self, tool_button, NAUTILUS_NAVI
--
nautilus-list mailing list
nautilus-list@gnome.org
https://mail.gnome.org/mailman/listinfo/nautilus-list