[evolution] Move menu bar handling to utils
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Move menu bar handling to utils
- Date: Thu, 21 Jul 2022 11:49:06 +0000 (UTC)
commit aa1814e414e19e451d3f2e72139afe835b5e494a
Author: Cédric Bellegarde <cedric bellegarde adishatz org>
Date: Mon May 30 21:39:26 2022 +0200
Move menu bar handling to utils
.../evolution-util/evolution-util-docs.sgml.in | 1 +
src/e-util/CMakeLists.txt | 2 +
src/e-util/e-menu-bar.c | 284 +++++++++++++++++++++
src/e-util/e-menu-bar.h | 60 +++++
src/e-util/e-util.h | 1 +
src/shell/e-shell-window-private.c | 119 +--------
src/shell/e-shell-window-private.h | 5 +-
src/shell/e-shell-window.c | 7 +-
8 files changed, 357 insertions(+), 122 deletions(-)
---
diff --git a/docs/reference/evolution-util/evolution-util-docs.sgml.in
b/docs/reference/evolution-util/evolution-util-docs.sgml.in
index 5b9898aedd..1f13919787 100644
--- a/docs/reference/evolution-util/evolution-util-docs.sgml.in
+++ b/docs/reference/evolution-util/evolution-util-docs.sgml.in
@@ -284,6 +284,7 @@
<xi:include href="xml/e-mail-identity-combo-box.xml"/>
<xi:include href="xml/e-map.xml"/>
<xi:include href="xml/e-markdown-editor.xml"/>
+ <xi:include href="xml/e-menu-bar.xml"/>
<xi:include href="xml/e-mktemp.xml"/>
<xi:include href="xml/e-month-widget.xml"/>
<xi:include href="xml/e-name-selector-dialog.xml"/>
diff --git a/src/e-util/CMakeLists.txt b/src/e-util/CMakeLists.txt
index 1b8a3dd1da..bf79e18567 100644
--- a/src/e-util/CMakeLists.txt
+++ b/src/e-util/CMakeLists.txt
@@ -173,6 +173,7 @@ set(SOURCES
e-markdown-utils.c
e-marshal.c
e-headerbar-button.c
+ e-menu-bar.c
e-misc-utils.c
e-mktemp.c
e-month-widget.c
@@ -450,6 +451,7 @@ set(HEADERS
e-markdown-editor.h
e-markdown-utils.h
e-headerbar-button.h
+ e-menu-bar.h
e-misc-utils.h
e-mktemp.h
e-month-widget.h
diff --git a/src/e-util/e-menu-bar.c b/src/e-util/e-menu-bar.c
new file mode 100644
index 0000000000..d679aadf87
--- /dev/null
+++ b/src/e-util/e-menu-bar.c
@@ -0,0 +1,284 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * SPDX-FileCopyrightText: (C) 2022 Cédric Bellegarde <cedric bellegarde adishatz org>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "evolution-config.h"
+
+#include "e-menu-bar.h"
+
+struct _EMenuBarPrivate {
+ GtkWidget *inner_menu_bar;
+
+ guint visible : 1;
+ gulong delayed_show_id;
+ gulong delayed_hide_id;
+};
+
+G_DEFINE_TYPE_WITH_CODE (EMenuBar, e_menu_bar, G_TYPE_OBJECT,
+ G_ADD_PRIVATE (EMenuBar))
+
+
+enum {
+ PROP_0,
+ PROP_VISIBLE
+};
+
+static void
+menu_bar_visible_settings_changed_cb (GSettings *settings,
+ const gchar *key,
+ gpointer data)
+{
+ g_return_if_fail (E_IS_MENU_BAR (data));
+
+ e_menu_bar_set_visible (
+ E_MENU_BAR (data),
+ g_settings_get_boolean (settings, key));
+}
+
+static void
+menu_bar_dispose (GObject *menu_bar)
+{
+ EMenuBar *self = E_MENU_BAR (menu_bar);
+
+ if (self->priv->delayed_show_id) {
+ g_source_remove (self->priv->delayed_show_id);
+ self->priv->delayed_show_id = 0;
+ }
+
+ if (self->priv->delayed_hide_id) {
+ g_source_remove (self->priv->delayed_hide_id);
+ self->priv->delayed_hide_id = 0;
+ }
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_menu_bar_parent_class)->dispose (menu_bar);
+}
+
+static void
+menu_bar_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EMenuBar *menubar = E_MENU_BAR (object);
+
+ switch (property_id) {
+ case PROP_VISIBLE:
+ e_menu_bar_set_visible (
+ menubar,
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+menu_bar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EMenuBar *menubar = E_MENU_BAR (object);
+
+ switch (property_id) {
+ case PROP_VISIBLE:
+ g_value_set_boolean (
+ value, e_menu_bar_get_visible (menubar));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+e_menu_bar_class_init (EMenuBarClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = menu_bar_dispose;
+ object_class->set_property = menu_bar_set_property;
+ object_class->get_property = menu_bar_get_property;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_VISIBLE,
+ g_param_spec_boolean (
+ "visible",
+ "Visible",
+ "Inner menubar visible",
+ FALSE,
+ G_PARAM_READWRITE));
+}
+
+static void
+e_menu_bar_init (EMenuBar *self)
+{
+ self->priv = e_menu_bar_get_instance_private (self);
+}
+
+static gboolean
+delayed_show_cb (gpointer user_data)
+{
+ EMenuBar *self = user_data;
+
+ self->priv->delayed_show_id = 0;
+
+ if (!self->priv->visible) {
+ gtk_widget_set_visible (GTK_WIDGET (self->priv->inner_menu_bar), TRUE);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+delayed_hide_cb (gpointer user_data)
+{
+ EMenuBar *self = user_data;
+ GtkWidget *widget = GTK_WIDGET (self->priv->inner_menu_bar);
+
+ self->priv->delayed_hide_id = 0;
+
+ if (!self->priv->visible &&
+ !self->priv->delayed_show_id) {
+ if (gtk_widget_get_visible (widget) &&
+ !gtk_menu_shell_get_selected_item (GTK_MENU_SHELL (self->priv->inner_menu_bar)))
+ gtk_widget_set_visible (widget, FALSE);
+ }
+
+ return FALSE;
+}
+
+static void
+e_menu_bar_window_event_after_cb (GtkWindow *window,
+ GdkEvent *event,
+ EMenuBar *self)
+{
+ g_return_if_fail (event != NULL);
+
+ if (event->type != GDK_KEY_PRESS &&
+ event->type != GDK_KEY_RELEASE &&
+ event->type != GDK_BUTTON_RELEASE &&
+ event->type != GDK_FOCUS_CHANGE)
+ return;
+
+ if (event->type == GDK_KEY_PRESS) {
+ GdkEventKey *key_event;
+
+ key_event = (GdkEventKey *) event;
+
+ if ((key_event->keyval == GDK_KEY_Alt_L || key_event->keyval == GDK_KEY_Alt_R) &&
+ !(key_event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK |
+ GDK_SUPER_MASK | GDK_HYPER_MASK |
+ GDK_META_MASK))) {
+ if (self->priv->delayed_hide_id) {
+ g_source_remove (self->priv->delayed_hide_id);
+ self->priv->delayed_hide_id = 0;
+ }
+
+ if (self->priv->delayed_show_id) {
+ g_source_remove (self->priv->delayed_show_id);
+ self->priv->delayed_show_id = 0;
+
+ delayed_show_cb (self);
+ } else {
+ /* To not flash when using Alt+Tab or
+ similar system-wide shortcuts */
+ self->priv->delayed_show_id =
+ g_timeout_add (250, delayed_show_cb, self);
+ }
+ }
+ } else if (event->type != GDK_BUTTON_RELEASE || !(event->button.state & GDK_MOD1_MASK)) {
+ if (self->priv->delayed_show_id) {
+ g_source_remove (self->priv->delayed_show_id);
+ self->priv->delayed_show_id = 0;
+ }
+
+ if (gtk_widget_get_visible (GTK_WIDGET (self->priv->inner_menu_bar)) &&
+ !self->priv->delayed_hide_id) {
+ self->priv->delayed_hide_id =
+ g_timeout_add (500, delayed_hide_cb, self);
+ }
+ }
+}
+
+/**
+ * e_menu_bar_new:
+ * @inner_menu_bar: #GtkMenuBar to handle
+ * @window: monitor #GtkWindow for <Alt> key event
+ *
+ * Creates a new #EMenuBar showing @inner_menu_bar on demand
+ *
+ * Returns: (transfer full): a new #EMenuBar
+ *
+ * Since: 3.46
+ **/
+GtkWidget *
+e_menu_bar_new (GtkMenuBar *inner_menu_bar,
+ GtkWindow *window)
+{
+ GtkWidget *menu_bar;
+ GSettings *settings;
+
+ g_return_val_if_fail (GTK_IS_MENU_BAR (inner_menu_bar), NULL);
+ g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
+
+ menu_bar = g_object_new (E_TYPE_MENU_BAR, NULL);
+ E_MENU_BAR (menu_bar)->priv->inner_menu_bar = GTK_WIDGET (inner_menu_bar);
+
+ settings = e_util_ref_settings ("org.gnome.evolution.shell");
+ g_signal_connect (
+ settings, "changed::menubar-visible",
+ G_CALLBACK (menu_bar_visible_settings_changed_cb),
+ menu_bar);
+ e_menu_bar_set_visible (
+ E_MENU_BAR (menu_bar),
+ g_settings_get_boolean (settings, "menubar-visible"));
+ g_object_unref (settings);
+
+ g_signal_connect_object (window, "event-after",
+ G_CALLBACK (e_menu_bar_window_event_after_cb), menu_bar, G_CONNECT_AFTER);
+
+ return menu_bar;
+}
+
+/**
+ * e_menu_bar_get_visible:
+ * @self: a #EMenuBar
+ *
+ * Determines whether the inner menu bar is visible.
+ *
+ * Returns: %TRUE if the inner menu bar is visible
+ *
+ * Since: 3.46
+ **/
+gboolean
+e_menu_bar_get_visible (EMenuBar *self)
+{
+ g_return_val_if_fail (E_IS_MENU_BAR (self), FALSE);
+
+ return self->priv->visible;
+}
+
+/**
+ * e_menu_bar_set_visible:
+ * @self: a #EMenuBar
+ * @visible: whether the inner menu bar should be shown or not
+ *
+ * Sets the visibility state of the inner menu bar.
+ *
+ * Since: 3.46
+ **/
+void
+e_menu_bar_set_visible (EMenuBar *menu_bar,
+ gboolean visible)
+{
+ g_return_if_fail (E_IS_MENU_BAR (menu_bar));
+
+ menu_bar->priv->visible = visible;
+ gtk_widget_set_visible (GTK_WIDGET (menu_bar->priv->inner_menu_bar), visible);
+}
diff --git a/src/e-util/e-menu-bar.h b/src/e-util/e-menu-bar.h
new file mode 100644
index 0000000000..c293f876f5
--- /dev/null
+++ b/src/e-util/e-menu-bar.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * SPDX-FileCopyrightText: (C) 2022 Cédric Bellegarde <cedric bellegarde adishatz org>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_MENUBAR_H
+#define E_MENUBAR_H
+
+#include <gtk/gtk.h>
+#include <e-util/e-util.h>
+
+#define E_TYPE_MENU_BAR \
+ (e_menu_bar_get_type ())
+#define E_MENU_BAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MENU_BAR, EMenuBar))
+#define E_MENU_BAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MENU_BAR, EMenuBarClass))
+#define E_IS_MENU_BAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MENU_BAR))
+#define E_IS_MENU_BAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MENU_BAR))
+#define E_MENU_BAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MENU_BAR, EMenuBarClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMenuBar EMenuBar;
+typedef struct _EMenuBarClass EMenuBarClass;
+typedef struct _EMenuBarPrivate EMenuBarPrivate;
+
+struct _EMenuBar {
+ GObject parent;
+ EMenuBarPrivate *priv;
+};
+
+struct _EMenuBarClass {
+ GObjectClass parent_class;
+};
+
+GType e_menu_bar_get_type (void);
+GtkWidget * e_menu_bar_new (GtkMenuBar *widget,
+ GtkWindow *window);
+gboolean e_menu_bar_get_visible (EMenuBar *menu_bar);
+void e_menu_bar_set_visible (EMenuBar *menu_bar,
+ gboolean visible);
+
+G_END_DECLS
+
+#endif /* E_MENUBAR_H */
diff --git a/src/e-util/e-util.h b/src/e-util/e-util.h
index 4ba1469e37..673293d9c3 100644
--- a/src/e-util/e-util.h
+++ b/src/e-util/e-util.h
@@ -156,6 +156,7 @@
#include <e-util/e-markdown-editor.h>
#include <e-util/e-markdown-utils.h>
#include <e-util/e-headerbar-button.h>
+#include <e-util/e-menu-bar.h>
#include <e-util/e-misc-utils.h>
#include <e-util/e-mktemp.h>
#include <e-util/e-month-widget.h>
diff --git a/src/shell/e-shell-window-private.c b/src/shell/e-shell-window-private.c
index 2545814b0b..7dce9252e6 100644
--- a/src/shell/e-shell-window-private.c
+++ b/src/shell/e-shell-window-private.c
@@ -269,107 +269,6 @@ e_shell_window_private_init (EShellWindow *shell_window)
G_CALLBACK (shell_window_connect_proxy_cb), shell_window);
}
-static gboolean
-delayed_menubar_show_cb (gpointer user_data)
-{
- EShellWindow *shell_window = user_data;
-
- g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
-
- shell_window->priv->delayed_menubar_show_id = 0;
-
- if (!e_shell_window_get_menubar_visible (shell_window)) {
- GtkWidget *main_menu;
-
- main_menu = e_shell_window_get_managed_widget (shell_window, "/main-menu");
-
- gtk_widget_show (main_menu);
- }
-
- return FALSE;
-}
-
-static gboolean
-delayed_menubar_hide_cb (gpointer user_data)
-{
- EShellWindow *shell_window = user_data;
-
- g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
-
- shell_window->priv->delayed_menubar_hide_id = 0;
-
- if (!e_shell_window_get_menubar_visible (shell_window) &&
- !shell_window->priv->delayed_menubar_show_id) {
- GtkWidget *main_menu;
-
- main_menu = e_shell_window_get_managed_widget (shell_window, "/main-menu");
-
- if (gtk_widget_get_visible (main_menu) &&
- !gtk_menu_shell_get_selected_item (GTK_MENU_SHELL (main_menu)))
- gtk_widget_hide (main_menu);
- }
-
- return FALSE;
-}
-
-static void
-e_shell_window_event_after_cb (EShellWindow *shell_window,
- GdkEvent *event)
-{
- GtkWidget *main_menu;
-
- g_return_if_fail (event != NULL);
-
- if (event->type != GDK_KEY_PRESS &&
- event->type != GDK_KEY_RELEASE &&
- event->type != GDK_BUTTON_RELEASE &&
- event->type != GDK_FOCUS_CHANGE)
- return;
-
- g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
-
- if (e_shell_window_get_menubar_visible (shell_window))
- return;
-
- main_menu = e_shell_window_get_managed_widget (shell_window, "/main-menu");
-
- if (event->type == GDK_KEY_PRESS) {
- GdkEventKey *key_event;
-
- key_event = (GdkEventKey *) event;
-
- if ((key_event->keyval == GDK_KEY_Alt_L || key_event->keyval == GDK_KEY_Alt_R) &&
- !(key_event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_SUPER_MASK | GDK_HYPER_MASK
| GDK_META_MASK))) {
- if (shell_window->priv->delayed_menubar_hide_id) {
- g_source_remove (shell_window->priv->delayed_menubar_hide_id);
- shell_window->priv->delayed_menubar_hide_id = 0;
- }
-
- if (shell_window->priv->delayed_menubar_show_id) {
- g_source_remove (shell_window->priv->delayed_menubar_show_id);
- shell_window->priv->delayed_menubar_show_id = 0;
-
- delayed_menubar_show_cb (shell_window);
- } else {
- /* To not flash when using Alt+Tab or similar system-wide shortcuts */
- shell_window->priv->delayed_menubar_show_id =
- e_named_timeout_add (250, delayed_menubar_show_cb, shell_window);
- }
- }
- } else if (event->type != GDK_BUTTON_RELEASE || !(event->button.state & GDK_MOD1_MASK)) {
- if (shell_window->priv->delayed_menubar_show_id) {
- g_source_remove (shell_window->priv->delayed_menubar_show_id);
- shell_window->priv->delayed_menubar_show_id = 0;
- }
-
- if (gtk_widget_get_visible (main_menu) &&
- !shell_window->priv->delayed_menubar_hide_id) {
- shell_window->priv->delayed_menubar_hide_id =
- e_named_timeout_add (500, delayed_menubar_hide_cb, shell_window);
- }
- }
-}
-
static gboolean
e_shell_window_key_press_event_cb (GtkWidget *widget,
GdkEventKey *event)
@@ -470,8 +369,10 @@ e_shell_window_private_constructed (EShellWindow *shell_window)
box = GTK_BOX (widget);
widget = shell_window_construct_menubar (shell_window);
- if (widget != NULL)
+ if (widget != NULL) {
+ shell_window->priv->menu_bar = e_menu_bar_new (GTK_MENU_BAR (widget), window);
gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ }
widget = shell_window_construct_toolbar (shell_window);
if (widget != NULL)
@@ -684,9 +585,6 @@ e_shell_window_private_constructed (EShellWindow *shell_window)
g_object_unref (settings);
- g_signal_connect (shell_window, "event-after",
- G_CALLBACK (e_shell_window_event_after_cb), NULL);
-
g_signal_connect (shell_window, "key-press-event",
G_CALLBACK (e_shell_window_key_press_event_cb), NULL);
@@ -716,16 +614,6 @@ e_shell_window_private_dispose (EShellWindow *shell_window)
{
EShellWindowPrivate *priv = shell_window->priv;
- if (priv->delayed_menubar_show_id) {
- g_source_remove (priv->delayed_menubar_show_id);
- priv->delayed_menubar_show_id = 0;
- }
-
- if (priv->delayed_menubar_hide_id) {
- g_source_remove (priv->delayed_menubar_hide_id);
- priv->delayed_menubar_hide_id = 0;
- }
-
/* Need to disconnect handlers before we unref the shell. */
if (priv->signal_handler_ids != NULL) {
GArray *array = priv->signal_handler_ids;
@@ -759,6 +647,7 @@ e_shell_window_private_dispose (EShellWindow *shell_window)
g_clear_object (&priv->switcher);
g_clear_object (&priv->tooltip_label);
g_clear_object (&priv->status_notebook);
+ g_clear_object (&priv->menu_bar);
priv->destroyed = TRUE;
}
diff --git a/src/shell/e-shell-window-private.h b/src/shell/e-shell-window-private.h
index de80f8e767..6fecfef838 100644
--- a/src/shell/e-shell-window-private.h
+++ b/src/shell/e-shell-window-private.h
@@ -82,6 +82,7 @@ struct _EShellWindowPrivate {
GtkWidget *tooltip_label;
GtkWidget *status_notebook;
GtkWidget *headerbar;
+ GtkWidget *menu_bar;
/* Shell signal handlers. */
GArray *signal_handler_ids;
@@ -90,16 +91,12 @@ struct _EShellWindowPrivate {
guint destroyed : 1; /* XXX Do we still need this? */
guint safe_mode : 1;
- guint menubar_visible : 1;
guint sidebar_visible : 1;
guint switcher_visible : 1;
guint taskbar_visible : 1;
guint toolbar_visible : 1;
guint is_main_instance : 1;
- gulong delayed_menubar_show_id;
- gulong delayed_menubar_hide_id;
-
GSList *postponed_alerts; /* EAlert * */
};
diff --git a/src/shell/e-shell-window.c b/src/shell/e-shell-window.c
index 6fe7672ad0..a7b302a081 100644
--- a/src/shell/e-shell-window.c
+++ b/src/shell/e-shell-window.c
@@ -1564,7 +1564,8 @@ e_shell_window_get_menubar_visible (EShellWindow *shell_window)
{
g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
- return shell_window->priv->menubar_visible;
+ return shell_window->priv->menu_bar &&
+ e_menu_bar_get_visible (E_MENU_BAR (shell_window->priv->menu_bar));
}
/**
@@ -1584,10 +1585,10 @@ e_shell_window_set_menubar_visible (EShellWindow *shell_window,
g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
- if (shell_window->priv->menubar_visible == menubar_visible)
+ if (e_menu_bar_get_visible (E_MENU_BAR (shell_window->priv->menu_bar)) == menubar_visible)
return;
- shell_window->priv->menubar_visible = menubar_visible;
+ e_menu_bar_set_visible (E_MENU_BAR (shell_window->priv->menu_bar), menubar_visible);
settings = e_util_ref_settings ("org.gnome.evolution.shell");
if (!menubar_visible &&
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]