2

How can I have Window Rules (as seen in System Settings > Workspace > Window Management > Window Rules), that are conditional on my laptop using an external monitor?

When I'm connected to an external monitor, I'd like several windows to be launched on the laptop's monitor and pinned (visible on all desktops). When I'm only using the laptop's monitor, the windows should get default behavior. Is there a way to specify this?

I don't need anything to happen when I unplug or plug in the monitor; it's fine for existing windows to keep their last behavior.

I'm open to solutions that may involve "you'll need to write a shell script or program", but I have no idea where I might hook such a thing in, or if it's even possible. (While "modify KWin" is something I could do, that seems overkill.)

I think I could solve the problem with polling, but that would be very inefficient, and unless I polled very frequently, would cause the window's behavior to change while I was trying to work with it.

My current solution is to just apply the "all desktops" rule all of the time, and just unpin the windows when I'm on my laptop. I don't try to position it, as the position with an external monitor is likely to be off screen without an external monitor.

I'm using KDE 5.24.6 (at least that's what plasmashell --version and kwin --version report) on Kubuntu 22.04.1.

1 Answer 1

2

This is not possible with window rules. You can use KWin scripting instead. Relevant functions in the API are:

  • workspace.numScreens (get the current number of screens)
  • workspace.numberScreensChanged (do something when the number of screens changes)
  • workspace.clientAdded (do something when a new window opens)
  • workspace.clientList() (to iterate all windows)
  • client.windowType, client.caption, client.resourceClass (to identify the window by type, title and application)
  • workspace.sendClientToScreen(window, screen) (set screen assignment)
  • client.onAllDesktops (set pinned status)

Example: On startup, when the screen setup changes and when a new window opens, set all normal windows of application "dolphin" and title "potato" to screen 1 and pinned when two monitors are connected, and screen 0 and unpinned with one monitor:

function arrangeWindow(window) {
    if (window.normalWindow && window.resourceClass == "dolphin" && window.caption == "potato") {
        if (workspace.numScreens == 2) {
            workspace.sendClientToScreen(window, 1);
            window.onAllDesktops = true;
        } else if (workspace.numScreens == 1) {
            workspace.sendClientToScreen(window, 0);
            window.onAllDesktops= false;
        }
    }
}

function arrangeAllWindows() {
    workspace.clientList().forEach(arrangeWindow);
}

arrangeAllWindows();
workspace.numScreensChanged.connect(arrangeAllWindows);
workspace.clientAddded.connect(arrangeWindow);
3
  • I need to experiment some more, but I think this is I was looking for. I think I want workspace.clientAdded.connect(), which I believe will give me an opportunity to Do Things as new windows appear. Sep 28, 2022 at 15:59
  • Yes, that's correct. Sep 28, 2022 at 16:58
  • I updated my example accordingly. Sep 28, 2022 at 17:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .