Skip to content

Commit ca5ea8d

Browse files
committed
Update Wayland Support command
Fixes: hluk/CopyQ#3513
1 parent bb12079 commit ca5ea8d

1 file changed

Lines changed: 111 additions & 92 deletions

File tree

‎commands/wayland-support.ini‎

Lines changed: 111 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -18,169 +18,188 @@ Command="
1818
copyq triggerGlobalShortcut {COMMAND_NAME}
1919
2020
On Gnome, clipboard monitor is executed as X11 app using XWayland.
21+
22+
Links:
23+
- https://github.com/ReimuNotMoe/ydotool
24+
- https://github.com/emersion/grim
25+
- https://github.com/emersion/slurp
2126
*/
2227
2328
function isSway() {
24-
return env('SWAYSOCK').length != 0
29+
return env('SWAYSOCK').length != 0;
2530
}
2631
2732
function isHyprland() {
28-
return env('HYPRLAND_CMD').length != 0
33+
return env('HYPRLAND_CMD').length != 0;
2934
}
3035
3136
function isKde() {
32-
return env('XDG_CURRENT_DESKTOP') == 'KDE'
37+
return env('XDG_CURRENT_DESKTOP') == 'KDE';
3338
}
3439
3540
function isGnome() {
36-
return str(env('XAUTHORITY')).includes('mutter-Xwayland')
41+
return str(env('XAUTHORITY')).includes('mutter-Xwayland');
3742
}
3843
3944
function run() {
40-
const p = execute.apply(this, arguments)
45+
const p = execute.apply(this, arguments);
4146
if (!p) {
42-
throw 'Failed to start ' + arguments[0]
47+
throw 'Failed to start ' + arguments[0];
4348
}
4449
if (p.exit_code !== 0) {
45-
throw 'Failed command ' + arguments[0] + ': ' + str(p.stderr)
50+
throw 'Failed command ' + arguments[0] + ': ' + str(p.stderr);
4651
}
47-
return p.stdout
52+
return p.stdout;
4853
}
4954
5055
function swayGetTree() {
51-
const tree = run('swaymsg', '--raw', '--type', 'get_tree')
52-
return JSON.parse(str(tree))
56+
const tree = run('swaymsg', '--raw', '--type', 'get_tree');
57+
return JSON.parse(str(tree));
5358
}
5459
5560
function swayFindFocused(tree) {
56-
const nodes = tree['nodes'].concat(tree['floating_nodes'])
61+
const nodes = tree['nodes'].concat(tree['floating_nodes']);
5762
for (const node of nodes) {
58-
if (node['focused'])
59-
return node
60-
const focusedNode = swayFindFocused(node)
61-
if (focusedNode)
62-
return focusedNode
63+
if (node['focused']) {
64+
return node;
65+
}
66+
const focusedNode = swayFindFocused(node);
67+
if (focusedNode) {
68+
return focusedNode;
69+
}
6370
}
64-
return undefined
71+
return undefined;
6572
}
6673
6774
function hyprlandFindFocused() {
68-
const window = run('hyprctl', '-j', 'activewindow')
69-
return JSON.parse(str(window))
75+
const window = run('hyprctl', '-j', 'activewindow');
76+
return JSON.parse(str(window));
7077
}
7178
7279
function kdeFocused() {
73-
return str(run('kdotool', 'getactivewindow', 'getwindowname'))
80+
try {
81+
const window = run('kdotool', 'getactivewindow', 'getwindowname');
82+
return str(window).trim();
83+
} catch (e) {
84+
serverLog(`Failed to call kdotool: ${e}`);
85+
// Avoid storing data since we cannot filter it by window title
86+
removeData(mimeOutputTab);
87+
return '';
88+
}
7489
}
7590
7691
function sendShortcut(...shortcut) {
77-
sleep(100)
78-
run('ydotool', 'key', ...shortcut)
92+
sleep(100);
93+
run('ydotool', 'key', ...shortcut);
7994
}
8095
81-
global.currentWindowTitle = function() {
96+
global.currentWindowTitle = function () {
8297
if (isSway()) {
83-
const tree = swayGetTree()
84-
const focusedNode = swayFindFocused(tree)
85-
return focusedNode ? focusedNode['name'] : ''
98+
const tree = swayGetTree();
99+
const focusedNode = swayFindFocused(tree);
100+
return focusedNode ? focusedNode['name'] : '';
86101
}
87102
88103
if (isHyprland()) {
89-
const focusedWindow = hyprlandFindFocused()
90-
return focusedWindow ? focusedWindow['title'] : ''
104+
const focusedWindow = hyprlandFindFocused();
105+
return focusedWindow ? focusedWindow['title'] : '';
91106
}
92107
93108
if (isKde()) {
94-
return kdeFocused()
109+
return kdeFocused();
95110
}
96111
97-
return ''
98-
}
112+
return '';
113+
};
99114
100-
global.paste = function() {
101-
sendShortcut('42:1', '110:1', '110:0', '42:0')
102-
}
115+
global.paste = function () {
116+
sendShortcut('42:1', '110:1', '110:0', '42:0');
117+
};
103118
104-
const copy_ = global.copy
105-
global.copy = function() {
119+
const copy_ = global.copy;
120+
global.copy = function () {
106121
if (arguments.length == 0) {
107-
sendShortcut('29:1', '46:1', '46:0', '29:0')
122+
sendShortcut('29:1', '46:1', '46:0', '29:0');
108123
} else {
109-
copy_.apply(this, arguments)
124+
copy_.apply(this, arguments);
110125
}
111-
}
126+
};
112127
113-
global.focusPrevious = function() {
114-
hide()
115-
}
128+
global.focusPrevious = function () {
129+
hide();
130+
};
116131
117132
function overrideToRunInXWayland(fn) {
118-
const oldFn = global[fn]
119-
global[fn] = function() {
133+
const oldFn = global[fn];
134+
global[fn] = function () {
120135
if (isGnome() && env('QT_QPA_PLATFORM') != 'xcb') {
121-
serverLog(`Starting XWayland ${fn}`)
122-
setEnv('QT_QPA_PLATFORM', 'xcb')
123-
execute('copyq', '--clipboard-access', fn)
124-
serverLog(`Stopping XWayland ${fn}`)
125-
return
136+
serverLog(`Starting XWayland ${fn}`);
137+
setEnv('QT_QPA_PLATFORM', 'xcb');
138+
execute('copyq', '--clipboard-access', fn);
139+
serverLog(`Stopping XWayland ${fn}`);
140+
return;
126141
}
127-
return oldFn()
142+
return oldFn();
143+
};
144+
}
145+
overrideToRunInXWayland('monitorClipboard');
146+
overrideToRunInXWayland('synchronizeFromSelection');
147+
overrideToRunInXWayland('synchronizeToSelection');
148+
149+
const onClipboardChanged_ = onClipboardChanged;
150+
onClipboardChanged = function () {
151+
const title = currentWindowTitle();
152+
if (title) {
153+
setData(mimeWindowTitle, title);
128154
}
129-
}
130-
overrideToRunInXWayland('monitorClipboard')
131-
overrideToRunInXWayland('synchronizeFromSelection')
132-
overrideToRunInXWayland('synchronizeToSelection')
133-
134-
const onClipboardChanged_ = onClipboardChanged
135-
onClipboardChanged = function() {
136-
const title = currentWindowTitle()
137-
if (title)
138-
setData(mimeWindowTitle, title)
139-
onClipboardChanged_()
140-
}
155+
onClipboardChanged_();
156+
};
141157
142158
function gnomeScreenshot(arg) {
143-
const tmpFile = TemporaryFile()
144-
tmpFile.setFileTemplate(Dir().temp().absoluteFilePath('copyq-XXXXXX.png'))
145-
tmpFile.openWriteOnly()
146-
tmpFile.close()
159+
const tmpFile = TemporaryFile();
160+
tmpFile.setFileTemplate(Dir().temp().absoluteFilePath('copyq-XXXXXX.png'));
161+
tmpFile.openWriteOnly();
162+
tmpFile.close();
147163
run(
148164
'gnome-screenshot',
149165
arg || '--delay=0',
150166
'--include-pointer',
151167
'--file',
152168
tmpFile.fileName(),
153-
)
154-
const file = File(tmpFile.fileName())
155-
file.openReadOnly()
156-
const stdout = File('/dev/stdout')
157-
stdout.openWriteOnly()
158-
stdout.write(file.readAll())
169+
);
170+
const file = File(tmpFile.fileName());
171+
file.openReadOnly();
172+
const stdout = File('/dev/stdout');
173+
stdout.openWriteOnly();
174+
stdout.write(file.readAll());
159175
}
160176
161-
screenshot = function(format, screenName) {
162-
if (isSway() || isHyprland())
163-
return run('grim', '-t', format || 'png', '-')
164-
if (isGnome())
165-
return gnomeScreenshot()
177+
screenshot = function (format, screenName) {
178+
if (isSway() || isHyprland()) {
179+
return run('grim', '-t', format || 'png', '-');
180+
}
181+
if (isGnome()) {
182+
return gnomeScreenshot();
183+
}
166184
return run(
167185
'spectacle',
168186
'--background',
169187
'--nonotify',
170188
'--pointer',
171189
'--output',
172190
'/dev/stdout',
173-
)
174-
}
191+
);
192+
};
175193
176-
screenshotSelect = function(format, screenName) {
194+
screenshotSelect = function (format, screenName) {
177195
if (isSway() || isHyprland()) {
178-
let geometry = run('slurp')
179-
geometry = str(geometry).trim()
180-
return run('grim', '-c', '-g', geometry, '-t', format || 'png', '-')
196+
let geometry = run('slurp');
197+
geometry = str(geometry).trim();
198+
return run('grim', '-c', '-g', geometry, '-t', format || 'png', '-');
199+
}
200+
if (isGnome()) {
201+
return gnomeScreenshot('--area');
181202
}
182-
if (isGnome())
183-
return gnomeScreenshot('--area')
184203
return run(
185204
'spectacle',
186205
'--background',
@@ -189,17 +208,17 @@ Command="
189208
'--region',
190209
'--output',
191210
'/dev/stdout',
192-
)
193-
}
211+
);
212+
};
194213
195-
global.triggerGlobalShortcut = function(commandName) {
196-
const cmds = commands()
214+
global.triggerGlobalShortcut = function (commandName) {
215+
const cmds = commands();
197216
for (const cmd of cmds) {
198217
if (cmd.isGlobalShortcut && cmd.enable && cmd.name == commandName)
199-
return action(cmd.cmd)
218+
return action(cmd.cmd);
200219
}
201-
throw 'Failed to find enabled global command with given name'
202-
}"
220+
throw 'Failed to find enabled global command with given name';
221+
};"
203222
Icon=
204223
IsScript=true
205224
Name=Wayland Support

0 commit comments

Comments
 (0)