Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disabling/enabling monitor does not call RandRFunc #825

Closed
entropic77 opened this issue Feb 18, 2023 · 8 comments · Fixed by #826
Closed

Disabling/enabling monitor does not call RandRFunc #825

entropic77 opened this issue Feb 18, 2023 · 8 comments · Fixed by #826
Assignees
Labels
type:bug Something's broken!
Milestone

Comments

@entropic77
Copy link

Upfront Information

  • Fvwm3 version: fvwm3 1.0.7 (1.0.6a-8-g2327aac1)

  • Linux distribution or BSD name/version: Debian 11.6 Bullseye

  • Platform (run: uname -sp): Linux unknown

Expected Behaviour

I expected RandRFunc to trigger when connecting/disconnecting a monitor. Basically on xrandr --output HDMI-1 --off and xrandr --output HDMI-1 --auto.

Actual Behaviour

The RandRFunc is not triggered.

FvwmEvent's monitor_enabled/monitor_enabled functions are also not triggered.

RandRFunc is called correctly on resolution and position change (for example xrandr --output HDMI-1 --right-of DP-1)

Steps to Reproduce

I'm using this minimal configuration file:

BugOpts DebugRandR true

DestroyFunc RandRFunc
AddToFunc   RandRFunc
+ I Echo "randrfunc called"

Then executing xrandr --output HDMI-1 --auto followed by xrandr --output HDMI-1 --off gives the following output in the log, but "randrfunc called" is not logged.

[1676715323.394479] monitor_output_change: monitor_output_change: outputs have changed
[1676715323.397734] monitor_update_ewmh: monitor debug...
[1676715323.397788] monitor_dump_state: Monitor Debug
[1676715323.397808] monitor_dump_state:         number of outputs: 2
[1676715323.397833] monitor_dump_state:         Name:   DP-1
        Disabled:       false
        Is Primary:     yes
        Is Current:     yes
        Is Previous:    yes
        Output: 68
        Coords: {x: 0, y: 0, w: 2560, h: 1440}
        VirtScr: {
                VxMax: 0, VyMax: 0, Vx: 0, Vy: 0
                EdgeScrollX: 0, EdgeScrollY: 0
                CurrentDesk: 0
                CurrentPage: {x: 0, y: 0}
                MyDisplayWidth: 2560, MyDisplayHeight: 1440
        }
        Desktops:       yes
        Flags:global

[1676715323.397884] monitor_dump_state:         Name:   HDMI-1
        Disabled:       false
        Is Primary:     no
        Is Current:     no
        Is Previous:    no
        Output: 71
        Coords: {x: 0, y: 0, w: 1920, h: 1080}
        VirtScr: {
                VxMax: 0, VyMax: 0, Vx: 0, Vy: 0
                EdgeScrollX: 0, EdgeScrollY: 0
                CurrentDesk: 0
                CurrentPage: {x: 0, y: 0}
                MyDisplayWidth: 2560, MyDisplayHeight: 1440
        }
        Desktops:       yes
        Flags:global

[1676715323.417977] ewmh_ComputeAndSetWorkArea: monitor 'DP-1': {l: 0, r: 0, t: 0, b: 0} {x: 0, y: 0, w: 2560, h: 1440}
[1676715323.419066] ewmh_ComputeAndSetWorkArea: monitor 'HDMI-1': {l: 0, r: 0, t: 0, b: 0} {x: 0, y: 0, w: 1920, h: 1080}
[1676715329.950613] monitor_output_change: monitor_output_change: outputs have changed
[1676715329.954508] monitor_update_ewmh: monitor debug...
[1676715329.954562] monitor_dump_state: Monitor Debug
[1676715329.954579] monitor_dump_state:         number of outputs: 2
[1676715329.954593] monitor_dump_state:         Name:   DP-1
        Disabled:       false
        Is Primary:     yes
        Is Current:     yes
        Is Previous:    yes
        Output: 68
        Coords: {x: 0, y: 0, w: 2560, h: 1440}
        VirtScr: {
                VxMax: 0, VyMax: 0, Vx: 0, Vy: 0
                EdgeScrollX: 0, EdgeScrollY: 0
                CurrentDesk: 0
                CurrentPage: {x: 0, y: 0}
                MyDisplayWidth: 2560, MyDisplayHeight: 1440
        }
        Desktops:       yes
        Flags:global

[1676715329.954656] monitor_dump_state:         Name:   HDMI-1
        Disabled:       false
        Is Primary:     no
        Is Current:     no
        Is Previous:    no
        Output: 71
        Coords: {x: 0, y: 0, w: 1920, h: 1080}
        VirtScr: {
                VxMax: 0, VyMax: 0, Vx: 0, Vy: 0
                EdgeScrollX: 0, EdgeScrollY: 0
                CurrentDesk: 0
                CurrentPage: {x: 0, y: 0}
                MyDisplayWidth: 2560, MyDisplayHeight: 1440
        }
        Desktops:       yes
        Flags:global

[1676715329.956858] ewmh_ComputeAndSetWorkArea: monitor 'DP-1': {l: 0, r: 0, t: 0, b: 0} {x: 0, y: 0, w: 2560, h: 1440}
[1676715329.957642] ewmh_ComputeAndSetWorkArea: monitor 'HDMI-1': {l: 0, r: 0, t: 0, b: 0} {x: 0, y: 0, w: 1920, h: 1080}
@entropic77 entropic77 added the type:bug Something's broken! label Feb 18, 2023
@ThomasAdam
Copy link
Member

