Skip to content

Commit 70069b5

Browse files
committed
add configuration to include/exclude windows by application
1 parent d052a4b commit 70069b5

File tree

12 files changed

+142
-115
lines changed

12 files changed

+142
-115
lines changed

always-open-on-primary-screen/.img/.~lock.icon.odg#

Lines changed: 0 additions & 1 deletion
This file was deleted.
36.9 KB
Loading

always-open-on-primary-screen/CHANGELOG.bbcode

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
[h1]v3.0[/h1]
2+
[list]\n[*] add configuration to include/exclude windows by application
3+
[/list]
4+
15
[h1]v3.0[/h1]
26
[list]\n[*] better compatibility with Wayland
37
[/list]

always-open-on-primary-screen/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# v3.0
2+
- add configuration to include/exclude windows by application
3+
14
# v3.0
25
- better compatibility with Wayland
36

always-open-on-primary-screen/README.bbcode

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
Makes new windows always open on the monitor that is set as the primary in [i]System Settings[/i] > [i]Display and Monitor[/i] > [i]Display Configuration[/i] > checkbox [i]Primary[/i].
22

3+
The windows to be affected can be filtered by application.
4+
35
Alternatives:[list]
46
[*] [url=https://store.kde.org/p/1617640/]Always Open on Active Screen[/url] (the one that has the mouse cursor)
5-
[*] [url=https://store.kde.org/p/1618008/]Always Open on Focused Screen[/url] (the one that has the focused window)[/list]For more information on installation as well as any requests, please visit [url=https://github.com/nclarius/KWin-window-positioning-scripts/tree/main/always-open-on-primary-screen]the GitHub page[/url].
7+
[*] [url=https://store.kde.org/p/1618008/]Always Open on Focused Screen[/url] (the one that has the focused window)[/list]For more information on installation and configuration as well as any requests, please visit [url=https://github.com/nclarius/KWin-window-positioning-scripts/tree/main/always-open-on-primary-screen]the GitHub page[/url].
68

7-
© 2021 Natalie Clarius ‹[email protected]
9+
© 2021-2022 Natalie Clarius ‹[email protected]
810

9-
with contributions by [url=https://github.com/joedefen]Joe Defenderfer[/url].
11+
with contributions by [url=https://github.com/joedefen]Joe Defenderfer[/url] and [url=https://github.com/tam1m]Tamim Baschour[/url].
1012

1113
This work is licensed under the GNU General Public License v3.0.
1214
This program comes with absolutely no warranty.

always-open-on-primary-screen/README.md

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Extension for KDE’s window manager to make new windows always open on the monitor that is set as primary in *System Settings* > *Display and Monitor* > *Display Configuration* > checkbox *Primary*.
44

5+
The windows to be affected can be filtered by application.
6+
57
![logo](.img/logo_.png)
68

79

@@ -25,20 +27,40 @@ cd KWin-window-positioning-scripts/always-open-on-primary-screen
2527
```
2628

2729

30+
## Configuration
31+
32+
*System Settings* > *Window Management* > *KWin Scripts* > configuration button in the *Always Open on Primary Screen* entry.
33+
34+
You may need to uncheck the checkbox for the script, apply the settings, recheck, and reapply in order for the changes to take effect.
35+
36+
In Plasma versions < 5.24, a bug in the KWin scripting system [[1]](https://bugs.kde.org/show_bug.cgi?id=411430) [[2]](https://bugs.kde.org/show_bug.cgi?id=444378) may cause the configuration not to be found. To fix this, please execute the following commands in a terminal:
37+
38+
```bash
39+
sed -i 's/ConfigModule/Library/g' ~/.local/share/kwin/scripts/tilegaps/metadata.desktop
40+
mkdir -p ~/.local/share/kservices5/
41+
ln -sf ~/.local/share/kwin/scripts/tilegaps/metadata.desktop ~/.local/share/kservices5/tilegaps.desktop
42+
qdbus org.kde.KWin /KWin reconfigure
43+
```
44+
45+
### Window class
46+
47+
To find the window class name of an application: Right-click on the titlebar of a window of the application > *More Actions* > *Configure Special Application Settings...* > the pre-filled entry in *Window class (application)* (if it consists of two words, only the second part) is the window class to put in the script configuration.
48+
49+
2850
## Troubleshooting and known issues
2951

30-
- If some applications still open on the wrong screen, consider disabling applications requesting their own window geometry (this features only exists on X11): *System Settings* > *Window Management* > *Window Behavior* > *Advanced* > *Window placement* > *Allow apps to remember the positions of their own windows, if they support it*.
31-
- Some XWayland applications may attempt to remember their window position; this can be prevented with a window rule, as suggested [here](https://github.com/nclarius/KWin-window-positioning-scripts/issues/11#issuecomment-1091979196): *System Settings* > *Window Management* > *Window Rules* > *Add New...* > enter the window class of the application and possibly restrict the window type to normal windows > *Add Property..* > *Ignore requested geometry* > *Force*, *Yes* > *Apply*.
32-
- - It has been suggested that the script might not work for snap applications; if this appears to be the case for you, consider using native packages instead.
52+
- On X11: If KDE applications open on the wrong screen, consider disabling applications requesting their own window geometry: *System Settings* > *Window Management* > *Window Behavior* > *Advanced* > *Window placement* > *Allow apps to remember the positions of their own windows, if they support it*.
53+
- On Wayland: Some XWayland applications may attempt to remember their window position; this can be prevented with a window rule: *System Settings* > *Window Management* > *Window Rules* > *Add New...* > enter the window class of the application and possibly restrict the window type to normal windows > *Add Property..* > *Ignore requested geometry* > *Force*, *Yes* > *Apply*.
54+
- It has been suggested that the script might not work for snap applications; if this appears to be the case for you, consider using the native packages instead.
3355
- For notifications to appear on the primary screen, make sure you have the notification applet present and enabled on your primary screen, and not present or disabled on any secondary screens.
34-
- Some applications (e.g. Spotify) may still open on the wrong screen despite these workarounds. I have not yet figured out how to fix this. If you do, please let me know!
56+
- If some applications still open on the wrong screen despite these workarounds, please report it, even more so if you have an idea what the problem might be or how to fix it.
3557

3658

3759
## Small Print
3860

39-
© 2021 Natalie Clarius \<[email protected]\>
61+
© 2021-2022 Natalie Clarius \<[email protected]\>
4062

41-
with contributions by [Joe Defenderfer](https://github.com/joedefen).
63+
with contributions by [Joe Defenderfer](https://github.com/joedefen) and [Tamim Baschour](https://github.com/tam1m).
4264

4365
This work is licensed under the GNU General Public License v3.0.
4466
This program comes with absolutely no warranty.
Binary file not shown.

always-open-on-primary-screen/contents/code/main.js

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,41 @@ GNU General Public License v3.0
66

77
// initialization
88
const config = {
9-
classlist: readConfig("classlist", "")
10-
.toLowerCase()
11-
.split("\n")
12-
.map((s) => s.trim()),
13-
allowmode: readConfig("allowmode", false),
14-
denymode: readConfig("denymode", true),
15-
debugmode: readConfig("debugMode", false),
16-
};
9+
classList: readConfig("classList", "")
10+
.toLowerCase()
11+
.split("\n")
12+
.map((s) => s.trim()),
13+
allowMode: readConfig("allowMode", true),
14+
denyMode: readConfig("denyMode", false),
15+
debugMode: readConfig("debugMode", true)
16+
};
1717

1818
function debug(...args) {
19-
if (config.debugmode) console.debug("alwaysopenonprimaryscreen:", ...args);
19+
if (config.debugMode) console.debug("alwaysopenonprimaryscreen:", ...args);
2020
}
2121
debug("initializing");
2222

2323
// primary screen is 0'th
24-
primaryScreen = 0;
24+
var primaryScreen = 0;
2525

2626
// when a client is added
2727
workspace.clientAdded.connect(client => {
2828
debug("client", JSON.stringify(client, undefined, 2));
2929

30-
// abort if client is null, not regeometrizable, or already on right screen
31-
if (!client
32-
|| (config.denymode && config.classlist.includes(String(client.resourceClass))) // using denymode and window class is in list
33-
|| (config.allowmode && !config.classlist.includes(String(client.resourceClass))) // using allowmode and window class is not in list
34-
|| !(client.resizeable && client.moveable && client.moveableAcrossScreens)
35-
|| client.screen == primaryScreen)
30+
// abort conditions
31+
if (!client // null
32+
|| (config.allowMode && !config.classList.includes(String(client.resourceClass))) // using allowmode and window class is not in list
33+
|| (config.denyMode && config.classList.includes(String(client.resourceClass))) // using denymode and window class is in list
34+
|| !(client.resizeable && client.moveable && client.moveableAcrossScreens) // not regeomtrizable
35+
|| client.screen == primaryScreen) // already on right screen
3636
return;
3737

3838
// move client to primary screen
3939
debug("sending client", client.caption, "to primary screen", primaryScreen);
4040
workspace.sendClientToScreen(client, primaryScreen);
4141

4242
// clip and move client into bounds of screen dimensions
43-
if (!(client.moveable && client.resizeable)) return;
44-
area = workspace.clientArea(KWin.MaximizeArea, client);
43+
var area = workspace.clientArea(KWin.MaximizeArea, client);
4544
// window width/height maximally screen width/height
4645
client.geometry.width = Math.min(client.width, area.width);
4746
client.geometry.height = Math.min(client.height, area.height);
Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
3-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
5-
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
6-
<kcfgfile name=""/>
2+
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
3+
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
4+
<kcfgfile name="" />
75
<group name="">
8-
<entry name="classlist" type="String">
6+
<entry name="classList" type="String">
97
<label>Effected window class names</label>
108
<default></default>
119
</entry>
12-
<entry name="allowmode" type="Bool">
13-
<default>false</default>
14-
</entry>
15-
<entry name="denymode" type="Bool">
10+
<entry name="allowMode" type="Bool">
1611
<default>true</default>
1712
</entry>
13+
<entry name="denyMode" type="Bool">
14+
<default>false</default>
15+
</entry>
1816
<entry name="debugMode" type="Bool">
1917
<label>Whether to log debug information</label>
20-
<default>false</default>
18+
<default>true</default>
2119
</entry>
2220
</group>
2321
</kcfg>
Lines changed: 70 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,74 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<ui version="4.0">
3-
<class>AlwaysOpenOnPrimaryScreenConfigForm</class>
4-
<widget class="QWidget" name="AlwaysOpenOnPrimaryScreenConfigForm">
5-
<property name="geometry">
6-
<rect>
7-
<x>0</x>
8-
<y>0</y>
9-
<width>400</width>
10-
<height>451</height>
11-
</rect>
12-
</property>
13-
<property name="windowTitle">
14-
<string>Form</string>
15-
</property>
16-
<layout class="QVBoxLayout" name="verticalLayout">
17-
<item>
18-
<widget class="QLabel" name="label">
19-
<property name="whatsThis">
20-
<string notr="true">Effected window class names. One per line</string>
21-
</property>
22-
<property name="text">
23-
<string notr="true">Effected window class names. One per line</string>
24-
</property>
3+
<class>AlwaysOpenOnPrimaryScreenConfigForm</class>
4+
<widget class="QWidget" name="AlwaysOpenOnPrimaryScreenConfigForm">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>400</width>
10+
<height>451</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Always Open on Primary Screen</string>
15+
</property>
16+
<layout class="QVBoxLayout" name="verticalLayout">
17+
<item>
18+
<widget class="QLabel" name="label_1">
19+
<property name="text">
20+
<string>Apply to windows belonging to</string>
21+
</property>
22+
</widget>
23+
</item>
24+
<item>
25+
<widget class="QSplitter" name="splitter">
26+
<property name="sizePolicy">
27+
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
28+
<horstretch>0</horstretch>
29+
<verstretch>0</verstretch>
30+
</sizepolicy>
31+
</property>
32+
<property name="orientation">
33+
<enum>Qt::Horizontal</enum>
34+
</property>
35+
<widget class="QRadioButton" name="kcfg_allowMode">
36+
<property name="text">
37+
<string notr="true">all except the follwing</string>
38+
</property>
39+
<attribute name="buttonGroup">
40+
<string notr="true">matchTypeGroup</string>
41+
</attribute>
42+
</widget>
43+
<widget class="QRadioButton" name="kcfg_denyMode">
44+
<property name="text">
45+
<string notr="true">none except the following</string>
46+
</property>
47+
<attribute name="buttonGroup">
48+
<string notr="true">matchTypeGroup</string>
49+
</attribute>
50+
</widget>
51+
</widget>
52+
</item>
53+
<item>
54+
<widget class="QLabel" name="label_2">
55+
<property name="text">
56+
<string>applications:</string>
57+
</property>
58+
</widget>
59+
</item>
60+
<item>
61+
<widget class="QPlainTextEdit" name="kcfg_classList">
62+
<property name="placeholderText">
63+
<string>List of window classes (example: dolphin), one per line</string>
64+
</property>
65+
</widget>
66+
</item>
67+
</layout>
2568
</widget>
26-
</item>
27-
<item>
28-
<widget class="QPlainTextEdit" name="kcfg_classlist"/>
29-
</item>
30-
<item>
31-
<widget class="QSplitter" name="splitter">
32-
<property name="sizePolicy">
33-
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
34-
<horstretch>0</horstretch>
35-
<verstretch>0</verstretch>
36-
</sizepolicy>
37-
</property>
38-
<property name="orientation">
39-
<enum>Qt::Horizontal</enum>
40-
</property>
41-
<widget class="QRadioButton" name="kcfg_allowmode">
42-
<property name="text">
43-
<string notr="true">Allow matching windows</string>
44-
</property>
45-
<attribute name="buttonGroup">
46-
<string notr="true">matchTypeGroup</string>
47-
</attribute>
48-
</widget>
49-
<widget class="QRadioButton" name="kcfg_denymode">
50-
<property name="text">
51-
<string notr="true">Deny matching windows</string>
52-
</property>
53-
<attribute name="buttonGroup">
54-
<string notr="true">matchTypeGroup</string>
55-
</attribute>
56-
</widget>
57-
</widget>
58-
</item>
59-
<item>
60-
<widget class="QCheckBox" name="kcfg_debugMode">
61-
<property name="text">
62-
<string notr="true">DebugMode</string>
63-
</property>
64-
</widget>
65-
</item>
66-
</layout>
67-
</widget>
68-
<resources/>
69-
<connections/>
70-
<buttongroups>
71-
<buttongroup name="matchTypeGroup"/>
72-
</buttongroups>
69+
<resources />
70+
<connections />
71+
<buttongroups>
72+
<buttongroup name="matchTypeGroup" />
73+
</buttongroups>
7374
</ui>

0 commit comments

Comments
 (0)