Skip to content

Commit

Permalink
keymap: Add option "unlockOnPress" for LockMods action
Browse files Browse the repository at this point in the history
This is an extensions to XKB. It intends to allow to deactivate CapsLock on press
rather than on release, as in other platforms such as Windows.
  • Loading branch information
wismill committed Feb 8, 2024
1 parent a6057c4 commit d13f3f0
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/keymap.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ enum xkb_action_flags {
ACTION_ACCEL = (1 << 8),
ACTION_SAME_SCREEN = (1 << 9),
ACTION_LOCK_ON_RELEASE = (1 << 10),
ACTION_UNLOCK_ON_PRESS = (1 << 11),
};

enum xkb_action_controls {
Expand Down
14 changes: 11 additions & 3 deletions src/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,17 @@ xkb_filter_mod_lock_new(struct xkb_state *state, struct xkb_filter *filter)
{
filter->priv = (state->components.locked_mods &
filter->action.mods.mods.mask);
state->set_mods |= filter->action.mods.mods.mask;
if (!(filter->action.mods.flags & ACTION_LOCK_NO_LOCK))
state->components.locked_mods |= filter->action.mods.mods.mask;
if (filter->priv && (filter->action.mods.flags & ACTION_UNLOCK_ON_PRESS)) {
/* XKB extension: Unlock on second press */
state->clear_mods |= filter->action.mods.mods.mask;
if (!(filter->action.mods.flags & ACTION_LOCK_NO_UNLOCK))
state->components.locked_mods &= ~filter->priv;
filter->priv = 0;
} else {
state->set_mods |= filter->action.mods.mods.mask;
if (!(filter->action.mods.flags & ACTION_LOCK_NO_LOCK))
state->components.locked_mods |= filter->action.mods.mods.mask;
}
}

static bool
Expand Down
15 changes: 11 additions & 4 deletions src/xkbcomp/action.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ enum action_field {
ACTION_FIELD_KEYCODE,
ACTION_FIELD_MODS_TO_CLEAR,
ACTION_FIELD_LOCK_ON_RELEASE,
ACTION_FIELD_UNLOCK_ON_PRESS,
};

ActionsInfo *
Expand Down Expand Up @@ -168,6 +169,7 @@ static const LookupEntry fieldStrings[] = {
{ "clearmods", ACTION_FIELD_MODS_TO_CLEAR },
{ "clearmodifiers", ACTION_FIELD_MODS_TO_CLEAR },
{ "lockOnRelease", ACTION_FIELD_LOCK_ON_RELEASE },
{ "unlockOnPress", ACTION_FIELD_UNLOCK_ON_PRESS },
{ NULL, 0 }
};

Expand Down Expand Up @@ -334,10 +336,15 @@ HandleSetLatchLockMods(struct xkb_context *ctx, const struct xkb_mod_set *mods,
return CheckBooleanFlag(ctx, action->type, field,
ACTION_LATCH_TO_LOCK, array_ndx, value,
&act->flags);
if (type == ACTION_TYPE_MOD_LOCK &&
field == ACTION_FIELD_AFFECT)
return CheckAffectField(ctx, action->type, array_ndx, value,
&act->flags);
if (type == ACTION_TYPE_MOD_LOCK) {
if (field == ACTION_FIELD_AFFECT)
return CheckAffectField(ctx, action->type, array_ndx, value,
&act->flags);
if (field == ACTION_FIELD_UNLOCK_ON_PRESS)
return CheckBooleanFlag(ctx, action->type, field,
ACTION_UNLOCK_ON_PRESS, array_ndx, value,
&act->flags);
}

return ReportIllegal(ctx, action->type, field);
}
Expand Down
3 changes: 2 additions & 1 deletion src/xkbcomp/keymap-dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,11 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
else
args = ModMaskText(keymap->ctx, &keymap->mods,
action->mods.mods.mods);
write_buf(buf, "%s%s(modifiers=%s%s%s%s)%s", prefix, type, args,
write_buf(buf, "%s%s(modifiers=%s%s%s%s%s)%s", prefix, type, args,
(action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "",
(action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "",
(action->type == ACTION_TYPE_MOD_LOCK) ? affect_lock_text(action->mods.flags, false) : "",
(action->type == ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_UNLOCK_ON_PRESS)) ? ",unlockOnPress" : "",
suffix);
break;

Expand Down
6 changes: 6 additions & 0 deletions test/data/compat/caps
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ partial xkb_compatibility "caps_lock" {
action = LockMods(modifiers = Lock);
};
};

partial xkb_compatibility "caps_lock_unlock_on_press" {
interpret Caps_Lock {
action = LockMods(modifiers = Lock, unlockOnPress);
};
};
1 change: 1 addition & 0 deletions test/data/rules/evdev
Original file line number Diff line number Diff line change
Expand Up @@ -1160,6 +1160,7 @@
mod_led:compose = +ledcompose(compose)
japan:kana_lock = +japan(kana_lock)
caps:shiftlock = +ledcaps(shift_lock)
caps:unlock_on_press = +caps(caps_lock_unlock_on_press)
grab:break_actions = +xfree86(grab_break)


Expand Down

0 comments on commit d13f3f0

Please sign in to comment.