Set specific screen as "primary" (Sway + greetd)

Hello,
I freshly installed EOS on my PC that uses two screens:

  • DP-3: 2k monitor I want to set as primary
  • HDMI-A-1: second monitor that is currently seen as the primary one.

When I boot the system I can see the startup logs scrolling on DP-3 only but when the display manager (greetd + ReGreet) runs I can only see the login screen on HDMI-A-1 as if it is being detected as the primary monitor.

In fact, I can see the following happening:

  1. Display manager login form appears only on HDMI-A-1.
  2. Screens positions are inverted (HDMI-A-1 is seen as the one on the right, same as DP-3 that is seen as the one on the left, but it should be the other way around).
  3. Workspaces are bound by default on the wrong screens (workspace 1 is bound to HDMI-A-1 and workspace 2 to DP-3).
  4. Sway uses gtklock configured as lock screen and when locking the system I can only see the lock screen on HDMI-A-1.

Regarding screens position, I managed configure the layout in the ~/.config/sway/config.d/output like so:

## Output configuration
#
# Example configuration:
#
output DP-3 resolution 2560x1440 position 0,0
output HDMI-A-1 resolution 1920x1080 position 2560,0
#
# You can get the names of your outputs by running: swaymsg -t get_outputs
#
# You can also bind workspaces 1,2,3 to specific outputs
#
workspace 1 output DP-3
workspace 2 output HDMI-A-1

However, I believe it’s just a workaround to the problem, because I can see screens in the right positions, but HDMI-A-1 is still considered the primary screen.

I know that there is no such thing as “primary” screen in Sway, and things like xrandr --output DP-3 --primary do not help me since I’m on Wayland.

Before installing EOS I had a plain Arch install where I also used Sway and Hyprland and where I also had the same problem.

I don’t know if this is something that happens on a lower level, because it seems like when Sway is running it’s already too late.

Can someone help me on this?

Thanks

Most likely your second monitor is connected just a hair faster than your 2K one at boot time, and thus becomes the de facto “first” display. I believe ReGreet just puts the form on whatever display is first.

To work around this, you could try this script someone added to this ReGreet GitHub issue:

Create the script somewhere available system-wide, for example /usr/local/bin.

/usr/local/bin/custom_regreet
#!/bin/bash
regreet & p=$!
# wait for regreet window to actually appear, then get focus
swaymsg -t subscribe '["window"]'
get_focused() {
    swaymsg -t get_tree | jq -r '.. | select(.focused? and .app_id=="apps.regreet")'
}
cur_focused=$(get_focused)
while [[ -z $cur_focused ]]; do
    cur_focused=$(get_focused)
done
swaymsg 'move output DP-3'
swaymsg '[app_id="apps.regreet"] focus'
# and wait for regreet's end
wait $p
swaymsg exit

Don’t forget to make the script executable.

chmod +x /usr/local/bin/custom_regreet

Optionally, you can use a monitor name instead of DP-3. Get the monitor name from the output of swaymsg -t get_outputs. This would be a fix if the monitor is getting an unexpected name assigned at boot (since the DP names are dynamic).

The line would look like this in that case:

[...]
swaymsg 'move output "Acer Technologies EB321HQU C 0x00000848"'
[...]

Obviously put your monitor there, not mine. :wink:

Once you have the custom script set up, change the Greetd Sway config to call your script instead of ReGreet.

/etc/greetd/sway.cfg
# Config for sway

exec "custom_regreet; swaymsg exit"

Log out, then when ReGreet comes up the form should be on the monitor you specified.


As for gtklock, you can use the -M argument to specify a monitor.

gtklock -M DP-3

It doesn’t take a monitor name like swaymsg does, you need to use the DP name in this case.

Update the Sway configs that call gtklock to use the -M argument.

The default config if you use a keybinding:

~/.config/sway/config.d/default
[...]
    # Lock screen
    bindsym $mod+f1 exec gtklock -M DP-3
[...]

The autostart config for the lockscreen triggered by suspend events:

~/.config/sway/config.d/autostart_applications
[...]
# Idle configuration
exec swayidle idlehint 1
exec_always swayidle -w before-sleep "gtklock -d -M DP-3"
[...]

The power menu script for triggering a lock from the Waybar:

~/.config/sway/scripts/power_menu.sh
[...]
case $SELECTION in
    *"󰌾 Lock"*)
        gtklock -M DP-3;;
[...]

I hope that helps, welcome to the community @belfed. :wave: