diff --git a/.gitignore b/.gitignore
index b835906..27d8e65 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@ lib64/
parts/
sdist/
var/
+.idea/
*.egg-info/
.installed.cfg
*.egg
diff --git a/dragonfly/actions/_generate_typeables.py b/dragonfly/actions/_generate_typeables.py
index 8ee9c41..f62ceed 100644
--- a/dragonfly/actions/_generate_typeables.py
+++ b/dragonfly/actions/_generate_typeables.py
@@ -3,18 +3,18 @@
# (c) Copyright 2007, 2008 by Christo Butcher
# Licensed under the LGPL.
#
-# Dragonfly is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
+# Dragonfly is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# Dragonfly 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
+# Dragonfly 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
# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU Lesser General Public
-# License along with Dragonfly. If not, see
+# You should have received a copy of the GNU Lesser General Public
+# License along with Dragonfly. If not, see
# .
#
@@ -135,7 +135,9 @@
("Modifier keys", [
(vkey, "win32con.VK_SHIFT", "shift"),
(vkey, "win32con.VK_CONTROL", "control ctrl"),
- (vkey, "win32con.VK_MENU", "alt")]),
+ (vkey, "win32con.VK_MENU", "alt"),
+ (vkey, "win32con.VK_RMENU", "altgr"),
+ (vkey, "win32con.VK_RCONTROL", "rcontrol")]),
("Special keys", [
(vkey, "win32con.VK_ESCAPE", "escape"),
(vkey, "win32con.VK_INSERT", "insert"),
diff --git a/dragonfly/actions/action_key.py b/dragonfly/actions/action_key.py
index 3911525..df006ff 100644
--- a/dragonfly/actions/action_key.py
+++ b/dragonfly/actions/action_key.py
@@ -210,6 +210,8 @@ class Key(DynStrActionBase):
_modifier_prefix_delimiter = "-"
_modifier_prefix_characters = {
'a': typeables["alt"],
+ 'g': typeables["altgr"],
+ 'r': typeables["rcontrol"],
'c': typeables["control"],
's': typeables["shift"],
'w': typeables["win"],
diff --git a/dragonfly/actions/keyboard.py b/dragonfly/actions/keyboard.py
index 2556bd7..fcdc3ba 100644
--- a/dragonfly/actions/keyboard.py
+++ b/dragonfly/actions/keyboard.py
@@ -3,18 +3,18 @@
# (c) Copyright 2007, 2008 by Christo Butcher
# Licensed under the LGPL.
#
-# Dragonfly is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
+# Dragonfly is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# Dragonfly 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
+# Dragonfly 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
# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU Lesser General Public
-# License along with Dragonfly. If not, see
+# You should have received a copy of the GNU Lesser General Public
+# License along with Dragonfly. If not, see
# .
#
@@ -76,6 +76,8 @@ class Keyboard(object):
shift_code = win32con.VK_SHIFT
ctrl_code = win32con.VK_CONTROL
alt_code = win32con.VK_MENU
+ ralt_code = win32con.VK_RMENU
+ rctrl_code = win32con.VK_RCONTROL
@classmethod
def send_keyboard_events(cls, events):
@@ -108,32 +110,28 @@ def send_keyboard_events(cls, events):
@classmethod
def xget_virtual_keycode(cls, char):
- if isinstance(char, str):
- code = windll.user32.VkKeyScanA(c_char(char))
- else:
- code = windll.user32.VkKeyScanW(c_wchar(char))
- if code == -1:
- raise ValueError("Unknown char: %r" % char)
-
+ code, modifiers = cls.get_keycode_and_modifiers(char)
# Construct a list of the virtual key code and modifiers.
- codes = [code & 0x00ff]
- if code & 0x0100: codes.append(cls.shift_code)
- elif code & 0x0200: codes.append(cls.ctrl_code)
- elif code & 0x0400: codes.append(cls.alt_code)
+ codes = [code]
+ codes.extends(modifiers)
return codes
@classmethod
def get_keycode_and_modifiers(cls, char):
+ user32 = windll.user32
+ w = user32.GetForegroundWindow()
+ tid = user32.GetWindowThreadProcessId(w, 0)
if isinstance(char, str):
- code = windll.user32.VkKeyScanA(c_char(char))
+ code = windll.user32.VkKeyScanExA(c_char(char), user32.GetKeyboardLayout(tid))
else:
- code = windll.user32.VkKeyScanW(c_wchar(char))
+ code = windll.user32.VkKeyScanExW(c_wchar(char), user32.GetKeyboardLayout(tid))
if code == -1:
raise ValueError("Unknown char: %r" % char)
# Construct a list of the virtual key code and modifiers.
modifiers = []
if code & 0x0100: modifiers.append(cls.shift_code)
+ elif code & 0x0600: modifiers = [cls.ralt_code]
elif code & 0x0200: modifiers.append(cls.ctrl_code)
elif code & 0x0400: modifiers.append(cls.alt_code)
code &= 0x00ff
diff --git a/dragonfly/actions/typeables.py b/dragonfly/actions/typeables.py
index d8612ef..9093e18 100644
--- a/dragonfly/actions/typeables.py
+++ b/dragonfly/actions/typeables.py
@@ -3,18 +3,18 @@
# (c) Copyright 2007, 2008 by Christo Butcher
# Licensed under the LGPL.
#
-# Dragonfly is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
+# Dragonfly is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# Dragonfly 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
+# Dragonfly 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
# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU Lesser General Public
-# License along with Dragonfly. If not, see
+# You should have received a copy of the GNU Lesser General Public
+# License along with Dragonfly. If not, see
# .
#
@@ -227,6 +227,8 @@
"control": Typeable(code=win32con.VK_CONTROL, name='control'),
"ctrl": Typeable(code=win32con.VK_CONTROL, name='ctrl'),
"alt": Typeable(code=win32con.VK_MENU, name='alt'),
+ "altgr": Typeable(code=win32con.VK_RMENU, name='altgr'),
+ "rcontrol": Typeable(code=win32con.VK_RCONTROL, name='rcontrol'),
# Special keys
"escape": Typeable(code=win32con.VK_ESCAPE, name='escape'),
@@ -314,4 +316,195 @@
"playpause": Typeable(code=win32con.VK_MEDIA_PLAY_PAUSE, name='playpause'),
"browserback": Typeable(code=win32con.VK_BROWSER_BACK, name='browserback'),
"browserforward": Typeable(code=win32con.VK_BROWSER_FORWARD, name='browserforward'),
+
+ # list of virtual keys codes : https://msdn.microsoft.com/fr-fr/library/windows/desktop/dd375731(v=vs.85).aspx
+ "vk01": Typeable(code=0x01, name='vk01'),
+ "vk02": Typeable(code=0x02, name='vk02'),
+ "vk03": Typeable(code=0x03, name='vk03'),
+ "vk04": Typeable(code=0x04, name='vk04'),
+ "vk05": Typeable(code=0x05, name='vk05'),
+ "vk06": Typeable(code=0x06, name='vk06'),
+ "vk07": Typeable(code=0x07, name='vk07'),
+ "vk08": Typeable(code=0x08, name='vk08'),
+ "vk09": Typeable(code=0x09, name='vk09'),
+ "vk0A": Typeable(code=0x0A, name='vk0A'),
+ "vk0C": Typeable(code=0x0C, name='vk0C'),
+ "vk0D": Typeable(code=0x0D, name='vk0D'),
+ "vk0E": Typeable(code=0x0E, name='vk0E'),
+ "vk10": Typeable(code=0x10, name='vk10'),
+ "vk11": Typeable(code=0x11, name='vk11'),
+ "vk12": Typeable(code=0x12, name='vk12'),
+ "vk13": Typeable(code=0x13, name='vk13'),
+ "vk14": Typeable(code=0x14, name='vk14'),
+ "vk15": Typeable(code=0x15, name='vk15'),
+ "vk16": Typeable(code=0x16, name='vk16'),
+ "vk17": Typeable(code=0x17, name='vk17'),
+ "vk18": Typeable(code=0x18, name='vk18'),
+ "vk19": Typeable(code=0x19, name='vk19'),
+ "vk1A": Typeable(code=0x1A, name='vk1A'),
+ "vk1B": Typeable(code=0x1B, name='vk1B'),
+ "vk1C": Typeable(code=0x1C, name='vk1C'),
+ "vk1D": Typeable(code=0x1D, name='vk1D'),
+ "vk1E": Typeable(code=0x1E, name='vk1E'),
+ "vk1F": Typeable(code=0x1F, name='vk1F'),
+ "vk20": Typeable(code=0x20, name='vk20'),
+ "vk21": Typeable(code=0x21, name='vk21'),
+ "vk22": Typeable(code=0x22, name='vk22'),
+ "vk23": Typeable(code=0x23, name='vk23'),
+ "vk24": Typeable(code=0x24, name='vk24'),
+ "vk25": Typeable(code=0x25, name='vk25'),
+ "vk26": Typeable(code=0x26, name='vk26'),
+ "vk27": Typeable(code=0x27, name='vk27'),
+ "vk28": Typeable(code=0x28, name='vk28'),
+ "vk29": Typeable(code=0x29, name='vk29'),
+ "vk2A": Typeable(code=0x2A, name='vk2A'),
+ "vk2B": Typeable(code=0x2B, name='vk2B'),
+ "vk2C": Typeable(code=0x2C, name='vk2C'),
+ "vk2D": Typeable(code=0x2D, name='vk2D'),
+ "vk2E": Typeable(code=0x2E, name='vk2E'),
+ "vk2F": Typeable(code=0x2F, name='vk2F'),
+ "vk30": Typeable(code=0x30, name='vk30'),
+ "vk31": Typeable(code=0x31, name='vk31'),
+ "vk32": Typeable(code=0x32, name='vk32'),
+ "vk33": Typeable(code=0x33, name='vk33'),
+ "vk34": Typeable(code=0x34, name='vk34'),
+ "vk35": Typeable(code=0x35, name='vk35'),
+ "vk36": Typeable(code=0x36, name='vk36'),
+ "vk37": Typeable(code=0x37, name='vk37'),
+ "vk38": Typeable(code=0x38, name='vk38'),
+ "vk39": Typeable(code=0x39, name='vk39'),
+ "vk3A": Typeable(code=0x3A, name='vk3A'),
+ "vk41": Typeable(code=0x41, name='vk41'),
+ "vk42": Typeable(code=0x42, name='vk42'),
+ "vk43": Typeable(code=0x43, name='vk43'),
+ "vk44": Typeable(code=0x44, name='vk44'),
+ "vk45": Typeable(code=0x45, name='vk45'),
+ "vk46": Typeable(code=0x46, name='vk46'),
+ "vk47": Typeable(code=0x47, name='vk47'),
+ "vk48": Typeable(code=0x48, name='vk48'),
+ "vk49": Typeable(code=0x49, name='vk49'),
+ "vk4A": Typeable(code=0x4A, name='vk4A'),
+ "vk4B": Typeable(code=0x4B, name='vk4B'),
+ "vk4C": Typeable(code=0x4C, name='vk4C'),
+ "vk4D": Typeable(code=0x4D, name='vk4D'),
+ "vk4E": Typeable(code=0x4E, name='vk4E'),
+ "vk4F": Typeable(code=0x4F, name='vk4F'),
+ "vk50": Typeable(code=0x50, name='vk50'),
+ "vk51": Typeable(code=0x51, name='vk51'),
+ "vk52": Typeable(code=0x52, name='vk52'),
+ "vk53": Typeable(code=0x53, name='vk53'),
+ "vk54": Typeable(code=0x54, name='vk54'),
+ "vk55": Typeable(code=0x55, name='vk55'),
+ "vk56": Typeable(code=0x56, name='vk56'),
+ "vk57": Typeable(code=0x57, name='vk57'),
+ "vk58": Typeable(code=0x58, name='vk58'),
+ "vk59": Typeable(code=0x59, name='vk59'),
+ "vk5A": Typeable(code=0x5A, name='vk5A'),
+ "vk5B": Typeable(code=0x5B, name='vk5B'),
+ "vk5C": Typeable(code=0x5C, name='vk5C'),
+ "vk5D": Typeable(code=0x5D, name='vk5D'),
+ "vk5E": Typeable(code=0x5E, name='vk5E'),
+ "vk5F": Typeable(code=0x5F, name='vk5F'),
+ "vk60": Typeable(code=0x60, name='vk60'),
+ "vk61": Typeable(code=0x61, name='vk61'),
+ "vk62": Typeable(code=0x62, name='vk62'),
+ "vk63": Typeable(code=0x63, name='vk63'),
+ "vk64": Typeable(code=0x64, name='vk64'),
+ "vk65": Typeable(code=0x65, name='vk65'),
+ "vk66": Typeable(code=0x66, name='vk66'),
+ "vk67": Typeable(code=0x67, name='vk67'),
+ "vk68": Typeable(code=0x68, name='vk68'),
+ "vk69": Typeable(code=0x69, name='vk69'),
+ "vk6A": Typeable(code=0x6A, name='vk6A'),
+ "vk6B": Typeable(code=0x6B, name='vk6B'),
+ "vk6C": Typeable(code=0x6C, name='vk6C'),
+ "vk6D": Typeable(code=0x6D, name='vk6D'),
+ "vk6E": Typeable(code=0x6E, name='vk6E'),
+ "vk6F": Typeable(code=0x6F, name='vk6F'),
+ "vk70": Typeable(code=0x70, name='vk70'),
+ "vk71": Typeable(code=0x71, name='vk71'),
+ "vk72": Typeable(code=0x72, name='vk72'),
+ "vk73": Typeable(code=0x73, name='vk73'),
+ "vk74": Typeable(code=0x74, name='vk74'),
+ "vk75": Typeable(code=0x75, name='vk75'),
+ "vk76": Typeable(code=0x76, name='vk76'),
+ "vk77": Typeable(code=0x77, name='vk77'),
+ "vk78": Typeable(code=0x78, name='vk78'),
+ "vk79": Typeable(code=0x79, name='vk79'),
+ "vk7A": Typeable(code=0x7A, name='vk7A'),
+ "vk7B": Typeable(code=0x7B, name='vk7B'),
+ "vk7C": Typeable(code=0x7C, name='vk7C'),
+ "vk7D": Typeable(code=0x7D, name='vk7D'),
+ "vk7E": Typeable(code=0x7E, name='vk7E'),
+ "vk7F": Typeable(code=0x7F, name='vk7F'),
+ "vk80": Typeable(code=0x80, name='vk80'),
+ "vk81": Typeable(code=0x81, name='vk81'),
+ "vk82": Typeable(code=0x82, name='vk82'),
+ "vk83": Typeable(code=0x83, name='vk83'),
+ "vk84": Typeable(code=0x84, name='vk84'),
+ "vk85": Typeable(code=0x85, name='vk85'),
+ "vk86": Typeable(code=0x86, name='vk86'),
+ "vk87": Typeable(code=0x87, name='vk87'),
+ "vk88": Typeable(code=0x88, name='vk88'),
+ "vk90": Typeable(code=0x90, name='vk90'),
+ "vk91": Typeable(code=0x91, name='vk91'),
+ "vk92": Typeable(code=0x92, name='vk92'),
+ "vk97": Typeable(code=0x97, name='vk97'),
+ "vkA0": Typeable(code=0xA0, name='vkA0'),
+ "vkA1": Typeable(code=0xA1, name='vkA1'),
+ "vkA2": Typeable(code=0xA2, name='vkA2'),
+ "vkA3": Typeable(code=0xA3, name='vkA3'),
+ "vkA4": Typeable(code=0xA4, name='vkA4'),
+ "vkA5": Typeable(code=0xA5, name='vkA5'),
+ "vkA6": Typeable(code=0xA6, name='vkA6'),
+ "vkA7": Typeable(code=0xA7, name='vkA7'),
+ "vkA8": Typeable(code=0xA8, name='vkA8'),
+ "vkA9": Typeable(code=0xA9, name='vkA9'),
+ "vkAA": Typeable(code=0xAA, name='vkAA'),
+ "vkAB": Typeable(code=0xAB, name='vkAB'),
+ "vkAC": Typeable(code=0xAC, name='vkAC'),
+ "vkAD": Typeable(code=0xAD, name='vkAD'),
+ "vkAE": Typeable(code=0xAE, name='vkAE'),
+ "vkAF": Typeable(code=0xAF, name='vkAF'),
+ "vkB0": Typeable(code=0xB0, name='vkB0'),
+ "vkB1": Typeable(code=0xB1, name='vkB1'),
+ "vkB2": Typeable(code=0xB2, name='vkB2'),
+ "vkB3": Typeable(code=0xB3, name='vkB3'),
+ "vkB4": Typeable(code=0xB4, name='vkB4'),
+ "vkB5": Typeable(code=0xB5, name='vkB5'),
+ "vkB6": Typeable(code=0xB6, name='vkB6'),
+ "vkB7": Typeable(code=0xB7, name='vkB7'),
+ "vkB8": Typeable(code=0xB8, name='vkB8'),
+ "vkBA": Typeable(code=0xBA, name='vkBA'),
+ "vkBB": Typeable(code=0xBB, name='vkBB'),
+ "vkBC": Typeable(code=0xBC, name='vkBC'),
+ "vkBD": Typeable(code=0xBD, name='vkBD'),
+ "vkBE": Typeable(code=0xBE, name='vkBE'),
+ "vkBF": Typeable(code=0xBF, name='vkBF'),
+ "vkC0": Typeable(code=0xC0, name='vkC0'),
+ "vkC1": Typeable(code=0xC1, name='vkC1'),
+ "vkD8": Typeable(code=0xD8, name='vkD8'),
+ "vkDB": Typeable(code=0xDB, name='vkDB'),
+ "vkDC": Typeable(code=0xDC, name='vkDC'),
+ "vkDD": Typeable(code=0xDD, name='vkDD'),
+ "vkDE": Typeable(code=0xDE, name='vkDE'),
+ "vkDF": Typeable(code=0xDF, name='vkDF'),
+ "vkE0": Typeable(code=0xE0, name='vkE0'),
+ "vkE1": Typeable(code=0xE1, name='vkE1'),
+ "vkE2": Typeable(code=0xE2, name='vkE2'),
+ "vkE3": Typeable(code=0xE3, name='vkE3'),
+ "vkE5": Typeable(code=0xE5, name='vkE5'),
+ "vkE6": Typeable(code=0xE6, name='vkE6'),
+ "vkE7": Typeable(code=0xE7, name='vkE7'),
+ "vkE8": Typeable(code=0xE8, name='vkE8'),
+ "vkE9": Typeable(code=0xE9, name='vkE9'),
+ "vkF6": Typeable(code=0xF6, name='vkF6'),
+ "vkF7": Typeable(code=0xF7, name='vkF7'),
+ "vkF8": Typeable(code=0xF8, name='vkF8'),
+ "vkF9": Typeable(code=0xF9, name='vkF9'),
+ "vkFA": Typeable(code=0xFA, name='vkFA'),
+ "vkFB": Typeable(code=0xFB, name='vkFB'),
+ "vkFC": Typeable(code=0xFC, name='vkFC'),
+ "vkFD": Typeable(code=0xFD, name='vkFD'),
+ "vkFE": Typeable(code=0xFE, name='vkFE'),
}