From 02baf0b35e9fd593a89d252e40aae6bfab7af3b9 Mon Sep 17 00:00:00 2001 From: speare Date: Mon, 16 Mar 2009 21:43:07 +0000 Subject: [PATCH] response to bug #167290; add another undoc option to support alt-key tracking for osx x11 and other gdk systems that cannot sense alt key properly --- src/inkscape-private.h | 3 +++ src/inkscape.cpp | 18 +++++++++++++-- src/main.cpp | 52 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/inkscape-private.h b/src/inkscape-private.h index 676fff8a4..cb7f98729 100644 --- a/src/inkscape-private.h +++ b/src/inkscape-private.h @@ -32,6 +32,9 @@ void inkscape_unref (void); guint inkscape_mapalt(); void inkscape_mapalt(guint); +guint inkscape_trackalt(); +void inkscape_trackalt(guint); + /* * These are meant solely for desktop, document etc. implementations */ diff --git a/src/inkscape.cpp b/src/inkscape.cpp index b497367cc..25b3cc5a9 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -110,6 +110,7 @@ struct Inkscape::Application { gboolean use_gui; // may want to consider a virtual function // for overriding things like the warning dlg's guint mapalt; + guint trackalt; }; struct Inkscape::ApplicationClass { @@ -462,7 +463,8 @@ inkscape_init (SPObject * object) inkscape->menus = sp_repr_read_mem (_(menus_skeleton), MENUS_SKELETON_SIZE, NULL); inkscape->desktops = NULL; inkscape->dialogs_toggle = TRUE; - inkscape->mapalt=GDK_MOD1_MASK; + inkscape->mapalt = GDK_MOD1_MASK; + inkscape->trackalt = FALSE; } static void @@ -520,6 +522,17 @@ void inkscape_mapalt(guint maskvalue) } } +guint +inkscape_trackalt() { + return inkscape->trackalt; +} + +void inkscape_trackalt(guint trackvalue) +{ + inkscape->trackalt = trackvalue; +} + + static void inkscape_activate_desktop_private (Inkscape::Application */*inkscape*/, SPDesktop *desktop) { @@ -775,9 +788,10 @@ inkscape_application_init (const gchar *argv0, gboolean use_gui) } /* Check for global remapping of Alt key */ - if(use_gui) + if (use_gui) { inkscape_mapalt(guint(prefs->getInt("/options/mapalt/value", 0))); + inkscape_trackalt(guint(prefs->getInt("/options/trackalt/value", 0))); } /* Initialize the extensions */ diff --git a/src/main.cpp b/src/main.cpp index 991a95add..b5ace5405 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -801,7 +801,7 @@ int sp_common_main( int argc, char const **argv, GSList **flDest ) static void snooper(GdkEvent *event, gpointer /*data*/) { - if(inkscape_mapalt()) /* returns the map of the keyboard modifier to map to Alt, zero if no mapping */ + if (inkscape_mapalt()) /* returns the map of the keyboard modifier to map to Alt, zero if no mapping */ { GdkModifierType mapping=(GdkModifierType)inkscape_mapalt(); switch (event->type) { @@ -824,6 +824,56 @@ snooper(GdkEvent *event, gpointer /*data*/) { break; } } + + if (inkscape_trackalt()) { + // MacOS X with X11 has some problem with the default + // xmodmapping. A ~/.xmodmap solution does not work reliably due + // to the way we package our executable in a .app that can launch + // X11 or use an already-running X11. The same problem has been + // reported on Linux but there is no .app/X11 to get in the way + // of ~/.xmodmap fixes. So we make this a preference. + // + // For some reason, Gdk senses changes in Alt (Mod1) state for + // many message types, but not for keystrokes! So this ugly hack + // tracks what the state of Alt-pressing is, and ensures + // GDK_MOD1_MASK is in the event->key.state as appropriate. + // + static gboolean altL_pressed = FALSE; + static gboolean altR_pressed = FALSE; + static gboolean alt_pressed = FALSE; + guint get_group0_keyval(GdkEventKey* event); + guint keyval = 0; + switch (event->type) { + case GDK_MOTION_NOTIFY: + alt_pressed = TRUE && (event->motion.state & GDK_MOD1_MASK); + break; + case GDK_BUTTON_PRESS: + alt_pressed = TRUE && (event->button.state & GDK_MOD1_MASK); + break; + case GDK_KEY_PRESS: + keyval = get_group0_keyval(&event->key); + if (keyval == GDK_Alt_L) altL_pressed = TRUE; + if (keyval == GDK_Alt_R) altR_pressed = TRUE; + alt_pressed = alt_pressed || altL_pressed || altR_pressed; + alt_pressed = alt_pressed || (event->button.state & GDK_MOD1_MASK); + if (alt_pressed) + event->key.state |= GDK_MOD1_MASK; + else + event->key.state &= ~GDK_MOD1_MASK; + break; + case GDK_KEY_RELEASE: + keyval = get_group0_keyval(&event->key); + if (keyval == GDK_Alt_L) altL_pressed = FALSE; + if (keyval == GDK_Alt_R) altR_pressed = FALSE; + if (!altL_pressed && !altR_pressed) + alt_pressed = FALSE; + break; + default: + break; + } + //printf("alt_pressed: %s\n", alt_pressed? "+" : "-"); + } + gtk_main_do_event (event); } -- 2.30.2