Skip to content

Commit

Permalink
add configuration to include/exclude windows by application
Browse files Browse the repository at this point in the history
  • Loading branch information
nclarius committed May 3, 2022
1 parent d052a4b commit 70069b5
Show file tree
Hide file tree
Showing 12 changed files with 142 additions and 115 deletions.
1 change: 0 additions & 1 deletion always-open-on-primary-screen/.img/.~lock.icon.odg#

This file was deleted.

Binary file added always-open-on-primary-screen/.img/config.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions always-open-on-primary-screen/CHANGELOG.bbcode
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[h1]v3.0[/h1]
[list]\n[*] add configuration to include/exclude windows by application
[/list]

[h1]v3.0[/h1]
[list]\n[*] better compatibility with Wayland
[/list]
Expand Down
3 changes: 3 additions & 0 deletions always-open-on-primary-screen/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# v3.0
- add configuration to include/exclude windows by application

# v3.0
- better compatibility with Wayland

Expand Down
8 changes: 5 additions & 3 deletions always-open-on-primary-screen/README.bbcode
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
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].

The windows to be affected can be filtered by application.

Alternatives:[list]
[*] [url=https://store.kde.org/p/1617640/]Always Open on Active Screen[/url] (the one that has the mouse cursor)
[*] [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].
[*] [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].

© 2021 Natalie Clarius ‹[email protected]
© 2021-2022 Natalie Clarius ‹[email protected]

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

This work is licensed under the GNU General Public License v3.0.
This program comes with absolutely no warranty.
Expand Down
34 changes: 28 additions & 6 deletions always-open-on-primary-screen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

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*.

The windows to be affected can be filtered by application.

![logo](.img/logo_.png)


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


## Configuration

*System Settings* > *Window Management* > *KWin Scripts* > configuration button in the *Always Open on Primary Screen* entry.

You may need to uncheck the checkbox for the script, apply the settings, recheck, and reapply in order for the changes to take effect.

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:

```bash
sed -i 's/ConfigModule/Library/g' ~/.local/share/kwin/scripts/tilegaps/metadata.desktop
mkdir -p ~/.local/share/kservices5/
ln -sf ~/.local/share/kwin/scripts/tilegaps/metadata.desktop ~/.local/share/kservices5/tilegaps.desktop
qdbus org.kde.KWin /KWin reconfigure
```

### Window class

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.


## Troubleshooting and known issues

- 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*.
- 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*.
- - 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.
- 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*.
- 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*.
- 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.
- 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.
- 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!
- 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.


## Small Print

© 2021 Natalie Clarius \<[email protected]\>
© 2021-2022 Natalie Clarius \<[email protected]\>

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

This work is licensed under the GNU General Public License v3.0.
This program comes with absolutely no warranty.
Expand Down
Binary file not shown.
35 changes: 17 additions & 18 deletions always-open-on-primary-screen/contents/code/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,41 @@ GNU General Public License v3.0

// initialization
const config = {
classlist: readConfig("classlist", "")
.toLowerCase()
.split("\n")
.map((s) => s.trim()),
allowmode: readConfig("allowmode", false),
denymode: readConfig("denymode", true),
debugmode: readConfig("debugMode", false),
};
classList: readConfig("classList", "")
.toLowerCase()
.split("\n")
.map((s) => s.trim()),
allowMode: readConfig("allowMode", true),
denyMode: readConfig("denyMode", false),
debugMode: readConfig("debugMode", true)
};

function debug(...args) {
if (config.debugmode) console.debug("alwaysopenonprimaryscreen:", ...args);
if (config.debugMode) console.debug("alwaysopenonprimaryscreen:", ...args);
}
debug("initializing");

// primary screen is 0'th
primaryScreen = 0;
var primaryScreen = 0;

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

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

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

// clip and move client into bounds of screen dimensions
if (!(client.moveable && client.resizeable)) return;
area = workspace.clientArea(KWin.MaximizeArea, client);
var area = workspace.clientArea(KWin.MaximizeArea, client);
// window width/height maximally screen width/height
client.geometry.width = Math.min(client.width, area.width);
client.geometry.height = Math.min(client.height, area.height);
Expand Down
20 changes: 9 additions & 11 deletions always-open-on-primary-screen/contents/config/main.xml
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<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
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name=""/>
<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
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
<kcfgfile name="" />
<group name="">
<entry name="classlist" type="String">
<entry name="classList" type="String">
<label>Effected window class names</label>
<default></default>
</entry>
<entry name="allowmode" type="Bool">
<default>false</default>
</entry>
<entry name="denymode" type="Bool">
<entry name="allowMode" type="Bool">
<default>true</default>
</entry>
<entry name="denyMode" type="Bool">
<default>false</default>
</entry>
<entry name="debugMode" type="Bool">
<label>Whether to log debug information</label>
<default>false</default>
<default>true</default>
</entry>
</group>
</kcfg>
139 changes: 70 additions & 69 deletions always-open-on-primary-screen/contents/ui/config.ui
Original file line number Diff line number Diff line change
@@ -1,73 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AlwaysOpenOnPrimaryScreenConfigForm</class>
<widget class="QWidget" name="AlwaysOpenOnPrimaryScreenConfigForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>451</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="whatsThis">
<string notr="true">Effected window class names. One per line</string>
</property>
<property name="text">
<string notr="true">Effected window class names. One per line</string>
</property>
<class>AlwaysOpenOnPrimaryScreenConfigForm</class>
<widget class="QWidget" name="AlwaysOpenOnPrimaryScreenConfigForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>451</height>
</rect>
</property>
<property name="windowTitle">
<string>Always Open on Primary Screen</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_1">
<property name="text">
<string>Apply to windows belonging to</string>
</property>
</widget>
</item>
<item>
<widget class="QSplitter" name="splitter">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QRadioButton" name="kcfg_allowMode">
<property name="text">
<string notr="true">all except the follwing</string>
</property>
<attribute name="buttonGroup">
<string notr="true">matchTypeGroup</string>
</attribute>
</widget>
<widget class="QRadioButton" name="kcfg_denyMode">
<property name="text">
<string notr="true">none except the following</string>
</property>
<attribute name="buttonGroup">
<string notr="true">matchTypeGroup</string>
</attribute>
</widget>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>applications:</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="kcfg_classList">
<property name="placeholderText">
<string>List of window classes (example: dolphin), one per line</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="kcfg_classlist"/>
</item>
<item>
<widget class="QSplitter" name="splitter">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QRadioButton" name="kcfg_allowmode">
<property name="text">
<string notr="true">Allow matching windows</string>
</property>
<attribute name="buttonGroup">
<string notr="true">matchTypeGroup</string>
</attribute>
</widget>
<widget class="QRadioButton" name="kcfg_denymode">
<property name="text">
<string notr="true">Deny matching windows</string>
</property>
<attribute name="buttonGroup">
<string notr="true">matchTypeGroup</string>
</attribute>
</widget>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_debugMode">
<property name="text">
<string notr="true">DebugMode</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="matchTypeGroup"/>
</buttongroups>
<resources />
<connections />
<buttongroups>
<buttongroup name="matchTypeGroup" />
</buttongroups>
</ui>
1 change: 0 additions & 1 deletion always-open-on-primary-screen/metadata.desktop
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,3 @@ X-KDE-ServiceTypes=KWin/Script,KCModule
X-KDE-ConfigModule=kwin/effects/configs/kcm_kwin4_genericscripted
X-KDE-PluginKeyword=alwaysopenonprimaryscreen
X-KDE-ParentComponents=alwaysopenonprimaryscreen
X-KDE-PluginInfo-EnabledByDefault=true
12 changes: 6 additions & 6 deletions always-open-on-primary-screen/package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ changes_bb='[list]\n'"$(cat CHANGELOG.txt | sed 's/- /[*] /g')"$'\n[/list]'
echo "$caption_bb"$'\n'"$changes_bb"$'\n\n'"$(cat CHANGELOG.bbcode)" > "CHANGELOG.bbcode"
echo 'generated changelog bbcode'

# generate GitHub release
gh release create "${name}"'_v'"${version}" -F CHANGELOG.txt
echo 'generated GitHub release'

# generate KDE store release
# generate kwinscript package
find . -name "*.kwinscript" -type f -delete
zip -rq "${name}"'_v'"${version}"'.kwinscript' \
contents \
Expand All @@ -35,12 +31,16 @@ zip -rq "${name}"'_v'"${version}"'.kwinscript' \
CHANGELOG.md \
CHANGELOG.bbcode \
LICENSE
echo 'generated KDE Store release'
echo 'generated kwinscript package'

# commit changes to GitHub
git add .
git commit -q -m "$(paste -sd '; ' CHANGELOG.txt | sed 's/- / /g')"
git push -q
echo 'commited changes to git'

# generate GitHub release
gh release create "${name}"'_v'"${version}" -F CHANGELOG.txt "${name}"'_v'"${version}"'.kwinscript'
echo 'generated GitHub release'

echo 'done'

0 comments on commit 70069b5

Please sign in to comment.