@entropic77

Yes. I'm sure when I last looked into this, using xrandr --off isn't the same thing as yanking an HDMI cable out the back of the monitor...

@entropic77
Copy link
Author

Ah, ok. I was trying to debug a multimonitor-problem and thought it would be easier to run an xrandr-command than to reach under the table to yank the cable.

After actually trying to unplug/replug the cable I should maybe describe the original problem I had:

The problem I'm trying to solve is to automatically move FvwmButtons to the currently primary monitor.

  • If the external monitor is not plugged in, the laptop's monitor is primary
  • If the external monitor is plugged in, this monitor is primary

I'm using autorandr to reconfigure which monitor is primary, based on if the external monitor is plugged in or not.

So in summary the actual issue is that RandRFunc is not called when autorandr reconfigures the screens, including changing the primary screen. So if fvwm can't do this I might have to find another way. Or perhaps functionality to detect randr's changing of primary screen could be implemented in fvwm somehow?

@ThomasAdam
Copy link
Member

I'll look into it.

@ThomasAdam ThomasAdam added this to FVWM3 Feb 18, 2023
@github-project-automation github-project-automation bot moved this to To do in FVWM3 Feb 18, 2023
@ThomasAdam ThomasAdam added this to the 1.0.7 milestone Feb 18, 2023
@ThomasAdam ThomasAdam self-assigned this Feb 18, 2023
ThomasAdam added a commit that referenced this issue Feb 18, 2023
Track which monitors hold the current primary bit, and the monitor which
used to have it.

This is sometimes useful to infer when the primary status of a monitor
has changed, and which monitor it is now, and which monitor it used to
be.

For example:

    DestroyFunc RandRFunc
    AddToFunc   RandRFunc
    + I Echo "Primary is: $[monitor.primary], previous: $[monitor.prev_primary]"

Fixes #825
@ThomasAdam
Copy link
Member

@entropic77

Have a look at the ta/add-prev-primary branch, which now introduces a new variable $[monitor.prev_primary] which you can use to ascertain the name of a previous monitor which was marked as primary. Hence:

DestroyFunc RandRFunc
DestroyFunc RandRFunc
+ I Echo "Primary is: $[monitor.primary], previous: $[monitor.prev_primary]"

To your earlier observations, I was remembering correctly. If you use xrandr to turn off one of your monitors, have a look at the output from xrandr -- it will still show as connected.

@entropic77
Copy link
Author

Your patch works fine when executing the xrandr-commands manually. But annoyingly enough not when letting autorandr handle the monitors.

I think I traced autorandr's behaviour to the following. At least I get the same end result:

(HDMI-1 is my external monitor and DP-1 internal)

  • connect cable
  • xrandr --output HDMI-1 --right-of DP-1 --primary --auto
  • disconnect cable
  • xrandr --output HDMI-1 --off I think this is the culprit
  • xrandr --output DP-1 --primary

End result: RandrFunc is not called when setting primary in the last step. Maybe because the HDMI monitor has been turned off and fvwm cannot keep track of it anymore?

These steps works as expected. And will cause RandRFunc to be called when setting primary:

  • connect cable
  • xrandr --output HDMI-1 --right-of DP-1 --primary --auto
  • disconnect cable
  • xrandr --output DP-1 --primary

@ThomasAdam
Copy link
Member

End result: RandrFunc is not called when setting primary in the last step. Maybe because the HDMI monitor has been turned off and fvwm cannot keep track of it anymore?

Yup.

@entropic77
Copy link
Author

Ok, but how about ignoring which other monitor was primary, and just check if the monitor in question was not primary. Like this:

diff --git a/fvwm/events.c b/fvwm/events.c
index 1ae159fa..10218213 100644
--- a/fvwm/events.c
+++ b/fvwm/events.c
@@ -1855,12 +1855,7 @@ monitor_emit_broadcast(void)
 		}
 
 		if (m->flags & MONITOR_PRIMARY) {
-			struct monitor *pm = m, *mnew;
-
-			if ((mnew = monitor_by_last_primary()) == NULL)
-				break;
-
-			if (pm != mnew) {
+			if (m->flags & MONITOR_PRIMARY && !m->was_primary) {
 				execute_function_override_window(
 				    NULL, NULL, randrfunc, NULL, 0, NULL);
 			}

@ThomasAdam
Copy link
Member

@entropic77

Perhaps. This is already an ugly hack as it is. At least my version mirrors other variables where there's a previous state.

ThomasAdam added a commit that referenced this issue Mar 14, 2023
Track which monitors hold the current primary bit, and the monitor which
used to have it.

This is sometimes useful to infer when the primary status of a monitor
has changed, and which monitor it is now, and which monitor it used to
be.

For example:

    DestroyFunc RandRFunc
    AddToFunc   RandRFunc
    + I Echo "Primary is: $[monitor.primary], previous: $[monitor.prev_primary]"

Fixes #825
@github-project-automation github-project-automation bot moved this from To do to Done in FVWM3 Mar 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:bug Something's broken!
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants