![](https://secure.gravatar.com/avatar/46b7fe9c91059c866acc6c82da614e1f.jpg?s=120&d=mm&r=g)
This is a resend as the original has not shown up in the list as far as I can see. Apologies if it's dup'ed.
The attached patch allows the global mapping of any single modifier key to Alt. The default behaviour is to leave Alt as the Alt key.
It adds an option to the preferences file: <group id="options"> <group id="mapalt" value="1" />
Where 'value' can be from 2 to 5 depending on which modifier you want to use instead of Alt (or, 1 to go back to Alt). My machine uses mod3 as the Meta key so I put '3' in here. I have not been able to find a definitive list of which mod values go with Meta/super/hyper etc. so I've left it up to the user to find out which one their machine uses for the key they want to use.
The method I had intended to use was a nightmare due to the separation of the various tool contexts, so I dropped it in favour of a simple event handler (called 'snooper', defined in main.cpp) which steals all the events coming from GDK, remapps the state of the modifier keys if needed and then passes them back on to be handled by gdk_main_do_event. This method is central and requires no changes to the various tool context sources and future developers of tools can continue to use GDK_MOD1_MASK as they do now. Likewise, the user sees all keystrokes and mouse button combinations that use Alt as now using Meta (or whatever they've picked); there's no confusion over keyboard shortcuts still using Alt while the mouse uses Meta or anything like that. It is possible to modify the event snooper to only map mouse combinations but I think a consistant, global mapping is less confusing.
The mapping and snooping are not activated unless the GUI is running.
As I said before, I'm no C++ programmer - this constitutes my second ever venture into C++ after "Hello World" - and there may be better ways to arrange this code, but I think the centralised event snooper is the only way to do it and perhaps having one will be useful for other things in the future. In any case, the maintainance issues of any other approach probably makes it "this way or not at all". If the patch is acceptable, I'd be happy to do up the user documentation.
One thing: I can't work out where the default preferences file is in the source tree, ie, the version that gets installed on a virgin machine. So I've not put the option into it, obviously. But the hardcoded default is to use Alt.
I've been enjoying "selecting under" and node sculpting today, so if nothing else, I'm happy!
Thomas Worthington
The patch follows. If this is screwed up it can be downloaded as a text file from
http://www.tww.cx/downloads/mapalt.diff
Index: src/inkscape-private.h =================================================================== --- src/inkscape-private.h (revision 15759) +++ src/inkscape-private.h (working copy) @@ -29,6 +29,9 @@ void inkscape_ref (void); void inkscape_unref (void);
+guint inkscape_mapalt(); +void inkscape_mapalt(guint); + /* * These are meant solely for desktop, document etc. implementations */ Index: src/inkscape.cpp =================================================================== --- src/inkscape.cpp (revision 15759) +++ src/inkscape.cpp (working copy) @@ -117,6 +117,7 @@ gboolean dialogs_toggle; gboolean use_gui; // may want to consider a virtual function // for overriding things like the warning dlg's + guint mapalt; };
struct Inkscape::ApplicationClass { @@ -302,9 +303,10 @@ inkscape->desktops = NULL;
inkscape->dialogs_toggle = TRUE; + + inkscape->mapalt=GDK_MOD1_MASK; }
- static void inkscape_dispose (GObject *object) { @@ -342,13 +344,28 @@
void -inkscape_unref (void) -{ +inkscape_unref (void) { if (inkscape) g_object_unref (G_OBJECT (inkscape)); }
+/* returns the mask of the keyboard modifier to map to Alt, zero if no mapping */ +/* Needs to be a guint because gdktypes.h does not define a 'no-modifier' value */ +guint +inkscape_mapalt() { + return inkscape->mapalt; +}
+/* Sets the keyboard modifer to map to Alt. Zero switches off mapping, as does '1', which is the default */ +void inkscape_mapalt(guint maskvalue) +{ + if(maskvalue<2 || maskvalue> 5 ){ /* MOD5 is the highest defined in gdktypes.h */ + inkscape->mapalt=0; + }else{ + inkscape->mapalt=(GDK_MOD1_MASK << (maskvalue-1)); + } +} + static void inkscape_activate_desktop_private (Inkscape::Application *inkscape, SPDesktop *desktop) { @@ -594,6 +611,12 @@ Inkscape::UI::Dialogs::DebugDialog::getInstance()->captureLogMessages(); }
+ /* Check for global remapping of Alt key */ + if(use_gui) + { + inkscape_mapalt(guint(prefs_get_int_attribute("options.mapalt","value",0))); + } + /* Initialize the extensions */ Inkscape::Extension::init();
Index: src/preferences-skeleton.h =================================================================== --- src/preferences-skeleton.h (revision 15759) +++ src/preferences-skeleton.h (working copy) @@ -175,6 +175,7 @@ " </group>\n" "\n" " <group id="options">\n" +" <group id="mapalt" value="1" />" " <group id="useextinput" value="1" />" " <group id="nudgedistance" value="2"/>\n" " <group id="rotationsnapsperpi" value="12"/>\n" Index: src/main.cpp =================================================================== --- src/main.cpp (revision 15759) +++ src/main.cpp (working copy) @@ -620,6 +620,38 @@ return 0; }
+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 */ + { + GdkModifierType mapping=(GdkModifierType)inkscape_mapalt(); + switch (event->type) { + case GDK_MOTION_NOTIFY: + if(event->motion.state & mapping) { + event->motion.state|=GDK_MOD1_MASK; + } + break; + case GDK_BUTTON_PRESS: + if(event->button.state & mapping) { + event->button.state|=GDK_MOD1_MASK; + } + break; + case GDK_KEY_PRESS: + if(event->key.state & mapping) { + event->key.state|=GDK_MOD1_MASK; + } + break; + default: + break; + } + } + gtk_main_do_event (event); +} + +void snoopunroll(gpointer data) +{ +} + int sp_main_gui(int argc, char const **argv) { @@ -631,6 +663,8 @@
inkscape_gtk_stock_init();
+ gdk_event_handler_set ((GdkEventFunc)snooper, 0,&snoopunroll); + Inkscape::Debug::log_display_config();
/* Set default icon */