Come up with a solution for displaying QQC2 elements in Plasma
Closed, DuplicatePublic

Description

When you use a QQC2 or Kirigami element in Plasma, it gets the desktop style.

This is desirable if the thing you used it in is a dialog window, because it makes the dialog window look native.

If the thing you used it in is a Plasma popup/widget/panel/whatever, then it gets the desktop style which makes it look wrong. It can even cause bugs when, for example, you use a dark plasma theme and a light apps theme, because the QQC2 element will respect the colors from the color scheme, not the colors from the Plasma theme. You end up with something like this:

Whoops. We just got a bug report on this: https://bugs.kde.org/show_bug.cgi?id=422684

At this point you're probably be tempted to say, "Duh, don't use Kirigami or QQC2 elements in Plasma, use the PlasmaComponents/PlasmaExtras version."

But this presents a problem: we're stuck maintaining a second toolkit, forever, which increases the maintenance burden and amount of buggyness throughout our software. And if something nice gets added to Kirigami (such as PlaceholderMessage, from the above image), you can't use it in Plasma unless you create a PlasmaExtras version, which again doubles your maintenance burden for that item and introduces a new issue that they can drift out of sync with one another over time. This is constantly happening with PlasmaComponents2, PlasmaComponents3, and QQC2 stuff, and it's really annoying.

I think it would be good if we could come up with a way for QQC2 and Kirigami controls to use the Plasma style when displayed in a non-windowed Plasma UI (e.g. a widget, panel pop-up, etc). If we did this, we would have a path forward for sunsetting PlasmaComponents, or turning it into a simple style bridge with no logic in it.

ngraham created this task.Jun 9 2020, 3:35 PM
ngraham triaged this task as Normal priority.
ngraham renamed this task from Come up with a solution for QQC2 elements in Plasma to Come up with a solution for displaying QQC2 elements in Plasma.
ngraham updated the task description. (Show Details)Jun 9 2020, 3:37 PM
ngraham claimed this task.Jun 9 2020, 5:46 PM
ngraham updated the task description. (Show Details)Jun 9 2020, 5:49 PM

Related to but necessarily a duplicate of T11558: kill plasma components in favour of qqc2-desktop-style. If we do T11558, we won't have to do this, but we can do this without having to do T11558.

mart added a subscriber: mart.Jun 11 2020, 1:12 PM

feasible technical solutions at the moment are

  • QQmlAbstractUrlInterceptor based solution: kinda error prone but easy to do
  • configuration windows in a separate process: quite complicated and error prone, would take a year to do
  • having config windows with the plasma style

a requitrement though is that the custom weird plasma styles from the store continue to work

I wouldn't be in favor of making config windows have the plasma style. In other respect they would match the desktop style (e.g. titlebar) so that would just be weird IMO.

One idea I've been throwing around recently is using the Plasma theme for apps too, by making the QStyle load Plasma theme SVGs. This would eliminate the potential problem of Plasma dialogs having a different appearance from apps, because all of them would be using the same theme in the first place. It would also allow a single theme to apply to the entire system, producing a major consistency win, and these newly-all-encompassing systemwide Plasma themes are share-able via GHNS, which is not currently possible using binary QStyle widgets themes. In so doing, the Breeze QStyle would be essentially transformed into a theme engine. Alternatively I suppose we would fork it into a new one, or write a new one.

If we did this, then we could port all of Plasma to use QQC2 rather than PlasmaComponents3 and load the Plasma style using qqc2-desktop-style or some other method, eventually winding up with only two UI libraries to maintain (QWidgets and QQC2+Kirigami, with no PC2 and PC3) and only one UI style to maintain (the Plasma style).

Thoughts?

Well Qstyle is had to make thus stuff like kvantumn. So this will help quite a bit

nicolasfella moved this task from Backlog to Needs Input on the KF6 board.Nov 22 2020, 12:12 AM
davidre added a subscriber: davidre.EditedDec 11 2020, 10:21 AM

I am looking into what Qt calls "compile time selection" with Qt6. On the first look it looks exactly what we had with manually importing PlasmaComponents.

Consider:

import QtQuick
import QtQuick.Controls
Row {
    Button{text:"Button"}
    Button1{text:"Material"}
    Button2{text:"Universal"}
}
------
Button1.qml:
import QtQuick.Controls.Material
Button {}
----
Button2.qml
import QtQuick.Controls.Universal
Button {}

this results in:

A bit more interesting if if we also import Controls in addition to the style in Button1.qml:

import QtQuick.Controls
import QtQuick.Controls.Material
Button {}

Which has the same result

Even more interesting is that the same happens if Controls is imported after Material:

import QtQuick.Controls.Material
import QtQuick.Controls
Button {}

Now to the really interesting things can we influence the style also in a file we are including?
The main file looks this now:

import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Fusion
Row {
    Button{text:"Button"}
    Button1{text:"SubFile"}
    Button2{text:"Universal"}
}

And Button1.qml reads now only:

import QtQuick.Controls
Button {}


That didn't work, ...
But if the order of the imports is switched, the Button in the other file will follow the style!

import QtQuick
import QtQuick.Controls.Fusion
import QtQuick.Controls
Row {
    Button{text:"Button"}
    Button1{text:"SubFile"}
    Button2{text:"Universal"}
}

But we mostly use namespace imports for Quick Controls, so it surely doesn't work when using it in a namespace because now you would have QQC.Button and the plain Button comes from fusion? No, it still works:
Consider

import QtQuick
import QtQuick.Controls.Fusion
import QtQuick.Controls as QQC
Row {
    QQC.Button{text:"Button"}
    Button1{text:"SubFile"}
    Button2{text:"Universal"}
}

(Button1.qml unchanged for now from above with only importing Controls)

The same applies of course if we import it to the same namespace in both files. I.e. Button1.qml now reads

import QtQuick.Controls as QQC
QQC2.Button {}


What is more interesting of course is what happens with differing namespace names

import QtQuick.Controls as Controls
Controls.Button {}


Or without a namespace in the top-level file (See third to last snippet) and the namespace as above in the sub file:

\o/

So it looks to me that if we would import the Plasma style once in the root file before QtQuick.Controls we could happily use Components that make use of Controls.
Or the other way around for ConfigViews.

Of course that needs further testing with a with multiple engines, etc..

Very interesting. Great investigation! That could really be nice if this works out for our use case.

ognarb added a subscriber: ognarb.Dec 15 2020, 5:57 PM

Very interesting. Great investigation! That could really be nice if this works out for our use case.

Finally, we can say "Qt6 will fix it™" :D