RFC: Split KWindowSystem into KX11 and KHighLevelWindowStuff
Open, Needs TriagePublic

Description

KWindowSystem is a mix of two things:

Very thorough low level X11 bindings for billions of things.
High level abstraction with multiple backends round a few things.


We present this as though it's a high level abstraction round billions of things, and then they subsequently don't work.
The API doesn't fit, so for Wayland we end up writing two sets of code for anything substantial anyway.

Wayland is also done in a complex way to accommodate the problem of using kwayland. Currently we have an in-tree plugin in kwindowsystem which in turn redirects to an out of tree plugin kwayland-integration which is released with plasma. That's a mess.

Some of the things we're using it for exist in Qt. Like
KWindowSystem::activatewindow is literally the same as
QWindow::activate(), unminimize is the same as setWindowState() etc.

It needs some revisiting, probably quite early as pushing some things
to Qt would help fix things

Current Proposal:

  • split KWindowSystem into KX11Stuff Net*, KSelection*, KStartup*, KXMessages, KWindowInfo, KWindowSystem.
  • KAwesomeHighLevelWindowStuff which has the KWindowEffects with the current backends. Code will call into KX11/KWayland/Whatever respectively.

KKeyServer I don't know? It's XKB relevant, and we still use that on wayland.


I've tried to analyse the current usages of everything except Plasma.

frameworks

KIO:

