├── makefile
├── README.md
├── metadata.desktop
└── contents
├── config
└── main.xml
├── code
└── kwin-desktop-pin.js
└── ui
└── config.ui
/makefile:
--------------------------------------------------------------------------------
1 | install:
2 | plasmapkg2 --type kwinscript -i .
3 | mkdir -p ~/.local/share/kservices5
4 | ln -sf ~/.local/share/kwin/scripts/desktop-pin/metadata.desktop ~/.local/share/kservices5/kwin-script-desktop-pin.desktop
5 |
6 | uninstall:
7 | plasmapkg2 --type kwinscript -r desktop-pin
8 | rm ~/.local/share/kservices5/kwin-script-desktop-pin.desktop
9 |
10 | debug:
11 | QT_LOGGING_RULES="kwin_*.debug=true" kwin --replace && tail -f ~/.xsession-errors
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### desktop pin
2 |
3 | kwin script for making windows inside/outside a specified area pin to all desktops
4 |
5 | i pretty much just use this to make the desktops act like gnome, where only the primary monitor switches
6 |
7 | `make install`: install the plugin
8 |
9 | `make uninstall`: uninstall the plugin
10 |
11 | `make debug`: replace kwin with debug logging enabled and tail the log (you need to re-run kwin --replace from krunner after using this)
--------------------------------------------------------------------------------
/metadata.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Name=Desktop Pin
3 | Comment=Pin monitors inside/outside a defined area to all desktops
4 | Icon=preferences-system-windows-script-test
5 |
6 | X-Plasma-API=javascript
7 | X-Plasma-MainScript=code/kwin-desktop-pin.js
8 |
9 | X-KDE-PluginInfo-Name=desktop-pin
10 | X-KDE-PluginInfo-Version=0.0.1
11 | X-KDE-PluginInfo-Author=Leigh Oliver
12 | X-KDE-PluginInfo-Website=github.com/leigholiver/kwin-desktop-pin
13 | X-KDE-PluginInfo-Email=leigholiver@users.noreply.github.com
14 | X-KDE-PluginInfo-Depends=
15 | X-KDE-PluginInfo-License=GPL
16 | X-KDE-ServiceTypes=KWin/Script,KCModule
17 |
18 | X-KDE-Library=kwin/effects/configs/kcm_kwin4_genericscripted
19 | X-KDE-PluginKeyword=desktop-pin
20 | X-KDE-ParentComponents=desktop-pin
21 |
22 | Type=Service
23 |
--------------------------------------------------------------------------------
/contents/config/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 | 0
11 |
12 |
13 |
14 | 0
15 |
16 |
17 |
18 | 1920
19 |
20 |
21 |
22 | 1080
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/contents/code/kwin-desktop-pin.js:
--------------------------------------------------------------------------------
1 | var excludes = readConfig("excludes", "");
2 | var config = {
3 | // defines the area
4 | x: readConfig("x", 0),
5 | y: readConfig("y", 0),
6 | width: readConfig("width", 1920),
7 | height: readConfig("height", 1080),
8 |
9 | // if false, any windows outside the area will stick
10 | // if true, any windows inside the area will stick
11 | include: readConfig("pinmode", false),
12 |
13 | // list of clients to exclude
14 | excludes: [
15 | "Desktop — Plasma",
16 | "Latte Shell — Latte Dock",
17 | "Latte Dock"
18 | ].concat((excludes == "" ? [] : ("" + excludes).split("\n")))
19 | };
20 | startDesktopPin();
21 |
22 | function calcPins(client) {
23 | if (clientIsExcluded(client)) return
24 |
25 | var midPointX = client.geometry.x + (client.geometry.width / 2);
26 | var midPointY = client.geometry.y + (client.geometry.height/ 2);
27 | var isInArea = (midPointX >= config.x && midPointX <= config.x + config.width) && (midPointY >= config.y && midPointY <= config.y + config.height);
28 | client.onAllDesktops = (config.include == isInArea);
29 | print(client.caption + " in area?: " + isInArea + " setting on all desktops to: " + client.onAllDesktops);
30 | }
31 |
32 | function startDesktopPin() {
33 | var clients = workspace.clientList();
34 | for (var i = clients.length; i > 0; i--) {
35 | onClientAdded(clients[i]);
36 | }
37 | workspace.clientAdded.connect(onClientAdded);
38 | workspace.clientRemoved.connect(onClientRemoved);
39 | }
40 |
41 | function onClientMoved(client) {
42 | if (typeof client === 'undefined') {
43 | return;
44 | }
45 | calcPins(client);
46 | }
47 |
48 | function onClientAdded(client) {
49 | if (typeof client === 'undefined') {
50 | return;
51 | }
52 | client.clientFinishUserMovedResized.connect(onClientMoved);
53 | calcPins(client);
54 | }
55 |
56 | function onClientRemoved(client) {
57 | if (typeof client === 'undefined') {
58 | return;
59 | }
60 | client.clientFinishUserMovedResized.disconnect(onClientMoved);
61 | }
62 |
63 | function clientIsExcluded(client) {
64 | for(var i=0; i
2 |
3 | KWin::DesktopPinConfigForm
4 |
5 |
6 |
7 | 0
8 | 0
9 | 263
10 | 285
11 |
12 |
13 |
14 | Form
15 |
16 |
17 | -
18 |
19 |
-
20 |
21 |
-
22 |
23 |
24 | Area X Pos
25 |
26 |
27 |
28 | -
29 |
30 |
31 | 0
32 |
33 |
34 | 0
35 |
36 |
37 | 9999
38 |
39 |
40 |
41 |
42 |
43 | -
44 |
45 |
-
46 |
47 |
48 | Area Y Pos
49 |
50 |
51 |
52 | -
53 |
54 |
55 | 0
56 |
57 |
58 | 0
59 |
60 |
61 | 9999
62 |
63 |
64 |
65 |
66 |
67 | -
68 |
69 |
-
70 |
71 |
72 | Area Width
73 |
74 |
75 |
76 | -
77 |
78 |
79 | 1920
80 |
81 |
82 | 0
83 |
84 |
85 | 9999
86 |
87 |
88 |
89 |
90 |
91 |
92 | -
93 |
94 |
-
95 |
96 |
97 | Area Height
98 |
99 |
100 |
101 | -
102 |
103 |
104 | 1080
105 |
106 |
107 | 0
108 |
109 |
110 | 9999
111 |
112 |
113 |
114 |
115 |
116 | -
117 |
118 |
-
119 |
120 |
121 | Pin Windows
122 |
123 |
124 |
125 | -
126 |
127 |
-
128 |
129 | Outside
130 |
131 |
132 | -
133 |
134 | Inside
135 |
136 |
137 |
138 |
139 |
140 |
141 | -
142 |
143 |
-
144 |
145 |
146 | Window captions to exclude (each caption on a new line, regex supported)
147 |
148 |
149 |
150 | -
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
--------------------------------------------------------------------------------