175 lines
4.4 KiB
JavaScript
Executable File
175 lines
4.4 KiB
JavaScript
Executable File
// https://github.com/eonpatapon/gnome-shell-extension-caffeine
|
|
|
|
import Gdk from 'gi://Gdk';
|
|
import Gtk from 'gi://Gtk';
|
|
import GObject from 'gi://GObject';
|
|
|
|
const genParam = (type, name, ...dflt) =>
|
|
GObject.ParamSpec[type](
|
|
name,
|
|
name,
|
|
name,
|
|
GObject.ParamFlags.READWRITE,
|
|
...dflt
|
|
);
|
|
|
|
const _ = (t) => t;
|
|
|
|
export let ShortcutSettingWidget = class extends Gtk.Button {
|
|
static {
|
|
GObject.registerClass(
|
|
{
|
|
Properties: {
|
|
shortcut: genParam('string', 'shortcut', ''),
|
|
},
|
|
Signals: {
|
|
changed: { param_types: [GObject.TYPE_STRING] },
|
|
},
|
|
},
|
|
this
|
|
);
|
|
}
|
|
|
|
constructor(content, settings, key, window) {
|
|
super({ valign: Gtk.Align.CENTER, has_frame: false });
|
|
this._key = key;
|
|
this._settings = settings;
|
|
this.window = window;
|
|
|
|
this.content = content;
|
|
this.connect('clicked', this._onActivated.bind(this));
|
|
|
|
let label = new Gtk.ShortcutLabel({ disabled_text: _('New accelerator…') });
|
|
this._label = label;
|
|
this.set_child(label);
|
|
|
|
this.bind_property(
|
|
'shortcut',
|
|
label,
|
|
'accelerator',
|
|
GObject.BindingFlags.DEFAULT
|
|
);
|
|
[this.shortcut] = this._settings.get_strv(this._key);
|
|
}
|
|
|
|
_onActivated(widget) {
|
|
let ctl = new Gtk.EventControllerKey();
|
|
|
|
if (!this._editor) {
|
|
this._editor = new Gtk.Window({
|
|
title: 'Accelerator',
|
|
modal: true,
|
|
hide_on_close: true,
|
|
transient_for: widget.get_root(),
|
|
width_request: 480,
|
|
height_request: 320,
|
|
child: this.content,
|
|
});
|
|
}
|
|
|
|
this._editor.add_controller(ctl);
|
|
ctl.connect('key-pressed', this._onKeyPressed.bind(this));
|
|
this._editor.present();
|
|
}
|
|
|
|
_onKeyPressed(_widget, keyval, keycode, state) {
|
|
let mask = state & Gtk.accelerator_get_default_mod_mask();
|
|
mask &= ~Gdk.ModifierType.LOCK_MASK;
|
|
|
|
if (!mask && keyval === Gdk.KEY_Escape) {
|
|
this._editor.close();
|
|
return Gdk.EVENT_STOP;
|
|
}
|
|
|
|
if (keyval === Gdk.KEY_BackSpace) {
|
|
this.saveShortcut(); // Clear shortcut
|
|
return Gdk.EVENT_STOP;
|
|
}
|
|
|
|
if (
|
|
!this.isValidBinding(mask, keycode, keyval) ||
|
|
!this.isValidAccel(mask, keyval)
|
|
) {
|
|
return Gdk.EVENT_STOP;
|
|
}
|
|
|
|
this.saveShortcut(keyval, keycode, mask);
|
|
return Gdk.EVENT_STOP;
|
|
}
|
|
|
|
saveShortcut(keyval, keycode, mask) {
|
|
if (!keyval && !keycode) {
|
|
this.shortcut = '';
|
|
} else {
|
|
this.shortcut = Gtk.accelerator_name_with_keycode(
|
|
null,
|
|
keyval,
|
|
keycode,
|
|
mask
|
|
);
|
|
}
|
|
|
|
console.log('saved new shortcut');
|
|
|
|
this.emit('changed', this.shortcut);
|
|
this._settings.set_strv(this._key, [this.shortcut]);
|
|
// this._editor.destroy();
|
|
this._editor.close();
|
|
}
|
|
|
|
// Functions from https://gitlab.gnome.org/GNOME/gnome-control-center/-/blob/main/panels/keyboard/keyboard-shortcuts.c
|
|
|
|
keyvalIsForbidden(keyval) {
|
|
return [
|
|
// Navigation keys
|
|
Gdk.KEY_Home,
|
|
Gdk.KEY_Left,
|
|
Gdk.KEY_Up,
|
|
Gdk.KEY_Right,
|
|
Gdk.KEY_Down,
|
|
Gdk.KEY_Page_Up,
|
|
Gdk.KEY_Page_Down,
|
|
Gdk.KEY_End,
|
|
Gdk.KEY_Tab,
|
|
|
|
// Return
|
|
Gdk.KEY_KP_Enter,
|
|
Gdk.KEY_Return,
|
|
|
|
Gdk.KEY_Mode_switch,
|
|
].includes(keyval);
|
|
}
|
|
|
|
isValidBinding(mask, keycode, keyval) {
|
|
return !(
|
|
mask === 0 ||
|
|
(mask === Gdk.SHIFT_MASK &&
|
|
keycode !== 0 &&
|
|
((keyval >= Gdk.KEY_a && keyval <= Gdk.KEY_z) ||
|
|
(keyval >= Gdk.KEY_A && keyval <= Gdk.KEY_Z) ||
|
|
(keyval >= Gdk.KEY_0 && keyval <= Gdk.KEY_9) ||
|
|
(keyval >= Gdk.KEY_kana_fullstop &&
|
|
keyval <= Gdk.KEY_semivoicedsound) ||
|
|
(keyval >= Gdk.KEY_Arabic_comma && keyval <= Gdk.KEY_Arabic_sukun) ||
|
|
(keyval >= Gdk.KEY_Serbian_dje &&
|
|
keyval <= Gdk.KEY_Cyrillic_HARDSIGN) ||
|
|
(keyval >= Gdk.KEY_Greek_ALPHAaccent &&
|
|
keyval <= Gdk.KEY_Greek_omega) ||
|
|
(keyval >= Gdk.KEY_hebrew_doublelowline &&
|
|
keyval <= Gdk.KEY_hebrew_taf) ||
|
|
(keyval >= Gdk.KEY_Thai_kokai && keyval <= Gdk.KEY_Thai_lekkao) ||
|
|
(keyval >= Gdk.KEY_Hangul_Kiyeog &&
|
|
keyval <= Gdk.KEY_Hangul_J_YeorinHieuh) ||
|
|
(keyval === Gdk.KEY_space && mask === 0) ||
|
|
this.keyvalIsForbidden(keyval)))
|
|
);
|
|
}
|
|
|
|
isValidAccel(mask, keyval) {
|
|
return (
|
|
Gtk.accelerator_valid(keyval, mask) ||
|
|
(keyval === Gdk.KEY_Tab && mask !== 0)
|
|
);
|
|
}
|
|
};
|