keyboard.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Gnome imports
  2. import Adw from "gi://Adw";
  3. import GObject from "gi://GObject";
  4. import Gtk from "gi://Gtk";
  5. // Extension Imports
  6. import { gettext as _ } from "resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js";
  7. // Prefs UI
  8. import { EntryRow, PreferencesPage, RadioRow } from "./widgets.js";
  9. import { Logger } from "../shared/logger.js";
  10. export class KeyboardPage extends PreferencesPage {
  11. static {
  12. GObject.registerClass(this);
  13. }
  14. constructor({ kbdSettings }) {
  15. super({ title: _("Keyboard"), icon_name: "input-keyboard-symbolic" });
  16. this.add_group({
  17. title: _("Drag-and-drop modifier key"),
  18. description: _(
  19. "Change the modifier key for tiling windows via drag-and-drop. Select 'None' to always tile"
  20. ),
  21. children: [
  22. new RadioRow({
  23. title: _("Modifier key"),
  24. settings: kbdSettings,
  25. bind: "mod-mask-mouse-tile",
  26. options: {
  27. Super: _("Super"),
  28. Ctrl: _("Ctrl"),
  29. Alt: _("Alt"),
  30. None: _("None"),
  31. },
  32. }),
  33. ],
  34. });
  35. this.add_group({
  36. title: _("Shortcuts"),
  37. description: _(
  38. 'Change the tiling shortcuts. To clear a shortcut clear the input field. To apply a shortcut press enter. <a href="https://github.com/forge-ext/forge/wiki/Keyboard-Shortcuts">Syntax examples</a>'
  39. ),
  40. children: Object.entries({
  41. window: "Tiling shortcuts",
  42. con: "Container shortcuts",
  43. workspace: "Workspace shortcuts",
  44. focus: "Appearance shortcuts",
  45. prefs: "Other shortcuts",
  46. }).map(([prefix, gettextKey]) =>
  47. KeyboardPage.makeKeygroupExpander(prefix, gettextKey, kbdSettings)
  48. ),
  49. });
  50. }
  51. static makeKeygroupExpander(prefix, gettextKey, settings) {
  52. const expander = new Adw.ExpanderRow({ title: _(gettextKey) });
  53. KeyboardPage.createKeyList(settings, prefix).forEach((key) =>
  54. expander.add_row(
  55. new EntryRow({
  56. title: key,
  57. settings,
  58. bind: key,
  59. map: {
  60. from(settings, bind) {
  61. return settings.get_strv(bind).join(",");
  62. },
  63. to(settings, bind, value) {
  64. if (!!value) {
  65. const mappings = value.split(",").map((x) => {
  66. const [, key, mods] = Gtk.accelerator_parse(x);
  67. return Gtk.accelerator_valid(key, mods) && Gtk.accelerator_name(key, mods);
  68. });
  69. if (mappings.every((x) => !!x)) {
  70. Logger.info("setting", bind, "to", mappings);
  71. settings.set_strv(bind, mappings);
  72. }
  73. } else {
  74. // If value deleted, unset the mapping
  75. settings.set_strv(bind, []);
  76. }
  77. },
  78. },
  79. })
  80. )
  81. );
  82. return expander;
  83. }
  84. static createKeyList(settings, categoryName) {
  85. return settings
  86. .list_keys()
  87. .filter((keyName) => !!keyName && !!categoryName && keyName.startsWith(categoryName))
  88. .sort((a, b) => {
  89. const aUp = a.toUpperCase();
  90. const bUp = b.toUpperCase();
  91. if (aUp < bUp) return -1;
  92. if (aUp > bUp) return 1;
  93. return 0;
  94. });
  95. }
  96. }