ydotool.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // SPDX-FileCopyrightText: JingMatrix https://github.com/JingMatrix
  2. //
  3. // SPDX-License-Identifier: GPL-2.0-or-later
  4. 'use strict';
  5. const Gio = imports.gi.Gio;
  6. const Gdk = imports.gi.Gdk;
  7. const keyCodes = new Map([
  8. ['1', 2],
  9. ['2', 3],
  10. ['3', 4],
  11. ['4', 5],
  12. ['5', 6],
  13. ['6', 7],
  14. ['7', 8],
  15. ['8', 9],
  16. ['9', 10],
  17. ['0', 11],
  18. ['-', 12],
  19. ['=', 13],
  20. ['Q', 16],
  21. ['W', 17],
  22. ['E', 18],
  23. ['R', 19],
  24. ['T', 20],
  25. ['Y', 21],
  26. ['U', 22],
  27. ['I', 23],
  28. ['O', 24],
  29. ['P', 25],
  30. ['[', 26],
  31. [']', 27],
  32. ['A', 30],
  33. ['S', 31],
  34. ['D', 32],
  35. ['F', 33],
  36. ['G', 34],
  37. ['H', 35],
  38. ['J', 36],
  39. ['K', 37],
  40. ['L', 38],
  41. [';', 39],
  42. ["'", 40],
  43. ['Z', 44],
  44. ['X', 45],
  45. ['C', 46],
  46. ['V', 47],
  47. ['B', 48],
  48. ['N', 49],
  49. ['M', 50],
  50. [',', 51],
  51. ['.', 52],
  52. ['/', 53],
  53. ['\\', 43],
  54. ]);
  55. class Controller {
  56. constructor() {
  57. // laucher for wl-clipboard
  58. this._launcher = new Gio.SubprocessLauncher({
  59. flags:
  60. Gio.SubprocessFlags.STDOUT_PIPE |
  61. Gio.SubprocessFlags.STDERR_MERGE,
  62. });
  63. this._args = [];
  64. this.buttonMap = new Map([
  65. [Gdk.BUTTON_PRIMARY, '0'],
  66. [Gdk.BUTTON_MIDDLE, '2'],
  67. [Gdk.BUTTON_SECONDARY, '1'],
  68. ]);
  69. }
  70. get args() {
  71. return this._args;
  72. }
  73. set args(opts) {
  74. this._args = ['ydotool'].concat(opts);
  75. try {
  76. this._launcher.spawnv(this._args);
  77. } catch (e) {
  78. debug(e, this._args);
  79. }
  80. }
  81. /*
  82. * Pointer Events
  83. */
  84. movePointer(dx, dy) {
  85. if (dx === 0 && dy === 0)
  86. return;
  87. this.args = ['mousemove', '--', dx.toString(), dy.toString()];
  88. }
  89. pressPointer(button) {
  90. this.args = ['click', '0x4' + this.buttonMap.get(button)];
  91. }
  92. releasePointer(button) {
  93. this.args = ['click', '0x8' + this.buttonMap.get(button)];
  94. }
  95. clickPointer(button) {
  96. this.args = ['click', '0xC' + this.buttonMap.get(button)];
  97. }
  98. doubleclickPointer(button) {
  99. this.args = [
  100. 'click',
  101. '0xC' + this.buttonMap.get(button),
  102. 'click',
  103. '0xC' + this.buttonMap.get(button),
  104. ];
  105. }
  106. scrollPointer(dx, dy) {
  107. if (dx === 0 && dy === 0)
  108. return;
  109. this.args = ['mousemove', '-w', '--', dx.toString(), dy.toString()];
  110. }
  111. /*
  112. * Keyboard Events
  113. */
  114. pressKeys(input, modifiers_codes) {
  115. if (typeof input === 'string' && modifiers_codes.length === 0) {
  116. try {
  117. this._launcher.spawnv(['wtype', input]);
  118. } catch (e) {
  119. debug(e);
  120. this.arg = ['type', '--', input];
  121. }
  122. } else {
  123. if (typeof input === 'number') {
  124. modifiers_codes.push(input);
  125. } else if (typeof input === 'string') {
  126. input = input.toUpperCase();
  127. for (var i = 0; i < input.length; i++) {
  128. if (keyCodes.get(input[i])) {
  129. modifiers_codes.push(keyCodes.get(input[i]));
  130. } else {
  131. debug('Keycode for ' + input[i] + ' not found');
  132. return;
  133. }
  134. }
  135. }
  136. this._args = ['key'];
  137. modifiers_codes.forEach((code) => this._args.push(code + ':1'));
  138. modifiers_codes
  139. .reverse()
  140. .forEach((code) => this._args.push(code + ':0'));
  141. this.args = this._args;
  142. }
  143. }
  144. destroy() {
  145. this._args = [];
  146. }
  147. }
  148. /**
  149. * The service class for this component
  150. */
  151. var Component = Controller;