WM: support the "Hyper" modifier key on Linux
Add support for a 5th modifier key called "hyper", this is a modifier supported on Wayland & X11 although other platforms could support an additional modifier too. Both GNOME and KDE can map CapsLock to Hyper. Other compositors can use the XKB_DEFAULT_OPTIONS environment variable. This allows users to have an additional modifier for their own use that doesn't conflict with other keys. Ref !136340
This commit is contained in:
@@ -187,6 +187,8 @@ typedef enum {
|
||||
GHOST_kModifierKeyRightControl,
|
||||
GHOST_kModifierKeyLeftOS,
|
||||
GHOST_kModifierKeyRightOS,
|
||||
GHOST_kModifierKeyLeftHyper,
|
||||
GHOST_kModifierKeyRightHyper,
|
||||
GHOST_kModifierKeyNum
|
||||
} GHOST_TModifierKey;
|
||||
|
||||
@@ -444,7 +446,10 @@ typedef enum {
|
||||
GHOST_kKeyRightAlt,
|
||||
GHOST_kKeyLeftOS, /* Command key on Apple, Windows key(s) on Windows. */
|
||||
GHOST_kKeyRightOS,
|
||||
#define _GHOST_KEY_MODIFIER_MAX GHOST_kKeyRightOS
|
||||
|
||||
GHOST_kKeyLeftHyper, /* Additional modifier on Wayland & X11, see !136340. */
|
||||
GHOST_kKeyRightHyper,
|
||||
#define _GHOST_KEY_MODIFIER_MAX GHOST_kKeyRightHyper
|
||||
|
||||
GHOST_kKeyGrLess, /* German PC only! */
|
||||
GHOST_kKeyApp, /* Also known as menu key. */
|
||||
|
||||
@@ -248,6 +248,8 @@ const char *GHOST_EventPrinter::getKeyString(const GHOST_TKey key) const
|
||||
CASE_KEY(GHOST_kKeyRightAlt, "RightAlt");
|
||||
CASE_KEY(GHOST_kKeyLeftOS, "LeftOS");
|
||||
CASE_KEY(GHOST_kKeyRightOS, "RightOS");
|
||||
CASE_KEY(GHOST_kKeyLeftHyper, "LeftHyper");
|
||||
CASE_KEY(GHOST_kKeyRightHyper, "RightHyper");
|
||||
CASE_KEY(GHOST_kKeyApp, "App");
|
||||
CASE_KEY(GHOST_kKeyGrLess, "GrLess");
|
||||
CASE_KEY(GHOST_kKeyCapsLock, "CapsLock");
|
||||
|
||||
@@ -48,6 +48,12 @@ GHOST_TKey GHOST_ModifierKeys::getModifierKeyCode(GHOST_TModifierKey mask)
|
||||
case GHOST_kModifierKeyRightOS:
|
||||
key = GHOST_kKeyRightOS;
|
||||
break;
|
||||
case GHOST_kModifierKeyLeftHyper:
|
||||
key = GHOST_kKeyLeftHyper;
|
||||
break;
|
||||
case GHOST_kModifierKeyRightHyper:
|
||||
key = GHOST_kKeyRightHyper;
|
||||
break;
|
||||
default:
|
||||
/* Should not happen. */
|
||||
GHOST_ASSERT(0, "Invalid key!");
|
||||
@@ -76,6 +82,10 @@ bool GHOST_ModifierKeys::get(GHOST_TModifierKey mask) const
|
||||
return m_LeftOS;
|
||||
case GHOST_kModifierKeyRightOS:
|
||||
return m_RightOS;
|
||||
case GHOST_kModifierKeyLeftHyper:
|
||||
return m_LeftHyper;
|
||||
case GHOST_kModifierKeyRightHyper:
|
||||
return m_RightHyper;
|
||||
default:
|
||||
GHOST_ASSERT(0, "Invalid key!");
|
||||
return false;
|
||||
@@ -109,6 +119,12 @@ void GHOST_ModifierKeys::set(GHOST_TModifierKey mask, bool down)
|
||||
case GHOST_kModifierKeyRightOS:
|
||||
m_RightOS = down;
|
||||
break;
|
||||
case GHOST_kModifierKeyLeftHyper:
|
||||
m_LeftHyper = down;
|
||||
break;
|
||||
case GHOST_kModifierKeyRightHyper:
|
||||
m_RightHyper = down;
|
||||
break;
|
||||
default:
|
||||
GHOST_ASSERT(0, "Invalid key!");
|
||||
break;
|
||||
@@ -125,6 +141,8 @@ void GHOST_ModifierKeys::clear()
|
||||
m_RightControl = false;
|
||||
m_LeftOS = false;
|
||||
m_RightOS = false;
|
||||
m_LeftHyper = false;
|
||||
m_RightHyper = false;
|
||||
}
|
||||
|
||||
bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys &keys) const
|
||||
@@ -132,5 +150,6 @@ bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys &keys) const
|
||||
return (m_LeftShift == keys.m_LeftShift) && (m_RightShift == keys.m_RightShift) &&
|
||||
(m_LeftAlt == keys.m_LeftAlt) && (m_RightAlt == keys.m_RightAlt) &&
|
||||
(m_LeftControl == keys.m_LeftControl) && (m_RightControl == keys.m_RightControl) &&
|
||||
(m_LeftOS == keys.m_LeftOS) && (m_RightOS == keys.m_RightOS);
|
||||
(m_LeftOS == keys.m_LeftOS) && (m_RightOS == keys.m_RightOS) &&
|
||||
(m_LeftHyper == keys.m_LeftHyper) && (m_RightHyper == keys.m_RightHyper);
|
||||
}
|
||||
|
||||
@@ -71,4 +71,6 @@ struct GHOST_ModifierKeys {
|
||||
/** Bit-field that stores the appropriate key state. */
|
||||
uint8_t m_LeftOS : 1;
|
||||
uint8_t m_RightOS : 1;
|
||||
uint8_t m_LeftHyper : 1;
|
||||
uint8_t m_RightHyper : 1;
|
||||
};
|
||||
|
||||
@@ -332,8 +332,9 @@ enum {
|
||||
MOD_INDEX_ALT = 1,
|
||||
MOD_INDEX_CTRL = 2,
|
||||
MOD_INDEX_OS = 3,
|
||||
MOD_INDEX_HYPER = 4,
|
||||
};
|
||||
#define MOD_INDEX_NUM (MOD_INDEX_OS + 1)
|
||||
#define MOD_INDEX_NUM (MOD_INDEX_HYPER + 1)
|
||||
|
||||
struct GWL_ModifierInfo {
|
||||
/** Only for printing messages. */
|
||||
@@ -380,6 +381,15 @@ static const GWL_ModifierInfo g_modifier_info_table[MOD_INDEX_NUM] = {
|
||||
/*mod_l*/ GHOST_kModifierKeyLeftOS,
|
||||
/*mod_r*/ GHOST_kModifierKeyRightOS,
|
||||
},
|
||||
/*MOD_INDEX_HYPER*/
|
||||
{
|
||||
/*display_name*/ "Hyper",
|
||||
/*xkb_id*/ XKB_VMOD_NAME_HYPER,
|
||||
/*key_l*/ GHOST_kKeyLeftHyper,
|
||||
/*key_r*/ GHOST_kKeyRightHyper,
|
||||
/*mod_l*/ GHOST_kModifierKeyLeftHyper,
|
||||
/*mod_r*/ GHOST_kModifierKeyRightHyper,
|
||||
},
|
||||
};
|
||||
|
||||
/** \} */
|
||||
@@ -2107,6 +2117,8 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
|
||||
GXMAP(gkey, XKB_KEY_Alt_R, GHOST_kKeyRightAlt);
|
||||
GXMAP(gkey, XKB_KEY_Super_L, GHOST_kKeyLeftOS);
|
||||
GXMAP(gkey, XKB_KEY_Super_R, GHOST_kKeyRightOS);
|
||||
GXMAP(gkey, XKB_KEY_Hyper_L, GHOST_kKeyLeftHyper);
|
||||
GXMAP(gkey, XKB_KEY_Hyper_R, GHOST_kKeyRightHyper);
|
||||
GXMAP(gkey, XKB_KEY_Menu, GHOST_kKeyApp);
|
||||
|
||||
GXMAP(gkey, XKB_KEY_Caps_Lock, GHOST_kKeyCapsLock);
|
||||
|
||||
@@ -710,6 +710,8 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent)
|
||||
XK_Alt_R,
|
||||
XK_Super_L,
|
||||
XK_Super_R,
|
||||
XK_Hyper_L,
|
||||
XK_Hyper_R,
|
||||
};
|
||||
|
||||
for (int i = 0; i < int(ARRAY_SIZE(modifiers)); i++) {
|
||||
@@ -1104,6 +1106,8 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
case GHOST_kKeyLeftControl:
|
||||
case GHOST_kKeyLeftOS:
|
||||
case GHOST_kKeyRightOS:
|
||||
case GHOST_kKeyLeftHyper:
|
||||
case GHOST_kKeyRightHyper:
|
||||
case GHOST_kKey0:
|
||||
case GHOST_kKey1:
|
||||
case GHOST_kKey2:
|
||||
@@ -1666,6 +1670,8 @@ GHOST_TSuccess GHOST_SystemX11::getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
const static KeyCode alt_r = XKeysymToKeycode(m_display, XK_Alt_R);
|
||||
const static KeyCode super_l = XKeysymToKeycode(m_display, XK_Super_L);
|
||||
const static KeyCode super_r = XKeysymToKeycode(m_display, XK_Super_R);
|
||||
const static KeyCode hyper_l = XKeysymToKeycode(m_display, XK_Hyper_L);
|
||||
const static KeyCode hyper_r = XKeysymToKeycode(m_display, XK_Hyper_R);
|
||||
|
||||
/* shift */
|
||||
keys.set(GHOST_kModifierKeyLeftShift,
|
||||
@@ -1685,6 +1691,11 @@ GHOST_TSuccess GHOST_SystemX11::getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightOS,
|
||||
((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1) != 0);
|
||||
/* hyper */
|
||||
keys.set(GHOST_kModifierKeyLeftHyper,
|
||||
((m_keyboard_vector[hyper_l >> 3] >> (hyper_l & 7)) & 1) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightHyper,
|
||||
((m_keyboard_vector[hyper_r >> 3] >> (hyper_r & 7)) & 1) != 0);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
@@ -1917,6 +1928,8 @@ static GHOST_TKey ghost_key_from_keysym(const KeySym key)
|
||||
GXMAP(type, XK_Alt_R, GHOST_kKeyRightAlt);
|
||||
GXMAP(type, XK_Super_L, GHOST_kKeyLeftOS);
|
||||
GXMAP(type, XK_Super_R, GHOST_kKeyRightOS);
|
||||
GXMAP(type, XK_Hyper_L, GHOST_kKeyLeftHyper);
|
||||
GXMAP(type, XK_Hyper_R, GHOST_kKeyRightHyper);
|
||||
|
||||
GXMAP(type, XK_Insert, GHOST_kKeyInsert);
|
||||
GXMAP(type, XK_Delete, GHOST_kKeyDelete);
|
||||
|
||||
@@ -47,7 +47,7 @@ def kmi_args_as_data(kmi):
|
||||
if kmi.any:
|
||||
s.append("\"any\": True")
|
||||
else:
|
||||
for attr in ("shift", "ctrl", "alt", "oskey"):
|
||||
for attr in ("shift", "ctrl", "alt", "oskey", "hyper"):
|
||||
if mod := getattr(kmi, attr):
|
||||
s.append(f"\"{attr:s}\": " + ("-1" if mod == -1 else "True"))
|
||||
if (mod := kmi.key_modifier) and (mod != 'NONE'):
|
||||
|
||||
@@ -24,6 +24,7 @@ def generate(context, space_type, *, use_fallback_keys=True, use_reset=True):
|
||||
("ctrl", False),
|
||||
("alt", False),
|
||||
("oskey", False),
|
||||
("hyper", False),
|
||||
("key_modifier", 'NONE'),
|
||||
):
|
||||
val = getattr(kmi, attr)
|
||||
|
||||
@@ -201,6 +201,11 @@ def draw_kmi(display_keymaps, kc, km, kmi, layout, level):
|
||||
subrow.prop(kmi, "alt_ui", toggle=True)
|
||||
subrow.prop(kmi, "oskey_ui", text="Cmd", toggle=True)
|
||||
|
||||
# On systems that don't support Hyper, only show if it's enabled.
|
||||
# Otherwise the user may have a key binding that doesn't work and can't be changed.
|
||||
if _platform_supports_hyper_key() or kmi.hyper == 1:
|
||||
subrow.prop(kmi, "hyper_ui", text="Hyper", toggle=True)
|
||||
|
||||
subrow.prop(kmi, "key_modifier", text="", event=True)
|
||||
|
||||
# Operator properties
|
||||
@@ -218,6 +223,16 @@ _EVENT_TYPES = set()
|
||||
_EVENT_TYPE_MAP = {}
|
||||
_EVENT_TYPE_MAP_EXTRA = {}
|
||||
|
||||
_HAS_HYPER_KEY = None
|
||||
|
||||
|
||||
def _platform_supports_hyper_key():
|
||||
global _HAS_HYPER_KEY
|
||||
if _HAS_HYPER_KEY is None:
|
||||
from _bpy import _ghost_backend
|
||||
_HAS_HYPER_KEY = _ghost_backend() in {'WAYLAND', 'X11'}
|
||||
return _HAS_HYPER_KEY
|
||||
|
||||
|
||||
def draw_filtered(display_keymaps, filter_type, filter_text, layout):
|
||||
|
||||
@@ -259,6 +274,7 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout):
|
||||
"alt": "alt",
|
||||
"shift": "shift",
|
||||
"oskey": "oskey",
|
||||
"hyper": "hyper",
|
||||
"any": "any",
|
||||
|
||||
# macOS specific modifiers names
|
||||
|
||||
@@ -259,7 +259,7 @@ def _fallback_id(text, fallback):
|
||||
|
||||
|
||||
def any_except(*args):
|
||||
mod = {"ctrl": -1, "alt": -1, "shift": -1, "oskey": -1}
|
||||
mod = {"ctrl": -1, "alt": -1, "shift": -1, "oskey": -1, "hyper": -1}
|
||||
for arg in args:
|
||||
del mod[arg]
|
||||
return mod
|
||||
|
||||
@@ -2610,7 +2610,7 @@ class WM_OT_toolbar_prompt(Operator):
|
||||
# Pressing entry even again exists, as long as it's not mapped to a key (for convenience).
|
||||
if event_type == self._init_event_type:
|
||||
if event_value == 'RELEASE':
|
||||
if not (event.ctrl or event.alt or event.shift or event.oskey):
|
||||
if not (event.ctrl or event.alt or event.shift or event.oskey or event.hyper):
|
||||
context.workspace.status_text_set(None)
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 10
|
||||
#define BLENDER_FILE_SUBVERSION 11
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
||||
@@ -1442,6 +1442,25 @@ void blo_do_versions_userdef(UserDef *userdef)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!USER_VERSION_ATLEAST(405, 11)) {
|
||||
wmKeyConfigFilterItemParams params{};
|
||||
params.check_item = true;
|
||||
params.check_diff_item_add = true;
|
||||
BKE_keyconfig_pref_filter_items(
|
||||
userdef,
|
||||
¶ms,
|
||||
[](wmKeyMapItem *kmi, void * /*user_data*/) -> bool {
|
||||
if (kmi->shift == KM_ANY && kmi->ctrl == KM_ANY && kmi->alt == KM_ANY &&
|
||||
kmi->oskey == KM_ANY)
|
||||
{
|
||||
kmi->hyper = KM_ANY;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a USER_VERSION_ATLEAST check.
|
||||
|
||||
@@ -968,6 +968,7 @@ DEF_ICON_COLOR(EVENT_SHIFT)
|
||||
DEF_ICON_COLOR(EVENT_CTRL)
|
||||
DEF_ICON_COLOR(EVENT_ALT)
|
||||
DEF_ICON_COLOR(EVENT_OS)
|
||||
DEF_ICON_COLOR(EVENT_HYPER)
|
||||
|
||||
DEF_ICON_COLOR(EVENT_F1)
|
||||
DEF_ICON_COLOR(EVENT_F2)
|
||||
|
||||
@@ -4105,6 +4105,7 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
|
||||
kmi_dummy.ctrl = (hotkey_but->modifier_key & KM_CTRL) ? KM_MOD_HELD : KM_NOTHING;
|
||||
kmi_dummy.alt = (hotkey_but->modifier_key & KM_ALT) ? KM_MOD_HELD : KM_NOTHING;
|
||||
kmi_dummy.oskey = (hotkey_but->modifier_key & KM_OSKEY) ? KM_MOD_HELD : KM_NOTHING;
|
||||
kmi_dummy.hyper = (hotkey_but->modifier_key & KM_HYPER) ? KM_MOD_HELD : KM_NOTHING;
|
||||
|
||||
but->drawstr = WM_keymap_item_to_string(&kmi_dummy, true).value_or("");
|
||||
}
|
||||
|
||||
@@ -710,6 +710,9 @@ int UI_icon_from_keymap_item(const wmKeyMapItem *kmi, int r_icon_mod[KM_MOD_NUM]
|
||||
if (kmi->oskey == KM_MOD_HELD) {
|
||||
r_icon_mod[i++] = ICON_EVENT_OS;
|
||||
}
|
||||
if (!ELEM(kmi->hyper, KM_NOTHING, KM_ANY)) {
|
||||
r_icon_mod[i++] = ICON_EVENT_HYPER;
|
||||
}
|
||||
}
|
||||
return UI_icon_from_event_type(kmi->type, kmi->val);
|
||||
}
|
||||
@@ -762,6 +765,7 @@ static void init_event_icons()
|
||||
INIT_EVENT_ICON(ICON_EVENT_CTRL, EVT_LEFTCTRLKEY, KM_ANY);
|
||||
INIT_EVENT_ICON(ICON_EVENT_ALT, EVT_LEFTALTKEY, KM_ANY);
|
||||
INIT_EVENT_ICON(ICON_EVENT_OS, EVT_OSKEY, KM_ANY);
|
||||
INIT_EVENT_ICON(ICON_EVENT_HYPER, EVT_HYPER, KM_ANY);
|
||||
INIT_EVENT_ICON(ICON_EVENT_F1, EVT_F1KEY, KM_ANY);
|
||||
INIT_EVENT_ICON(ICON_EVENT_F2, EVT_F2KEY, KM_ANY);
|
||||
INIT_EVENT_ICON(ICON_EVENT_F3, EVT_F3KEY, KM_ANY);
|
||||
|
||||
@@ -253,6 +253,9 @@ void icon_draw_rect_input(const float x,
|
||||
icon_draw_rect_input_text(&rect, IFACE_("OS"), aspect, alpha, inverted, ICON_KEY_EMPTY2);
|
||||
}
|
||||
}
|
||||
else if (icon_id == ICON_EVENT_HYPER) {
|
||||
icon_draw_rect_input_text(&rect, IFACE_("Hyp"), aspect, alpha, inverted, ICON_KEY_EMPTY2);
|
||||
}
|
||||
else if (icon_id == ICON_EVENT_DEL) {
|
||||
icon_draw_rect_input_text(&rect, IFACE_("Del"), aspect, alpha, inverted, ICON_KEY_EMPTY2);
|
||||
}
|
||||
|
||||
@@ -987,6 +987,8 @@ static void ui_keymap_but_cb(bContext * /*C*/, void *but_v, void * /*key_v*/)
|
||||
&but->rnapoin, "alt", (hotkey_but->modifier_key & KM_ALT) ? KM_MOD_HELD : KM_NOTHING);
|
||||
RNA_int_set(
|
||||
&but->rnapoin, "oskey", (hotkey_but->modifier_key & KM_OSKEY) ? KM_MOD_HELD : KM_NOTHING);
|
||||
RNA_int_set(
|
||||
&but->rnapoin, "hyper", (hotkey_but->modifier_key & KM_HYPER) ? KM_MOD_HELD : KM_NOTHING);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1129,8 +1129,15 @@ std::optional<std::string> UI_key_event_operator_string(const bContext *C,
|
||||
}
|
||||
|
||||
if ((event_val != KM_NOTHING) && (event_type != KM_NOTHING)) {
|
||||
return WM_keymap_item_raw_to_string(
|
||||
KM_NOTHING, KM_NOTHING, KM_NOTHING, KM_NOTHING, 0, event_val, event_type, false);
|
||||
return WM_keymap_item_raw_to_string(KM_NOTHING,
|
||||
KM_NOTHING,
|
||||
KM_NOTHING,
|
||||
KM_NOTHING,
|
||||
KM_NOTHING,
|
||||
0,
|
||||
event_val,
|
||||
event_type,
|
||||
false);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
|
||||
@@ -37,7 +37,7 @@ static const wmKeyMapItem *keymap_item_from_enum_item(const wmKeyMap *keymap,
|
||||
static bool keymap_item_can_collapse(const wmKeyMapItem *kmi_a, const wmKeyMapItem *kmi_b)
|
||||
{
|
||||
return (kmi_a->shift == kmi_b->shift && kmi_a->ctrl == kmi_b->ctrl && kmi_a->alt == kmi_b->alt &&
|
||||
kmi_a->oskey == kmi_b->oskey);
|
||||
kmi_a->oskey == kmi_b->oskey && kmi_a->hyper == kmi_b->hyper);
|
||||
}
|
||||
|
||||
int uiTemplateStatusBarModalItem(uiLayout *layout,
|
||||
|
||||
@@ -965,6 +965,9 @@ void WorkspaceStatus::opmodal(std::string text,
|
||||
if (kmi->oskey == KM_MOD_HELD) {
|
||||
ed_workspace_status_item(workspace_, {}, ICON_EVENT_OS, 0.0f, inverted);
|
||||
}
|
||||
if (!ELEM(kmi->hyper, KM_NOTHING, KM_ANY)) {
|
||||
ed_workspace_status_item(workspace_, {}, ICON_EVENT_HYPER, 0.0f, inverted);
|
||||
}
|
||||
ed_workspace_status_icon_item(workspace_, icon, inverted);
|
||||
ed_workspace_status_text_item(workspace_, std::move(text));
|
||||
}
|
||||
|
||||
@@ -454,6 +454,9 @@ struct ViewOpsData_Utility : ViewOpsData {
|
||||
if (kmi_merge->oskey == KM_MOD_HELD || ELEM(kmi_merge->type, EVT_OSKEY)) {
|
||||
kmi_cpy->oskey = KM_MOD_HELD;
|
||||
}
|
||||
if (kmi_merge->hyper == KM_MOD_HELD || ELEM(kmi_merge->type, EVT_HYPER)) {
|
||||
kmi_cpy->hyper = KM_MOD_HELD;
|
||||
}
|
||||
if (!ISKEYMODIFIER(kmi_merge->type)) {
|
||||
kmi_cpy->keymodifier = kmi_merge->type;
|
||||
}
|
||||
|
||||
@@ -1995,7 +1995,8 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
||||
(ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) &&
|
||||
(event->modifier & KM_SHIFT)) ||
|
||||
(ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && (event->modifier & KM_ALT)) ||
|
||||
((kmi->type == EVT_OSKEY) && (event->modifier & KM_OSKEY)))
|
||||
((kmi->type == EVT_OSKEY) && (event->modifier & KM_OSKEY)) ||
|
||||
((kmi->type == EVT_HYPER) && (event->modifier & KM_HYPER)))
|
||||
{
|
||||
t->modifiers &= ~MOD_NODE_ATTACH;
|
||||
}
|
||||
|
||||
@@ -472,6 +472,10 @@ typedef struct wmKeyMapItem {
|
||||
int8_t alt;
|
||||
/** Also known as "Apple", "Windows-Key" or "Super. */
|
||||
int8_t oskey;
|
||||
/** See #KM_HYPER for details. */
|
||||
int8_t hyper;
|
||||
|
||||
char _pad0[7];
|
||||
|
||||
/** Raw-key modifier. */
|
||||
short keymodifier;
|
||||
|
||||
@@ -283,6 +283,7 @@ const EnumPropertyItem rna_enum_event_type_items[] = {
|
||||
{EVT_RIGHTSHIFTKEY, "RIGHT_SHIFT", 0, "Right Shift", "ShiftR"},
|
||||
RNA_ENUM_ITEM_SEPR,
|
||||
{EVT_OSKEY, "OSKEY", 0, "OS Key", "Cmd"},
|
||||
{EVT_HYPER, "HYPER", 0, "Hyper", "Hyp"},
|
||||
{EVT_APPKEY, "APP", 0, "Application", "App"},
|
||||
{EVT_GRLESSKEY, "GRLESS", 0, "Grless", ""},
|
||||
{EVT_ESCKEY, "ESC", 0, "Esc", ""},
|
||||
@@ -1136,7 +1137,9 @@ static bool rna_KeyMapItem_any_get(PointerRNA *ptr)
|
||||
{
|
||||
wmKeyMapItem *kmi = (wmKeyMapItem *)ptr->data;
|
||||
|
||||
if (kmi->shift == KM_ANY && kmi->ctrl == KM_ANY && kmi->alt == KM_ANY && kmi->oskey == KM_ANY) {
|
||||
if (kmi->shift == KM_ANY && kmi->ctrl == KM_ANY && kmi->alt == KM_ANY && kmi->oskey == KM_ANY &&
|
||||
kmi->hyper == KM_ANY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -1149,10 +1152,10 @@ static void rna_KeyMapItem_any_set(PointerRNA *ptr, bool value)
|
||||
wmKeyMapItem *kmi = (wmKeyMapItem *)ptr->data;
|
||||
|
||||
if (value) {
|
||||
kmi->shift = kmi->ctrl = kmi->alt = kmi->oskey = KM_ANY;
|
||||
kmi->shift = kmi->ctrl = kmi->alt = kmi->oskey = kmi->hyper = KM_ANY;
|
||||
}
|
||||
else {
|
||||
kmi->shift = kmi->ctrl = kmi->alt = kmi->oskey = KM_NOTHING;
|
||||
kmi->shift = kmi->ctrl = kmi->alt = kmi->oskey = kmi->hyper = KM_NOTHING;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1180,6 +1183,12 @@ static bool rna_KeyMapItem_oskey_get(PointerRNA *ptr)
|
||||
return kmi->oskey != KM_NOTHING;
|
||||
}
|
||||
|
||||
static bool rna_KeyMapItem_hyper_get(PointerRNA *ptr)
|
||||
{
|
||||
wmKeyMapItem *kmi = (wmKeyMapItem *)ptr->data;
|
||||
return kmi->hyper != KM_NOTHING;
|
||||
}
|
||||
|
||||
static PointerRNA rna_WindowManager_active_keyconfig_get(PointerRNA *ptr)
|
||||
{
|
||||
wmWindowManager *wm = static_cast<wmWindowManager *>(ptr->data);
|
||||
@@ -2435,6 +2444,11 @@ static void rna_def_event(BlenderRNA *brna)
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "OS Key", "True when the Cmd key is held");
|
||||
|
||||
prop = RNA_def_property(srna, "hyper", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "modifier", KM_HYPER);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Hyper", "True when the Hyper key is held");
|
||||
|
||||
RNA_define_verify_sdna(true); /* not in sdna */
|
||||
}
|
||||
|
||||
@@ -2991,6 +3005,12 @@ static void rna_def_keyconfig(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "OS Key", "Operating system key pressed, -1 for any state");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
prop = RNA_def_property(srna, "hyper", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, nullptr, "hyper");
|
||||
RNA_def_property_range(prop, KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_property_ui_text(prop, "Hyper", "Hyper key pressed, -1 for any state");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
/* XXX(@ideasman42): the `*_ui` suffix is only for the UI, may be removed,
|
||||
* since this is only exposed so the UI can show these settings as toggle-buttons. */
|
||||
prop = RNA_def_property(srna, "shift_ui", PROP_BOOLEAN, PROP_NONE);
|
||||
@@ -3021,6 +3041,18 @@ static void rna_def_keyconfig(BlenderRNA *brna)
|
||||
// RNA_def_property_enum_items(prop, keymap_modifiers_items);
|
||||
RNA_def_property_ui_text(prop, "OS Key", "Operating system key pressed");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
prop = RNA_def_property(srna, "hyper_ui", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "hyper", 0);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_hyper_get", nullptr);
|
||||
// RNA_def_property_enum_items(prop, keymap_modifiers_items);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Hyper",
|
||||
"Hyper key pressed. "
|
||||
/* Additional info since this is not so widely known. */
|
||||
"An additional modifier which can be configured on Linux, typically replacing CapsLock");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
/* End `_ui` modifiers. */
|
||||
|
||||
prop = RNA_def_property(srna, "key_modifier", PROP_ENUM, PROP_NONE);
|
||||
|
||||
@@ -273,7 +273,8 @@ static int rna_Operator_props_dialog_popup(bContext *C,
|
||||
cancel_default);
|
||||
}
|
||||
|
||||
static int keymap_item_modifier_flag_from_args(bool any, int shift, int ctrl, int alt, int oskey)
|
||||
static int keymap_item_modifier_flag_from_args(
|
||||
bool any, int shift, int ctrl, int alt, int oskey, int hyper)
|
||||
{
|
||||
int modifier = 0;
|
||||
if (any) {
|
||||
@@ -307,6 +308,13 @@ static int keymap_item_modifier_flag_from_args(bool any, int shift, int ctrl, in
|
||||
else if (oskey == KM_ANY) {
|
||||
modifier |= KM_OSKEY_ANY;
|
||||
}
|
||||
|
||||
if (hyper == KM_MOD_HELD) {
|
||||
modifier |= KM_HYPER;
|
||||
}
|
||||
else if (hyper == KM_ANY) {
|
||||
modifier |= KM_HYPER_ANY;
|
||||
}
|
||||
}
|
||||
return modifier;
|
||||
}
|
||||
@@ -321,6 +329,7 @@ static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km,
|
||||
int ctrl,
|
||||
int alt,
|
||||
int oskey,
|
||||
int hyper,
|
||||
int keymodifier,
|
||||
int direction,
|
||||
bool repeat,
|
||||
@@ -335,7 +344,7 @@ static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km,
|
||||
// wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmKeyMapItem *kmi = nullptr;
|
||||
char idname_bl[OP_MAX_TYPENAME];
|
||||
const int modifier = keymap_item_modifier_flag_from_args(any, shift, ctrl, alt, oskey);
|
||||
const int modifier = keymap_item_modifier_flag_from_args(any, shift, ctrl, alt, oskey, hyper);
|
||||
|
||||
WM_operator_bl_idname(idname_bl, idname);
|
||||
|
||||
@@ -395,6 +404,7 @@ static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km,
|
||||
int ctrl,
|
||||
int alt,
|
||||
int oskey,
|
||||
int hyper,
|
||||
int keymodifier,
|
||||
int direction,
|
||||
bool repeat)
|
||||
@@ -406,7 +416,7 @@ static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km,
|
||||
}
|
||||
|
||||
wmKeyMapItem *kmi = nullptr;
|
||||
const int modifier = keymap_item_modifier_flag_from_args(any, shift, ctrl, alt, oskey);
|
||||
const int modifier = keymap_item_modifier_flag_from_args(any, shift, ctrl, alt, oskey, hyper);
|
||||
int propvalue = 0;
|
||||
|
||||
KeyMapItem_Params params{};
|
||||
@@ -716,7 +726,8 @@ static wmEvent *rna_Window_event_add_simulate(wmWindow *win,
|
||||
bool shift,
|
||||
bool ctrl,
|
||||
bool alt,
|
||||
bool oskey)
|
||||
bool oskey,
|
||||
bool hyper)
|
||||
{
|
||||
if ((G.f & G_FLAG_EVENT_SIMULATE) == 0) {
|
||||
BKE_report(reports, RPT_ERROR, "Not running with '--enable-event-simulate' enabled");
|
||||
@@ -775,6 +786,9 @@ static wmEvent *rna_Window_event_add_simulate(wmWindow *win,
|
||||
if (oskey) {
|
||||
e.modifier |= KM_OSKEY;
|
||||
}
|
||||
if (hyper) {
|
||||
e.modifier |= KM_HYPER;
|
||||
}
|
||||
|
||||
e.utf8_buf[0] = '\0';
|
||||
if (unicode != nullptr) {
|
||||
@@ -862,6 +876,7 @@ void RNA_api_window(StructRNA *srna)
|
||||
RNA_def_boolean(func, "ctrl", false, "Ctrl", "");
|
||||
RNA_def_boolean(func, "alt", false, "Alt", "");
|
||||
RNA_def_boolean(func, "oskey", false, "OS Key", "");
|
||||
RNA_def_boolean(func, "hyper", false, "Hyper", "");
|
||||
parm = RNA_def_pointer(func, "event", "Event", "Item", "Added key map item");
|
||||
RNA_def_function_return(func, parm);
|
||||
}
|
||||
@@ -1304,6 +1319,7 @@ void RNA_api_keymapitems(StructRNA *srna)
|
||||
RNA_def_int(func, "ctrl", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Ctrl", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "alt", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Alt", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "oskey", KM_NOTHING, KM_ANY, KM_MOD_HELD, "OS Key", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "hyper", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Hyper", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_enum(func, "key_modifier", rna_enum_event_type_items, 0, "Key Modifier", "");
|
||||
RNA_def_enum(func, "direction", rna_enum_event_direction_items, KM_ANY, "Direction", "");
|
||||
RNA_def_boolean(func, "repeat", false, "Repeat", "When set, accept key-repeat events");
|
||||
@@ -1329,6 +1345,7 @@ void RNA_api_keymapitems(StructRNA *srna)
|
||||
RNA_def_int(func, "ctrl", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Ctrl", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "alt", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Alt", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "oskey", KM_NOTHING, KM_ANY, KM_MOD_HELD, "OS Key", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "hyper", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Hyper", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_enum(func, "key_modifier", rna_enum_event_type_items, 0, "Key Modifier", "");
|
||||
RNA_def_enum(func, "direction", rna_enum_event_direction_items, KM_ANY, "Direction", "");
|
||||
RNA_def_boolean(func, "repeat", false, "Repeat", "When set, accept key-repeat events");
|
||||
|
||||
@@ -181,6 +181,7 @@ std::optional<std::string> WM_keymap_item_raw_to_string(int8_t shift,
|
||||
int8_t ctrl,
|
||||
int8_t alt,
|
||||
int8_t oskey,
|
||||
int8_t hyper,
|
||||
short keymodifier,
|
||||
short val,
|
||||
short type,
|
||||
|
||||
@@ -277,16 +277,28 @@ enum {
|
||||
KM_ALT = (1 << 2),
|
||||
/** Use for Windows-Key on MS-Windows, Command-key on macOS and Super on Linux. */
|
||||
KM_OSKEY = (1 << 3),
|
||||
/**
|
||||
* An additional modifier available on Unix systems (in addition to "Super").
|
||||
* Even though standard keyboards don't have a "Hyper" key it is a valid modifier
|
||||
* on Wayland and X11, where it is possible to map a key (typically CapsLock)
|
||||
* to be a Hyper modifier, see !136340.
|
||||
*
|
||||
* Note that this is currently only supported on Wayland & X11
|
||||
* but could could be supported on other platforms if desired.
|
||||
*/
|
||||
KM_HYPER = (1 << 4),
|
||||
|
||||
/* Used for key-map item creation function arguments. */
|
||||
KM_SHIFT_ANY = (1 << 4),
|
||||
KM_CTRL_ANY = (1 << 5),
|
||||
KM_ALT_ANY = (1 << 6),
|
||||
KM_OSKEY_ANY = (1 << 7),
|
||||
KM_SHIFT_ANY = (1 << 5),
|
||||
KM_CTRL_ANY = (1 << 6),
|
||||
KM_ALT_ANY = (1 << 7),
|
||||
KM_OSKEY_ANY = (1 << 8),
|
||||
KM_HYPER_ANY = (1 << 9),
|
||||
|
||||
};
|
||||
|
||||
/** The number of modifiers #wmKeyMapItem & #wmEvent can use. */
|
||||
#define KM_MOD_NUM 4
|
||||
#define KM_MOD_NUM 5
|
||||
|
||||
/* `KM_MOD_*` flags for #wmKeyMapItem and `wmEvent.alt/shift/oskey/ctrl`. */
|
||||
/* Note that #KM_ANY and #KM_NOTHING are used with these defines too. */
|
||||
@@ -759,7 +771,7 @@ struct wmEvent {
|
||||
*/
|
||||
char utf8_buf[6];
|
||||
|
||||
/** Modifier states: #KM_SHIFT, #KM_CTRL, #KM_ALT & #KM_OSKEY. */
|
||||
/** Modifier states: #KM_SHIFT, #KM_CTRL, #KM_ALT, #KM_OSKEY & #KM_HYPER. */
|
||||
uint8_t modifier;
|
||||
|
||||
/** The direction (for #KM_CLICK_DRAG events only). */
|
||||
|
||||
@@ -91,6 +91,8 @@ void WM_event_print(const wmEvent *event)
|
||||
{"CTRL", KM_CTRL},
|
||||
{"ALT", KM_ALT},
|
||||
{"OS", KM_OSKEY},
|
||||
{"HYPER", KM_HYPER},
|
||||
|
||||
};
|
||||
event_ids_from_flag(
|
||||
modifier_id, sizeof(modifier_id), flag_data, ARRAY_SIZE(flag_data), event->modifier);
|
||||
|
||||
@@ -2397,6 +2397,12 @@ BLI_INLINE bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (kmi->hyper != KM_ANY) {
|
||||
const int8_t hyper = (winevent->modifier & KM_HYPER) ? KM_MOD_HELD : KM_NOTHING;
|
||||
if ((hyper != kmi->hyper) && (winevent->type != EVT_HYPER)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only key-map entry with key-modifier is checked,
|
||||
* means all keys without modifier get handled too. */
|
||||
@@ -5214,6 +5220,9 @@ static int wm_event_type_from_ghost_key(GHOST_TKey key)
|
||||
case GHOST_kKeyLeftOS:
|
||||
case GHOST_kKeyRightOS:
|
||||
return EVT_OSKEY;
|
||||
case GHOST_kKeyLeftHyper:
|
||||
case GHOST_kKeyRightHyper:
|
||||
return EVT_HYPER;
|
||||
case GHOST_kKeyLeftAlt:
|
||||
return EVT_LEFTALTKEY;
|
||||
case GHOST_kKeyRightAlt:
|
||||
@@ -6075,6 +6084,10 @@ void wm_event_add_ghostevent(wmWindowManager *wm,
|
||||
SET_FLAG_FROM_TEST(event.modifier, (event.val == KM_PRESS), KM_OSKEY);
|
||||
break;
|
||||
}
|
||||
case EVT_HYPER: {
|
||||
SET_FLAG_FROM_TEST(event.modifier, (event.val == KM_PRESS), KM_HYPER);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (event.val == KM_PRESS) {
|
||||
if (event.keymodifier == 0) {
|
||||
|
||||
@@ -197,7 +197,7 @@ static bool wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b)
|
||||
{
|
||||
return (wm_keymap_item_equals_result(a, b) && a->type == b->type && a->val == b->val &&
|
||||
a->shift == b->shift && a->ctrl == b->ctrl && a->alt == b->alt && a->oskey == b->oskey &&
|
||||
a->keymodifier == b->keymodifier && a->maptype == b->maptype &&
|
||||
a->hyper == b->hyper && a->keymodifier == b->keymodifier && a->maptype == b->maptype &&
|
||||
((a->val != KM_CLICK_DRAG) || (a->direction == b->direction)) &&
|
||||
((ISKEYBOARD(a->type) == 0) ||
|
||||
(a->flag & KMI_REPEAT_IGNORE) == (b->flag & KMI_REPEAT_IGNORE)));
|
||||
@@ -515,14 +515,15 @@ static void keymap_event_set(wmKeyMapItem *kmi, const KeyMapItem_Params *params)
|
||||
kmi->direction = params->direction;
|
||||
|
||||
if (params->modifier == KM_ANY) {
|
||||
kmi->shift = kmi->ctrl = kmi->alt = kmi->oskey = KM_ANY;
|
||||
kmi->shift = kmi->ctrl = kmi->alt = kmi->oskey = kmi->hyper = KM_ANY;
|
||||
}
|
||||
else {
|
||||
/* Only one of the flags should be set. */
|
||||
BLI_assert(((params->modifier & (KM_SHIFT | KM_SHIFT_ANY)) != (KM_SHIFT | KM_SHIFT_ANY)) &&
|
||||
((params->modifier & (KM_CTRL | KM_CTRL_ANY)) != (KM_CTRL | KM_CTRL_ANY)) &&
|
||||
((params->modifier & (KM_ALT | KM_ALT_ANY)) != (KM_ALT | KM_ALT_ANY)) &&
|
||||
((params->modifier & (KM_OSKEY | KM_OSKEY_ANY)) != (KM_OSKEY | KM_OSKEY_ANY)));
|
||||
((params->modifier & (KM_OSKEY | KM_OSKEY_ANY)) != (KM_OSKEY | KM_OSKEY_ANY)) &&
|
||||
((params->modifier & (KM_HYPER | KM_HYPER_ANY)) != (KM_HYPER | KM_HYPER_ANY)));
|
||||
|
||||
kmi->shift = ((params->modifier & KM_SHIFT) ?
|
||||
KM_MOD_HELD :
|
||||
@@ -536,6 +537,9 @@ static void keymap_event_set(wmKeyMapItem *kmi, const KeyMapItem_Params *params)
|
||||
kmi->oskey = ((params->modifier & KM_OSKEY) ?
|
||||
KM_MOD_HELD :
|
||||
((params->modifier & KM_OSKEY_ANY) ? KM_ANY : KM_NOTHING));
|
||||
kmi->hyper = ((params->modifier & KM_HYPER) ?
|
||||
KM_MOD_HELD :
|
||||
((params->modifier & KM_HYPER_ANY) ? KM_ANY : KM_NOTHING));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1199,6 +1203,7 @@ std::optional<std::string> WM_keymap_item_raw_to_string(const int8_t shift,
|
||||
const int8_t ctrl,
|
||||
const int8_t alt,
|
||||
const int8_t oskey,
|
||||
const int8_t hyper,
|
||||
const short keymodifier,
|
||||
const short val,
|
||||
const short type,
|
||||
@@ -1227,6 +1232,10 @@ std::optional<std::string> WM_keymap_item_raw_to_string(const int8_t shift,
|
||||
result_array.append(WM_key_event_string(EVT_OSKEY, true));
|
||||
result_array.append(space);
|
||||
}
|
||||
if (hyper == KM_MOD_HELD) {
|
||||
result_array.append(WM_key_event_string(EVT_HYPER, true));
|
||||
result_array.append(space);
|
||||
}
|
||||
|
||||
if (keymodifier) {
|
||||
result_array.append(WM_key_event_string(keymodifier, compact));
|
||||
@@ -1252,8 +1261,15 @@ std::optional<std::string> WM_keymap_item_raw_to_string(const int8_t shift,
|
||||
|
||||
std::optional<std::string> WM_keymap_item_to_string(const wmKeyMapItem *kmi, const bool compact)
|
||||
{
|
||||
return WM_keymap_item_raw_to_string(
|
||||
kmi->shift, kmi->ctrl, kmi->alt, kmi->oskey, kmi->keymodifier, kmi->val, kmi->type, compact);
|
||||
return WM_keymap_item_raw_to_string(kmi->shift,
|
||||
kmi->ctrl,
|
||||
kmi->alt,
|
||||
kmi->oskey,
|
||||
kmi->hyper,
|
||||
kmi->keymodifier,
|
||||
kmi->val,
|
||||
kmi->type,
|
||||
compact);
|
||||
}
|
||||
|
||||
std::optional<std::string> WM_modalkeymap_items_to_string(const wmKeyMap *km,
|
||||
@@ -1736,6 +1752,10 @@ bool WM_keymap_item_compare(const wmKeyMapItem *k1, const wmKeyMapItem *k2)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (k1->hyper != KM_ANY && k2->hyper != KM_ANY && k1->hyper != k2->hyper) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (k1->keymodifier != k2->keymodifier) {
|
||||
return false;
|
||||
}
|
||||
@@ -2072,6 +2092,7 @@ void WM_keymap_item_restore_to_default(wmWindowManager *wm, wmKeyMap *keymap, wm
|
||||
kmi->ctrl = orig->ctrl;
|
||||
kmi->alt = orig->alt;
|
||||
kmi->oskey = orig->oskey;
|
||||
kmi->hyper = orig->hyper;
|
||||
kmi->keymodifier = orig->keymodifier;
|
||||
kmi->maptype = orig->maptype;
|
||||
kmi->flag = (kmi->flag & ~(KMI_REPEAT_IGNORE | KMI_INACTIVE)) |
|
||||
|
||||
@@ -545,6 +545,12 @@ static bool wm_keymap_item_uses_modifier(const wmKeyMapItem *kmi, const int even
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (kmi->hyper != KM_ANY) {
|
||||
if ((kmi->hyper == KM_NOTHING) != ((event_modifier & KM_HYPER) == 0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -152,6 +152,9 @@ static const struct {
|
||||
{KM_OSKEY,
|
||||
{GHOST_kKeyLeftOS, GHOST_kKeyRightOS},
|
||||
{GHOST_kModifierKeyLeftOS, GHOST_kModifierKeyRightOS}},
|
||||
{KM_HYPER,
|
||||
{GHOST_kKeyLeftHyper, GHOST_kKeyRightHyper},
|
||||
{GHOST_kModifierKeyLeftHyper, GHOST_kModifierKeyRightHyper}},
|
||||
};
|
||||
|
||||
enum ModSide {
|
||||
|
||||
@@ -176,6 +176,9 @@ enum {
|
||||
/* Menu/App key. */
|
||||
EVT_APPKEY = 0x00b2, /* 178 */
|
||||
|
||||
/** Additional modifier, see: #KM_HYPER for details. */
|
||||
EVT_HYPER = 0x00b3, /* 179 */
|
||||
|
||||
EVT_PADPERIOD = 0x00c7, /* 199 */
|
||||
|
||||
EVT_CAPSLOCKKEY = 0x00d3, /* 211 */
|
||||
@@ -395,7 +398,7 @@ enum {
|
||||
/** Test whether the event is a modifier key. */
|
||||
#define ISKEYMODIFIER(event_type) \
|
||||
(((event_type) >= EVT_LEFTCTRLKEY && (event_type) <= EVT_LEFTSHIFTKEY) || \
|
||||
(event_type) == EVT_OSKEY)
|
||||
ELEM((event_type), EVT_OSKEY, EVT_HYPER))
|
||||
|
||||
/**
|
||||
* Test whether the event is any kind:
|
||||
|
||||
Reference in New Issue
Block a user