dedean16 / kwin-swapdesktop

A KWin script that provides two shortcuts to swap the current desktop with the next/previous one.
GNU General Public License v3.0
3 stars 1 forks source link

Dynamic Vertical Desktop Grid: One Desktop Per Row #1

Open r0skar opened 5 months ago

r0skar commented 5 months ago

Hei - Do you think its feasible to add an option to force every new desktop in its own grid row? Basically keep the same behavior as is now, but have the desktops arranged vertically. I looked at the Scripting API and the desktopGridWidth is marked as readon-only - but maybe there is another way?

dedean16 commented 1 month ago

Nice idea! I don't think that's possible through the API directly, as indeed desktopGridWidth is read-only. It should be possible through dbus. E.g. this command sets the number of rows to 4: qdbus org.kde.KWin /VirtualDesktopManager org.kde.KWin.VirtualDesktopManager.rows 4 but I haven't figured out yet how to set properties from a KWin script with callDBus.

r0skar commented 1 month ago

Yeah i got down deep into that rabbit hole. AFAIK the main problem with callDBus is how kwin is transforming the array of arguments. I have since then changed my approach a little and created a standalone bin that watches for virtual desktop changes. Whenever a desktop is added/removed, it will update the row count. This keeps them in synch and - so far - works great with any "native" virtual desktop plugins too.

For any else searching, here is my script (note: its really just a hack for my specific usecase):

#!/usr/bin/env python3
# This program keeps the virtual desktop row count in synch with
# the amount of virtual desktops. This means that each virtual desktop
# will always be in its own row. Effectively, enabling dynamic vertical desktops.

import dbus
import dbus.mainloop.glib
from gi.repository import GLib
import subprocess

def update_desktop_rows():
    bus = dbus.SessionBus()
    desktop_manager = bus.get_object('org.kde.KWin', '/VirtualDesktopManager')
    props_iface = dbus.Interface(desktop_manager, 'org.freedesktop.DBus.Properties')
    desktop_count = props_iface.Get('org.kde.KWin.VirtualDesktopManager', 'count')
    subprocess.run([
        'busctl', '--user', 'set-property', 'org.kde.KWin', '/VirtualDesktopManager',
        'org.kde.KWin.VirtualDesktopManager', 'rows', 'u', str(desktop_count)
    ])

def on_desktop_count_changed(*args):
    update_desktop_rows()

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
bus.add_signal_receiver(
    on_desktop_count_changed,
    signal_name='countChanged',
    dbus_interface='org.kde.KWin.VirtualDesktopManager'
)

update_desktop_rows()  # Initial update
loop = GLib.MainLoop()
loop.run()

Add this to autostart.