Skip to content

Commit cc73657

Browse files
committed
GUACAMOLE-2232: On-Screen Keyboard: CapsLock gets out-of-sync on macOS.
1 parent f21ba60 commit cc73657

9 files changed

Lines changed: 60 additions & 15 deletions

File tree

guacamole-common-js/src/main/webapp/modules/OnScreenKeyboard.js

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -306,27 +306,53 @@ Guacamole.OnScreenKeyboard = function(layout) {
306306
// Retrieve originally-pressed keysym, if modifier was already pressed
307307
var originalKeysym = modifierKeysyms[key.modifier];
308308

309-
// Activate modifier if not pressed
310-
if (originalKeysym === undefined) {
311-
312-
addClass(keyboard, modifierClass);
313-
modifierKeysyms[key.modifier] = key.keysym;
314-
315-
// Send key event only if keysym is meaningful
309+
// Toggle modifiers send both keydown and keyup on each press
310+
if (key.toggle) {
311+
312+
// Toggle the modifier visual state
313+
if (originalKeysym === undefined) {
314+
addClass(keyboard, modifierClass);
315+
modifierKeysyms[key.modifier] = key.keysym;
316+
}
317+
else {
318+
removeClass(keyboard, modifierClass);
319+
delete modifierKeysyms[key.modifier];
320+
}
321+
322+
// Send both keydown and keyup to perform the toggle
316323
if (key.keysym && osk.onkeydown)
317324
osk.onkeydown(key.keysym);
325+
if (key.keysym && osk.onkeyup)
326+
osk.onkeyup(key.keysym);
318327

319328
}
320329

321-
// Deactivate if not pressed
330+
// Sticky modifiers: activate on first press, deactivate on second
322331
else {
323332

324-
removeClass(keyboard, modifierClass);
325-
delete modifierKeysyms[key.modifier];
326-
327-
// Send key event only if original keysym is meaningful
328-
if (originalKeysym && osk.onkeyup)
329-
osk.onkeyup(originalKeysym);
333+
// Activate modifier if not pressed
334+
if (originalKeysym === undefined) {
335+
336+
addClass(keyboard, modifierClass);
337+
modifierKeysyms[key.modifier] = key.keysym;
338+
339+
// Send key event only if keysym is meaningful
340+
if (key.keysym && osk.onkeydown)
341+
osk.onkeydown(key.keysym);
342+
343+
}
344+
345+
// Deactivate if pressed
346+
else {
347+
348+
removeClass(keyboard, modifierClass);
349+
delete modifierKeysyms[key.modifier];
350+
351+
// Send key event only if original keysym is meaningful
352+
if (originalKeysym && osk.onkeyup)
353+
osk.onkeyup(originalKeysym);
354+
355+
}
330356

331357
}
332358

@@ -928,11 +954,22 @@ Guacamole.OnScreenKeyboard.Key = function(template, name) {
928954
* the names of keys; both the "RightShift" and "LeftShift" keys may set
929955
* the "shift" modifier, for example. By default, the key will affect no
930956
* modifiers.
931-
*
957+
*
932958
* @type {string}
933959
*/
934960
this.modifier = template.modifier;
935961

962+
/**
963+
* Whether this key is a toggle modifier. Toggle modifiers send both
964+
* keydown and keyup events when pressed, so each press performs one
965+
* toggle of the modifier state (e.g., Caps Lock, Num Lock, Scroll Lock).
966+
* Non-toggle modifiers remain sticky and are released by a subsequent
967+
* press. By default, modifiers are not toggles.
968+
*
969+
* @type {boolean}
970+
*/
971+
this.toggle = template.toggle || false;
972+
936973
/**
937974
* An array containing the names of each modifier required for this key to
938975
* have an effect. For example, a lowercase letter may require nothing,

guacamole/src/main/frontend/src/layouts/de-de-qwertz.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
"Caps" : [{
104104
"title" : "Caps",
105105
"modifier" : "caps",
106+
"toggle" : true,
106107
"keysym" : 65509
107108
}],
108109
"LAlt" : [{

guacamole/src/main/frontend/src/layouts/en-us-qwerty.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"Caps" : [{
7676
"title" : "Caps",
7777
"modifier" : "caps",
78+
"toggle" : true,
7879
"keysym" : 65509
7980
}],
8081
"LAlt" : [{

guacamole/src/main/frontend/src/layouts/es-es-qwerty.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
"Caps" : [{
104104
"title" : "Caps",
105105
"modifier" : "caps",
106+
"toggle" : true,
106107
"keysym" : 65509
107108
}],
108109
"LAlt" : [{

guacamole/src/main/frontend/src/layouts/fr-fr-azerty.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
"Caps" : [{
107107
"title" : "Caps",
108108
"modifier" : "caps",
109+
"toggle" : true,
109110
"keysym" : 65509
110111
}],
111112
"LAlt" : [{

guacamole/src/main/frontend/src/layouts/it-it-qwerty.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
"Caps" : [{
104104
"title" : "Caps",
105105
"modifier" : "caps",
106+
"toggle" : true,
106107
"keysym" : 65509
107108
}],
108109
"LAlt" : [{

guacamole/src/main/frontend/src/layouts/nl-nl-qwerty.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
"Caps" : [{
104104
"title" : "Caps",
105105
"modifier" : "caps",
106+
"toggle" : true,
106107
"keysym" : 65509
107108
}],
108109
"LAlt" : [{

guacamole/src/main/frontend/src/layouts/ru-ru-qwerty.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"Caps" : [{
7676
"title" : "Caps",
7777
"modifier" : "caps",
78+
"toggle" : true,
7879
"keysym" : 65509
7980
}],
8081
"LAlt" : [{

guacamole/src/main/frontend/src/layouts/tr-tr-qwerty.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
"Caps" : [{
7575
"title" : "Caps",
7676
"modifier" : "caps",
77+
"toggle" : true,
7778
"keysym" : 65509
7879
}],
7980
"LAlt" : [{

0 commit comments

Comments
 (0)