xrandr backend: "invalid arguments" error
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
disper |
Fix Released
|
Medium
|
wvengen |
Bug Description
Okay, sorry if this report is going to be a little vague, but it happened in the past, yet I can't reproduce it again.
Basically, due to another issue I had, I had to use xrandr rather than disper to setup my second monitor for a presentation. But after it, disper would stop working, XRRSetScreenCon
Anyway. I decided to track this down and see what was xrandr doing differently from disper. Xrandr was issuing XRRSetScreenCon
In the end, I found that the reason disper had tagged both pipes as "changed" was this piece of code (_arrange_outputs in xrandr/core.py):
# Normalize the postions so to the upper left cornor of all outputs
# is at 0,0
min_x = 32768
min_y = 32768
for output in self.get_outputs():
if output._mode == None: continue
if output._x < min_x: min_x = output._x
if output._y < min_y: min_y = output._y
for output in self.get_outputs():
if output._mode == None: continue
min_x and min_y were both zero, yet disper was tagging all the connected pipes as "changed".
Can I recommend that you encapsulate that last "for" in an "if", like this?
if min_x != 0 or min_y != 0:
for output in self.get_outputs():
if output._mode == None: continue
I do not know if it would really fix whatever caused the bug, but it would at least prevent pipes that were not changed from being marked as modified. Maybe the real bug-fix is to skip "not changed" outputs? Because that's what a similar loop is doing at the beginning of the function (it reads: " Skip not changed and not used outputs")
PS: Also, this function has a redundant line:
if not relative or not relative._mode:
Because the set of "changed position" is done anyway later on, in line 873.
I attach a diff with both suggestions in case the text isn't clear (disper version 0.3.0).
Changed in disper: | |
milestone: | none → 0.3.1 |
Changed in disper: | |
status: | Fix Committed → Fix Released |
I just realized that your xrandr backend is more or less a "translation" for the code of xrandr. If so, then indeed xrandr does a " if (min_x || min_y)" before iterating pipes and setting their "changed position" flag. So my proposed patch is most likely the correct solution.
Though, you are missing a "continue" in the case where the monitor isn't relative. Your backend reads like this:
if not relative or not relative._mode:
output. _x = 0
output. _y = 0
output. _changes = output._changes | xrandr. CHANGES_ POSITION RELATION_ LEFT_OF:
if output._relation == xrandr.
Whereas xrandr's code reads more like this:
if not relative or not relative._mode:
output. _x = 0
output. _y = 0
output. _changes = output._changes | xrandr. CHANGES_ POSITION
continue RELATION_ LEFT_OF:
if output._relation == xrandr.
Well, you could solve this by adding the "continue" line, or just by removing the "changes" line (as patch does) AND changing the next if for a "elif". You can decide which one to apply.