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

Reply via email to