Commit beaba95f authored by Phillip Wood's avatar Phillip Wood Committed by Matthias Clasen

Window: Focus custom titlebar with F10

As discussed on desktop-devel-list [1], "There should be an intuitive,
consistent, immediate way to jump to the widgets that live in the
header bar." F10 has been suggested for this as it is already used to
active menubars.

F10 will focus the custom titlebar widget if the window has one and it
isn't already focused. If the titlebar widget doesn't exist or is
already focused then F10 focuses the menubar if there is one.

[1] https://mail.gnome.org/archives/desktop-devel-list/2014-February/msg00176.html

https://bugzilla.gnome.org/show_bug.cgi?id=725141
parent 0da3fc8b
......@@ -656,8 +656,8 @@ get_menu_bars (GtkWindow *window)
return g_object_get_data (G_OBJECT (window), "gtk-menu-bar-list");
}
static GList *
get_viewable_menu_bars (GtkWindow *window)
GList *
_gtk_menu_bar_get_viewable_menu_bars (GtkWindow *window)
{
GList *menu_bars;
GList *viewable_menu_bars = NULL;
......@@ -691,76 +691,12 @@ set_menu_bars (GtkWindow *window,
g_object_set_data (G_OBJECT (window), I_("gtk-menu-bar-list"), menubars);
}
static gboolean
window_key_press_handler (GtkWidget *widget,
GdkEventKey *event,
gpointer data)
{
gchar *accel = NULL;
gboolean retval = FALSE;
g_object_get (gtk_widget_get_settings (widget),
"gtk-menu-bar-accel", &accel,
NULL);
if (accel && *accel)
{
guint keyval = 0;
GdkModifierType mods = 0;
gtk_accelerator_parse (accel, &keyval, &mods);
if (keyval == 0)
g_warning ("Failed to parse menu bar accelerator '%s'\n", accel);
/* FIXME this is wrong, needs to be in the global accel resolution
* thing, to properly consider i18n etc., but that probably requires
* AccelGroup changes etc.
*/
if (event->keyval == keyval &&
((event->state & gtk_accelerator_get_default_mod_mask ()) ==
(mods & gtk_accelerator_get_default_mod_mask ())))
{
GList *tmp_menubars = get_viewable_menu_bars (GTK_WINDOW (widget));
GList *menubars;
menubars = _gtk_container_focus_sort (GTK_CONTAINER (widget), tmp_menubars,
GTK_DIR_TAB_FORWARD, NULL);
g_list_free (tmp_menubars);
if (menubars)
{
GtkMenuShell *menu_shell = GTK_MENU_SHELL (menubars->data);
_gtk_menu_shell_set_keyboard_mode (menu_shell, TRUE);
gtk_menu_shell_select_first (menu_shell, FALSE);
g_list_free (menubars);
retval = TRUE;
}
}
}
g_free (accel);
return retval;
}
static void
add_to_window (GtkWindow *window,
GtkMenuBar *menubar)
{
GList *menubars = get_menu_bars (window);
if (!menubars)
{
g_signal_connect (window,
"key-press-event",
G_CALLBACK (window_key_press_handler),
NULL);
}
set_menu_bars (window, g_list_prepend (menubars, menubar));
}
......@@ -771,14 +707,6 @@ remove_from_window (GtkWindow *window,
GList *menubars = get_menu_bars (window);
menubars = g_list_remove (menubars, menubar);
if (!menubars)
{
g_signal_handlers_disconnect_by_func (window,
window_key_press_handler,
NULL);
}
set_menu_bars (window, menubars);
}
......@@ -816,7 +744,7 @@ _gtk_menu_bar_cycle_focus (GtkMenuBar *menubar,
if (gtk_widget_is_toplevel (toplevel))
{
GList *tmp_menubars = get_viewable_menu_bars (GTK_WINDOW (toplevel));
GList *tmp_menubars = _gtk_menu_bar_get_viewable_menu_bars (GTK_WINDOW (toplevel));
GList *menubars;
GList *current;
......
......@@ -88,6 +88,8 @@ void gtk_menu_bar_set_child_pack_direction (GtkMenuBar *menuba
/* Private functions */
void _gtk_menu_bar_cycle_focus (GtkMenuBar *menubar,
GtkDirectionType dir);
GList* _gtk_menu_bar_get_viewable_menu_bars (GtkWindow *window);
G_END_DECLS
......
......@@ -42,6 +42,7 @@
#include "gtkmain.h"
#include "gtkmnemonichash.h"
#include "gtkmenubar.h"
#include "gtkmenushellprivate.h"
#include "gtkicontheme.h"
#include "gtkmarshalers.h"
#include "gtkplug.h"
......@@ -11552,6 +11553,71 @@ gtk_window_parse_geometry (GtkWindow *window,
return result != 0;
}
static gboolean
gtk_window_activate_menubar (GtkWindow *window,
GdkEventKey *event)
{
GtkWindowPrivate *priv = window->priv;
gchar *accel = NULL;
guint keyval = 0;
GdkModifierType mods = 0;
g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
"gtk-menu-bar-accel", &accel,
NULL);
if (accel == NULL || *accel == 0)
return FALSE;
gtk_accelerator_parse (accel, &keyval, &mods);
g_free (accel);
if (keyval == 0)
{
g_warning ("Failed to parse menu bar accelerator '%s'\n", accel);
return FALSE;
}
/* FIXME this is wrong, needs to be in the global accel resolution
* thing, to properly consider i18n etc., but that probably requires
* AccelGroup changes etc.
*/
if (event->keyval == keyval &&
((event->state & gtk_accelerator_get_default_mod_mask ()) ==
(mods & gtk_accelerator_get_default_mod_mask ())))
{
GList *tmp_menubars;
GList *menubars;
GtkMenuShell *menu_shell;
if (priv->title_box != NULL &&
!gtk_widget_is_ancestor (gtk_window_get_focus (window), priv->title_box) &&
gtk_widget_child_focus (priv->title_box, GTK_DIR_TAB_FORWARD))
return TRUE;
tmp_menubars = _gtk_menu_bar_get_viewable_menu_bars (window);
if (tmp_menubars == NULL)
return FALSE;
menubars = _gtk_container_focus_sort (GTK_CONTAINER (window), tmp_menubars,
GTK_DIR_TAB_FORWARD, NULL);
g_list_free (tmp_menubars);
if (menubars == NULL)
return FALSE;
menu_shell = GTK_MENU_SHELL (menubars->data);
_gtk_menu_shell_set_keyboard_mode (menu_shell, TRUE);
gtk_menu_shell_select_first (menu_shell, FALSE);
g_list_free (menubars);
return TRUE;
}
return FALSE;
}
static void
gtk_window_mnemonic_hash_foreach (guint keyval,
GSList *targets,
......@@ -11775,7 +11841,7 @@ gtk_window_activate_key (GtkWindow *window,
}
}
return FALSE;
return gtk_window_activate_menubar (window, event);
}
static void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment