notice when the only screen changes
ClosedPublic

Authored by mart on Dec 21 2016, 3:49 PM.

Details

Summary

in a corner case that is used a lot, the internal laptop screen
gets automatically disabled when an external screen is connected.
the only QScreen* available from the QGuiApp gets recycled for the
new screen and there is no signal this switch occurred.

To work around this, as all the view get an expose event when this happen,
monitor the rename of the desktopview's qscreen and manage this separatedly
in the shell.

BUG:373880

Test Plan

connection and disconnecting an external screen to the laptop
both in the case of internal screen enabled or disabled

Diff Detail

Repository
R120 Plasma Workspace
Branch
phab/screenheuristic
Lint
No Linters Available
Unit
No Unit Test Coverage
mart updated this revision to Diff 9259.Dec 21 2016, 3:49 PM
mart retitled this revision from to notice when the only screen changes.
mart updated this object.
mart edited the test plan for this revision. (Show Details)
mart added a reviewer: Plasma.
Restricted Application added a project: Plasma. · View Herald TranscriptDec 21 2016, 3:49 PM
Restricted Application added a subscriber: plasma-devel. · View Herald Transcript

At a minimum this needs an upstream bug report with a description of exactly what is happening in both QPAs and in QPlatformWindow.

It's one thing to have a temporary workaround, it's another to deliberately write hacks from the start.

shell/desktopview.cpp
208

if you add this in setScreen you'll reduce a lot of false positive signals on initial connection/ startup

mart added a comment.Dec 23 2016, 10:47 AM

At a minimum this needs an upstream bug report with a description of exactly what is happening in both QPAs and in QPlatformWindow.

It's one thing to have a temporary workaround, it's another to deliberately write hacks from the start.

upstream bug https://bugreports.qt.io/browse/QTBUG-57785

mart added inline comments.Dec 23 2016, 10:58 AM
shell/desktopview.cpp
208

when the outputs get switched, setScreen won't happen, the expose event is the only place that is guaranteed to be triggered when this happen

I meant if you add this m_screenName *also* in set screen you'll reduce the number of false emits.

mart updated this revision to Diff 9326.Dec 23 2016, 11:27 AM
  • set m_screenName in setScreenToFollow()
mart updated this revision to Diff 9327.Dec 23 2016, 11:31 AM
  • remove useless debug
mart added a comment.Dec 23 2016, 4:34 PM

note, 5.8.5 is out the 27th, and this needs to be there, as it fixes a major issue.
if no further comments before then, tomorrow 24th I'll push

Oh! I think I now see why we have this bug.

We get a disconnect then connect, which from Qt5.5 goes:

Old Real Screen
Fake Screen
New Real Screen

You never get any signals when you're going to or from the fake screen (by design), but implicitly that means we miss a real change.

Is that the conclusion you had reached from debug?

mart added a comment.Dec 24 2016, 9:03 AM

Oh! I think I now see why we have this bug.

We get a disconnect then connect, which from Qt5.5 goes:

Old Real Screen
Fake Screen
New Real Screen

You never get any signals when you're going to or from the fake screen (by design), but implicitly that means we miss a real change.

Is that the conclusion you had reached from debug?

yes, I think what's happening, when the output switches the chain of events is
QXcbConnection::destroyScreen()
if (virtualDesktop->screens().count() == 1) {

// If there are no other screens on the same virtual desktop,
// then transform the physical screen into a fake screen.

then the new output is enabled:
QXcbConnection::updateScreens()
...
} else if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED) {
...
// Transform the fake screen into a physical screen
screen->setOutput(output.output, outputInfo.data());

and in this, no primaryScreenChanged, not screenAdded/screenRemoved got emitted, because the only qscreen pointer was massaged into being fake, then real again, but the instance is always there.

mart added a comment.Dec 24 2016, 9:11 AM

so, is this workaround ok with a message to remove when/if we depend from a qt with a proper solution to https://bugreports.qt.io/browse/QTBUG-57785 ?

davidedmundson accepted this revision.Dec 24 2016, 5:37 PM
davidedmundson added a reviewer: davidedmundson.
This revision is now accepted and ready to land.Dec 24 2016, 5:37 PM

so, is this workaround ok with a message to remove when/if we depend from a qt with a proper solution to https://bugreports.qt.io/browse/QTBUG-57785 ?

Based on this I still don't really get why we're not just using a native event filter on xrandr configure events as I asked on IRC. You might need to the processing in a Qt queued connection, but it'd still be a billion times simpler, and you could put the logic in screenpool, where it logically should be.

You said it was because of wayland, but that doesn't hold true , because even if the Qt wayland QPA does the same thing (and a quick grep for the word "fake" implies it doesn't) we're the ones that control what order the QPA gets output events so could avoid the situation anyway.

mart updated this revision to Diff 9352.Dec 24 2016, 7:17 PM
mart edited edge metadata.
  • use a native event filter over XCB_RANDR_NOTIFY
mart added a comment.Dec 24 2016, 7:18 PM

this is an attempt so use the native event filter approach (can't test yet, as i'm away and don't have an external screen handy)

will proper test tomorrow (too bad it's getting really tight for release:/)

mart added a comment.Dec 24 2016, 7:49 PM

so, is this workaround ok with a message to remove when/if we depend from a qt with a proper solution to https://bugreports.qt.io/browse/QTBUG-57785 ?

Based on this I still don't really get why we're not just using a native event filter on xrandr configure events as I asked on IRC. You might need to the processing in a Qt

yep, you are right, at the beginning i tought this was a qscreen problen on top of the xcb qpa, but it turns out is x11 specific, so the nativeeventfilter is more correct

mart added a comment.Dec 25 2016, 7:19 PM
In D3777#71267, @mart wrote:

yep, you are right, at the beginning i tought this was a qscreen problen on top of the xcb qpa, but it turns out is x11 specific, so the nativeeventfilter is more correct

there seems to be no XCB_RANDR_SCREEN_CHANGE_NOTIFY ever arriving in the event filter.
I'll go with the expose event path for 5.8.5, then will try to change it to the event filter again for 5.9/5.8.6

mart updated this revision to Diff 9355.Dec 25 2016, 7:23 PM
  • Revert "e a native event filter over XCB_RANDR_NOTIFY"
This revision was automatically updated to reflect the committed changes.
This revision was automatically updated to reflect the committed changes.