kcookieserver -> setMainWindow (==setTransientPArent)
kcookiewin -> setMainWindow
kpasswrdserver -> watch windowRemoved (won't work on wayland - also why?)
krun -> currentDesktop
krun -> startupinfo

knotifications:

  • window added / window removed (won't work on wayland!!!)

ktextedit:

  • activateWindow

    kwallet:
    • allowExternalProcessWindowActivation....
    • setMainWindow
    • setOnAllDesktops
    • forceActiveWidnow

Current Usage of KWindowSystem (excluding Plasma)

applications:

dolphin - activate window

dolphin -> isplatform wayland

(why?? - lack of raise request)

kate -> activate window

kate -> set on all desktops? (no idea why?)
current desktop -> for activating the "right" one

kdialog -> set main window

keditbookmarks->activate

konq -> startup ID (legit case)
konq -> unminize

konsole -> compositingActive
konsole -> getCurrentDesktop

yakuake -> isX11
yakuake -> detect work area changed (== QScreen::availableGeom)

kwordquiz -> unminimize

various kipi-plugins-> unminize

KRuler -> set window type

-> set keep above

okular -> get current dekstop again for DBus activation - should
probably be shared

-> forceActivate

spectacle -> isX11

-> updating the title!!!!! !???!!
-> compositing active

dragonplayer -> forceActivate

juk -> forceActivate

-> workArea

kget -> forceActivate

krdc -> isX11

ktp -> forceActivate

kgpg -> setOnDesktop

print-manager -> forceActivate

-> updating the title!!!!! !???!!

It's not that wtf like it reads at first. It doesn't read its own name property but of another window that is being screenshotted

dfaure added a subscriber: dfaure.Dec 22 2019, 7:33 PM

kpasswrdserver -> watch windowRemoved (won't work on wayland - also why?)

Password requests are associated with a window ID. While a (non-modal) password dialog is shown, if the window goes away (e.g. user closes webbrowser window) the dialog is deleted. No point in asking a password for a window that was closed meanwhile.

Why can't wayland offer a way to be informed that a window has been closed? How can wayland be the solution to all problems if it doesn't have basic things like that? :-)

It doesn't read its own name property but of another window that is being screenshotted

That makes more sense - I like how spectacle already has the multiple backends route and this is already encapsulated.

kpasswdserver
How can wayland be the solution to all problems if it doesn't have basic things like that? :-)

Because it (deliberately) lacks the even more basic thing... knowing about windows from any other client.

The maximum one can do is set a transient parent, but even that is a laboured process with auth-tokens and a second communication channel. With the existing spec there, at most you can set that once, but there's no update signals.

We can do solutions at a plasma level, but it might prove easier to refactor this to work in other ways.

Good thing to tackle this. The separate kwayland-integration plugin always felt weird to me. I currently don't have an overview on KWindowSystem so I can't really comment on your analysis and proposed split but if you think it should be done like that let's move forward with it. What are the next steps?

Without knowledge on how such splits were done in the past could we start by moving code into separate repos in workspace and make Plasma depend on this incrementally instead of the functionality in KWindowSystem? And then move these repos back into Frameworks each as separate framework after everything has been split up.

We wanted to split up KWayland and move the server-part into Plasma to be able to iterate faster on KWin. Is this something to consider for the task here?

zzag added a subscriber: zzag.Jan 7 2020, 4:41 PM
zzag added a comment.Jan 7 2020, 8:29 PM

The separate kwayland-integration plugin always felt weird to me.

KWindowSystem is a tier 1 framework so it cannot use KWayland directly.

@octofox
That's the current state for KF5, but do you agree it's a weird thing that we want to get away from?

The only things in tier 2 that currently use KWindowSystem are:

  • KCrash (for something that's X11 specific anyway)
  • KNotification for SNIs (which I don't have a complete plan for)

If we can resolve the last one in a nice way, then we can bump KWindowSystem (or KHighLevelWindowStuff) up a tier and it simplifies everything.

What are the next steps?

Next step at this phase are trying to identify which KWindowSystem things:

  • are actually used in places where abstraction makes sense
  • actually can be abstracted
  • if there's anything fundamental that should really just be in Qt
  • porting things, where possible, to use Qt API instead of KWindowSystem (like I did in D26159)

KNotification for SNIs (which I don't have a complete plan for)

That would be resolved if my plan to kill KSystemTrayItem in favor of QSystemTrayIcon works out

zzag added a comment.Jan 8 2020, 9:44 AM

@octofox
That's the current state for KF5, but do you agree it's a weird thing that we want to get away from?

Yes, having two wayland platform plugins for kwindowsystem seems to be weird, but unfortunately there is no other way around it given current kf constraints. Also, this maybe doesn't add anything to the discussion, but the in-tree plugin doesn't redirect anything. KWindowSystem has an in-tree wayland plugin because KWindowSystemPrivateDummy::compositiveActive() always returns false, but we want it to return true on wayland. It just so happens that KF5WindowSystemKWaylandPlugin (from kwayland-integratin) comes before KF5WindowSystemWaylandPlugin (from kwindowsytem) when QDir::entryList() enumerates entries in plugin-dir/kf5/org.kde.kwindowsystem.platforms/.

I can't comment on the split thing because I haven't given any thought to it yet. But perhaps it will be worth to have KX11 or something.

ervin moved this task from Needs Input to In Discussion on the KF6 board.Mar 27 2021, 3:51 PM

Sprint notes:

People are on board with the proposal. There's a better way to phrase it:

Handling Your Windows - > should be a high level multi-platform code - we provide only what's missing from Qt
Handling other program's windows -> should be in relevant low level frameworks and not abstracted as it doesn't work


Solid subtasks:

  • KKeyServer - the two usages in krita / wacom KCM can be ported to KGuiAddons ksequencerecorder

Remaining usage is actually X11 only.

  • We want a high level abstraction about startupIds that wraps KStartupInfo and works on wayland. This will have a lot of fall out

We can start this now. Need to check with @apol on this.

  • KXMessages can be made private, it's only used internally and a dead feature in kwin/kstart
  • we should deprecate

KWindowEffects::windowSizes ( const QList< WId > & ids )

  • KWindowEffects - should use QWindow* instead of WId

(after splitting)

  • highlightWindows doesn't belong in this class, it's not about applying an effect to your window, lets make a new approach in kwin and taskmanager (that works on wayland)
ervin moved this task from In Discussion to Needs Splitting on the KF6 board.Mar 28 2021, 12:22 PM
zzag added a comment.May 7 2021, 8:53 PM

KXMessages can be made private, it's only used internally and a dead feature in kwin/kstart

Can we remove it in kwin now?

KWindowEffects - should use QWindow* instead of WId

Done.

highlightWindows doesn't belong in this class, it's not about applying an effect to your window, lets make a new approach in kwin and taskmanager (that works on wayland)

Done

Something we could relatively easily do now is move (i.e. copy+deprecate) some of the X11-specific functions in the KWindowSystem class to a new KX11Extras class

Candidates could be e.g. compositingActive, forceActiveWindow, activeWindow, stackingOrder, etc

Another thing would be "renaming" KWindowInfo to e.g. KX11WindowInfo

I went through the users of KWindowInfo. The vast majority of usages in apps (i.e. not Plasma) is for virtual desktop info. That's only implemented on X11 anyway

KKeyServer -> KX11Keys or KXkbKeys ?