which is look at the right modifier when checking if a key event can invoke an accelerator. Also get the mnemonic modifier from GTK instead of hardcoding it, and don't check for it if mnemonics are disabled, which is the right thing to do on all platforms.
148 lines
4.1 KiB
C
148 lines
4.1 KiB
C
/* GIMP - The GNU Image Manipulation Program
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* gimpwindow.c
|
|
*
|
|
* This program 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "widgets-types.h"
|
|
|
|
#include "display/display-types.h"
|
|
#include "display/gimpcanvas.h"
|
|
|
|
#include "gimpwindow.h"
|
|
|
|
#include "gimp-log.h"
|
|
|
|
|
|
static gboolean gimp_window_key_press_event (GtkWidget *widget,
|
|
GdkEventKey *kevent);
|
|
|
|
G_DEFINE_TYPE (GimpWindow, gimp_window, GTK_TYPE_WINDOW)
|
|
|
|
|
|
static void
|
|
gimp_window_class_init (GimpWindowClass *klass)
|
|
{
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
|
|
widget_class->key_press_event = gimp_window_key_press_event;
|
|
}
|
|
|
|
static void
|
|
gimp_window_init (GimpWindow *window)
|
|
{
|
|
}
|
|
|
|
static gboolean
|
|
gimp_window_key_press_event (GtkWidget *widget,
|
|
GdkEventKey *event)
|
|
{
|
|
GtkWindow *window = GTK_WINDOW (widget);
|
|
GtkWidget *focus = gtk_window_get_focus (window);
|
|
GdkDisplay *display = gtk_widget_get_display (widget);
|
|
GdkModifierType state = event->state;
|
|
GdkModifierType accel_mods;
|
|
gboolean enable_mnemonics;
|
|
gboolean handled = FALSE;
|
|
|
|
/* we're overriding the GtkWindow implementation here to give
|
|
* the focus widget precedence over unmodified accelerators
|
|
* before the accelerator activation scheme.
|
|
*/
|
|
|
|
/* text widgets get all key events first */
|
|
if (GTK_IS_EDITABLE (focus) ||
|
|
GTK_IS_TEXT_VIEW (focus) ||
|
|
GIMP_IS_CANVAS (focus))
|
|
{
|
|
handled = gtk_window_propagate_key_event (window, event);
|
|
|
|
if (handled)
|
|
GIMP_LOG (KEY_EVENTS,
|
|
"handled by gtk_window_propagate_key_event(text_widget)");
|
|
}
|
|
|
|
/* we process raw key events here, and they contain only real
|
|
* modifiers; call the mapping function in order to get virtual
|
|
* modifiers added (e.g. META) in case the accel modifier is virtual
|
|
*/
|
|
gdk_keymap_add_virtual_modifiers (gdk_keymap_get_for_display (display),
|
|
&state);
|
|
|
|
/* FIXME: get this from GTK API */
|
|
#ifndef GDK_WINDOWING_QUARTZ
|
|
accel_mods = GDK_CONTROL_MASK;
|
|
#else
|
|
accel_mods = GDK_META_MASK;
|
|
#endif
|
|
|
|
g_object_get (gtk_widget_get_settings (widget),
|
|
"gtk-enable-mnemonics", &enable_mnemonics,
|
|
NULL);
|
|
|
|
if (enable_mnemonics)
|
|
accel_mods |= gtk_window_get_mnemonic_modifier (window);
|
|
|
|
/* invoke modified accelerators */
|
|
if (! handled && state & accel_mods)
|
|
{
|
|
handled = gtk_window_activate_key (window, event);
|
|
|
|
if (handled)
|
|
GIMP_LOG (KEY_EVENTS,
|
|
"handled by gtk_window_activate_key(modified)");
|
|
}
|
|
|
|
/* invoke focus widget handlers */
|
|
if (! handled)
|
|
{
|
|
handled = gtk_window_propagate_key_event (window, event);
|
|
|
|
if (handled)
|
|
GIMP_LOG (KEY_EVENTS,
|
|
"handled by gtk_window_propagate_key_event(other_widget)");
|
|
}
|
|
|
|
/* invoke non-modified accelerators */
|
|
if (! handled && ! (state & accel_mods))
|
|
{
|
|
handled = gtk_window_activate_key (window, event);
|
|
|
|
if (handled)
|
|
GIMP_LOG (KEY_EVENTS,
|
|
"handled by gtk_window_activate_key(unmodified)");
|
|
}
|
|
|
|
/* chain up, bypassing gtk_window_key_press(), to invoke binding set */
|
|
if (! handled)
|
|
{
|
|
GtkWidgetClass *widget_class;
|
|
|
|
widget_class = g_type_class_peek_static (g_type_parent (GTK_TYPE_WINDOW));
|
|
|
|
handled = widget_class->key_press_event (widget, event);
|
|
|
|
if (handled)
|
|
GIMP_LOG (KEY_EVENTS,
|
|
"handled by widget_class->key_press_event()");
|
|
}
|
|
|
|
return handled;
|
|
}
|