[gnome-text-editor] tab-menu: implement tab menus for tab bar
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-text-editor] tab-menu: implement tab menus for tab bar
- Date: Tue, 26 Oct 2021 22:23:13 +0000 (UTC)
commit 4f0aa0a0a09725f932e7a72d147313012f1427c9
Author: Christian Hergert <chergert redhat com>
Date: Tue Oct 26 15:15:03 2021 -0700
tab-menu: implement tab menus for tab bar
These were lost during the transition from notebook back to AdwTabBar. We
also handle the cases with modified pages a bit better now by joining them
together into a single dialog request.
Fixes #199
src/editor-page-private.h | 3 ++
src/editor-page.c | 18 ++++++++
src/editor-session.c | 15 ++++---
src/editor-window-actions.c | 23 ++++++++++
src/editor-window-private.h | 3 ++
src/editor-window.c | 102 +++++++++++++++++++++++++++++++++++---------
src/editor-window.ui | 1 +
src/menus.ui | 10 ++---
8 files changed, 144 insertions(+), 31 deletions(-)
---
diff --git a/src/editor-page-private.h b/src/editor-page-private.h
index 6a3b936..43f6b61 100644
--- a/src/editor-page-private.h
+++ b/src/editor-page-private.h
@@ -59,6 +59,7 @@ struct _EditorPage
GtkInfoBar *infobar;
guint close_requested : 1;
+ guint moving : 1;
};
void _editor_page_class_actions_init (EditorPageClass *klass);
@@ -89,5 +90,7 @@ void _editor_page_move_next_search (EditorPage *self,
gboolean hide_after_search);
void _editor_page_move_previous_search (EditorPage *self,
gboolean hide_after_search);
+void _editor_page_begin_move (EditorPage *self);
+void _editor_page_end_move (EditorPage *self);
G_END_DECLS
diff --git a/src/editor-page.c b/src/editor-page.c
index a132898..69a3b59 100644
--- a/src/editor-page.c
+++ b/src/editor-page.c
@@ -1285,3 +1285,21 @@ editor_page_grab_focus (EditorPage *self)
_editor_page_raise (self);
gtk_widget_grab_focus (GTK_WIDGET (self->view));
}
+
+void
+_editor_page_begin_move (EditorPage *self)
+{
+ g_return_if_fail (!self->moving);
+
+ g_object_ref (self);
+ self->moving = TRUE;
+}
+
+void
+_editor_page_end_move (EditorPage *self)
+{
+ g_return_if_fail (self->moving);
+
+ self->moving = FALSE;
+ g_object_unref (self);
+}
diff --git a/src/editor-session.c b/src/editor-session.c
index 6b3caf3..f7bc2f0 100644
--- a/src/editor-session.c
+++ b/src/editor-session.c
@@ -2018,23 +2018,24 @@ _editor_session_remove_draft (EditorSession *self,
void
_editor_session_move_page_to_window (EditorSession *self,
- EditorPage *page,
+ EditorPage *epage,
EditorWindow *window)
{
EditorWindow *old_window;
g_return_if_fail (EDITOR_IS_SESSION (self));
- g_return_if_fail (EDITOR_IS_PAGE (page));
+ g_return_if_fail (EDITOR_IS_PAGE (epage));
g_return_if_fail (EDITOR_IS_WINDOW (window));
- old_window = _editor_page_get_window (page);
+ old_window = _editor_page_get_window (epage);
if (window != old_window)
{
- g_object_ref (page);
- _editor_window_remove_page (old_window, page);
- _editor_window_add_page (window, page);
- g_object_unref (page);
+ AdwTabPage *page = adw_tab_view_get_page (old_window->tab_view, GTK_WIDGET (epage));
+
+ _editor_page_begin_move (epage);
+ adw_tab_view_transfer_page (old_window->tab_view, page, window->tab_view, 0);
+ _editor_page_end_move (epage);
}
}
diff --git a/src/editor-window-actions.c b/src/editor-window-actions.c
index 77184b5..cde11c0 100644
--- a/src/editor-window-actions.c
+++ b/src/editor-window-actions.c
@@ -539,6 +539,24 @@ editor_window_actions_hide_preferences_cb (GtkWidget *widget,
adw_flap_set_reveal_flap (self->flap, FALSE);
}
+static void
+editor_window_actions_close_other_pages_cb (GtkWidget *widget,
+ const char *action_name,
+ GVariant *param)
+{
+ EditorWindow *self = (EditorWindow *)widget;
+ EditorPage *current_page;
+ GList *pages;
+
+ g_assert (EDITOR_IS_WINDOW (self));
+
+ current_page = editor_window_get_visible_page (self);
+ pages = _editor_window_get_pages (self);
+ pages = g_list_remove (pages, current_page);
+ _editor_window_request_close_pages (self, pages, TRUE);
+ g_list_free (pages);
+}
+
void
_editor_window_class_actions_init (EditorWindowClass *klass)
{
@@ -556,6 +574,10 @@ _editor_window_class_actions_init (EditorWindowClass *klass)
"win.close-page-or-window",
NULL,
editor_window_actions_close_page_cb);
+ gtk_widget_class_install_action (widget_class,
+ "win.close-other-pages",
+ NULL,
+ editor_window_actions_close_other_pages_cb);
gtk_widget_class_install_action (widget_class,
"win.open",
NULL,
@@ -699,6 +721,7 @@ _editor_window_actions_update (EditorWindow *self,
}
gtk_widget_action_set_enabled (GTK_WIDGET (self), "win.close-current-page", has_page);
+ gtk_widget_action_set_enabled (GTK_WIDGET (self), "win.close-other-pages", has_page);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "page.change-language", has_page);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "page.discard-changes", externally_modified || (modified
&& !draft));
gtk_widget_action_set_enabled (GTK_WIDGET (self), "page.print", has_page);
diff --git a/src/editor-window-private.h b/src/editor-window-private.h
index b28b0d4..f2a5722 100644
--- a/src/editor-window-private.h
+++ b/src/editor-window-private.h
@@ -79,5 +79,8 @@ void _editor_window_remove_page (EditorWindow *self,
void _editor_window_focus_search (EditorWindow *self);
gboolean _editor_window_request_close_page (EditorWindow *self,
EditorPage *page);
+gboolean _editor_window_request_close_pages (EditorWindow *self,
+ GList *pages,
+ gboolean close_saved);
G_END_DECLS
diff --git a/src/editor-window.c b/src/editor-window.c
index 29bcf22..bafc2d6 100644
--- a/src/editor-window.c
+++ b/src/editor-window.c
@@ -306,6 +306,7 @@ editor_window_constructed (GObject *object)
GtkPopover *popover;
GMenu *options_menu;
GMenu *primary_menu;
+ GMenu *tab_menu;
g_assert (EDITOR_IS_WINDOW (self));
@@ -314,6 +315,9 @@ editor_window_constructed (GObject *object)
app = GTK_APPLICATION (EDITOR_APPLICATION_DEFAULT);
session = editor_application_get_session (EDITOR_APPLICATION_DEFAULT);
+ tab_menu = gtk_application_get_menu_by_id (app, "tab-menu");
+ adw_tab_view_set_menu_model (self->tab_view, G_MENU_MODEL (tab_menu));
+
/* Set the recents list for the open popover */
g_object_bind_property (session, "recents",
self->open_menu_popover, "model",
@@ -364,15 +368,17 @@ on_tab_view_close_page_cb (EditorWindow *self,
if (page != adw_tab_view_get_selected_page (view))
adw_tab_view_set_selected_page (view, page);
- if ((epage = EDITOR_PAGE (adw_tab_page_get_child (page))))
- {
- epage->close_requested = TRUE;
+ epage = EDITOR_PAGE (adw_tab_page_get_child (page));
- if (_editor_window_request_close_page (self, epage))
- {
- editor_session_remove_page (EDITOR_SESSION_DEFAULT, epage);
- return FALSE;
- }
+ if (epage->moving)
+ return TRUE;
+
+ epage->close_requested = TRUE;
+
+ if (_editor_window_request_close_page (self, epage))
+ {
+ editor_session_remove_page (EDITOR_SESSION_DEFAULT, epage);
+ return FALSE;
}
return TRUE;
@@ -428,23 +434,80 @@ gboolean
_editor_window_request_close_page (EditorWindow *self,
EditorPage *page)
{
+ GList *list;
+ gboolean ret;
+
g_return_val_if_fail (EDITOR_IS_WINDOW (self), FALSE);
g_return_val_if_fail (EDITOR_IS_PAGE (page), FALSE);
- /* If this document has changes, then request the user to save them. */
- if (editor_page_get_is_modified (page))
+ if (page->moving)
+ return TRUE;
+
+ list = g_list_append (NULL, page);
+ ret = _editor_window_request_close_pages (self, list, FALSE);
+ g_list_free (list);
+
+ return ret;
+}
+
+gboolean
+_editor_window_request_close_pages (EditorWindow *self,
+ GList *pages,
+ gboolean close_saved)
+{
+ g_autoptr(GPtrArray) ar = NULL;
+
+ g_return_val_if_fail (EDITOR_IS_WINDOW (self), FALSE);
+
+ if (pages == NULL)
+ return TRUE;
+
+ ar = g_ptr_array_new_with_free_func (g_object_unref);
+
+ for (const GList *iter = pages; iter; iter = iter->next)
{
- g_autoptr(GPtrArray) pages = g_ptr_array_new_with_free_func (g_object_unref);
- g_ptr_array_add (pages, g_object_ref (page));
- _editor_save_changes_dialog_run_async (GTK_WINDOW (self),
- pages,
- NULL,
- editor_window_actions_close_page_confirm_cb,
- g_ptr_array_ref (pages));
- return FALSE;
+ EditorPage *page = iter->data;
+
+ if (editor_page_get_is_modified (page))
+ g_ptr_array_add (ar, g_object_ref (page));
+ else if (close_saved)
+ editor_session_remove_page (EDITOR_SESSION_DEFAULT, page);
}
- return TRUE;
+ if (ar->len == 0)
+ return TRUE;
+
+ _editor_save_changes_dialog_run_async (GTK_WINDOW (self),
+ ar,
+ NULL,
+ editor_window_actions_close_page_confirm_cb,
+ g_ptr_array_ref (ar));
+
+ return FALSE;
+}
+
+static void
+on_tab_view_setup_menu_cb (EditorWindow *self,
+ AdwTabPage *page,
+ AdwTabView *view)
+{
+ EditorPage *epage;
+
+ g_assert (EDITOR_IS_WINDOW (self));
+ g_assert (!page || ADW_IS_TAB_PAGE (page));
+ g_assert (ADW_IS_TAB_VIEW (view));
+
+ if (page == NULL)
+ return;
+
+ /* If the tab is not the current page, change to it so that
+ * win/page actions apply to the proper page.
+ */
+
+ epage = EDITOR_PAGE (adw_tab_page_get_child (page));
+
+ if (epage != self->visible_page)
+ editor_window_set_visible_page (self, epage);
}
static void
@@ -574,6 +637,7 @@ editor_window_class_init (EditorWindowClass *klass)
gtk_widget_class_bind_template_callback (widget_class, on_tab_view_close_page_cb);
gtk_widget_class_bind_template_callback (widget_class, on_notify_reveal_flap_cb);
+ gtk_widget_class_bind_template_callback (widget_class, on_tab_view_setup_menu_cb);
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_w, GDK_CONTROL_MASK,
"win.close-page-or-window", NULL);
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_o, GDK_CONTROL_MASK, "win.open", NULL);
diff --git a/src/editor-window.ui b/src/editor-window.ui
index d538045..2428fc4 100644
--- a/src/editor-window.ui
+++ b/src/editor-window.ui
@@ -150,6 +150,7 @@
<property name="hexpand">true</property>
<property name="vexpand">true</property>
<signal name="close-page" handler="on_tab_view_close_page_cb" swapped="true"/>
+ <signal name="setup-menu" handler="on_tab_view_setup_menu_cb" swapped="true"/>
</object>
</child>
</object>
diff --git a/src/menus.ui b/src/menus.ui
index 34de1cb..d6c04d7 100644
--- a/src/menus.ui
+++ b/src/menus.ui
@@ -149,30 +149,30 @@
<section>
<item>
<attribute name="label" translatable="yes">Move _Left</attribute>
- <attribute name="action">tab.move-left</attribute>
+ <attribute name="action">page.move-left</attribute>
<attribute name="accel"><control><shift><alt>Page_Up</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Move _Right</attribute>
- <attribute name="action">tab.move-right</attribute>
+ <attribute name="action">page.move-right</attribute>
<attribute name="accel"><control><shift><alt>Page_Down</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Move to New Window</attribute>
- <attribute name="action">tab.move-to-new-window</attribute>
+ <attribute name="action">page.move-to-new-window</attribute>
<attribute name="accel"><control><shift>n</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Close _Other Tabs</attribute>
- <attribute name="action">tab.close-other-tabs</attribute>
+ <attribute name="action">win.close-other-pages</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Close</attribute>
- <attribute name="action">tab.close</attribute>
+ <attribute name="action">win.close-current-page</attribute>
<attribute name="accel"><control>w</attribute>
</item>
</section>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]