Display (with Nexdock / ext display) configuration

I’ve 2 questions (maybe both are related - How to save configuration over multiple plug in / out)

  1. How can I make external display primary when connected
  2. How can I save external display to use 150% scaling?

[EDIT]: Clarification: I know how to do it from settings but I’m asking how to make it permanent

[EDIT2]: there is /usr/share/phosh/phoc.ini which can be updated it seems, I’ll try few edits to this file over weekend. https://wiki.mobian-project.org/doku.php?id=tweaks (scale the screen section)

1 Like

Are you asking how to automatically set the external display as primary and change the scale, or just how to do it at all?

If it’s the latter, you can go to settings app, and under display there is an option to set main display. Underneath that there is a way to select which display you want to configure (Nexdock appears as “Unknown 13.3”) and then select the scaling you want. If you have the NexDock 360 you can even choose the orientation of the screen too portrait mode so you can use it more like a tablet.

Just updated op but ya I know how to do it from settings (that’s how I’m doing it now) just annoying to do it every time.

1 Like

Until it gets properly integrated in the DE, you can use something like https://git.sr.ht/~emersion/kanshi to automatically configure displays on hotplug as desired. kanshi itself is packaged in byzantium.

2 Likes

Poor man’s kanshi:

  • make a udev rule that matches the display / any external display
  • run a script run from that rule that sets the configuration for the display that had been connected

I tried it a while a ago and didn’t get it working completely. Lost focus on that, but it has been fun to learn some udev stuff.

2 Likes

Is there info about how to use kanshi?
I simply wrote

profile default {
        output DP-1 enable scale 1.5
}

But I don’t think that is correct because running kanshi just mentions no profile matched
BTW I ran:

purism@pureos:~$ for p in /sys/class/drm/*/status; do con=${p%/status}; echo -n "${con#*/card?-}: "; cat $p; done
DSI-1: connected
DP-1: connected

I’ve also tried XWAYLAND<num> instead of DP-1

Trying to make this work but it’s not really working.
I’ve tried rule to be something like:
SUBSYSTEM=="drm", ACTION=="add", RUN+="/bin/add_nexdock.sh"

Script itself is:

#!/usr/bin/bash
echo "Start Nexdock added at $(date)" >>/tmp/scripts.log 
export DISPLAY=:0.0 
xrandr --output DP-1 --mode 1280x720 --rate 60 
echo "Done Nexdock added at $(date)" >>/tmp/scripts.log

But /tmp/scripts.log itself is not generated so I guess rule is not triggered., maybe I need more details to rule?

Also I should mention: I don’ t think xrandr is correct way of changing resolution in this case

purism@pureos:~$ xrandr --output DP-1
warning: output DP-1 not found; ignoring
purism@pureos:~$ xrandr --output XWAYLAND10

xrandr responds to XWAYLAND<num> but this value changes upon every hot-plug. And xrandr can never find mode which is not current (see below)

purism@pureos:~$ xrandr --output XWAYLAND10 --mode 1280x720
purism@pureos:~$ xrandr --output XWAYLAND10 --mode 1920x1080
xrandr: cannot find mode 1920x1080
1 Like

I haven’t tried kanshi yet (I plan to, in the coming week), but their page says that a profile is matched based on the presence of all outputs described in a profile.

So if a profile only has DP-1, it means that it will match only when you have DP-1 present — which will not happen since the L5 always has at the very least its internal display, in addition to DP-1…

So you would need a profile with both the DP-1 and the DSI-1 or whatever the internal display is called, and that would match the situation where you plug in an external display.

All the above with the caveat that I have yet to test it…

1 Like

I reviewed what I did:

  • for wayland it is wlr-randr which helps to configure the screens, e.g. wlr-randr --output DSI-1 --pos 1536,0 --output DP-1 --pos 0,0 --scale 1.25
  • I remember that my rules fired several times which led to a lot of problems. Tried to solve that by triggering a systemd .service from the udev rule. It didn’t work with the then actual version of systemd/udev. I used a version from backports which solved the problem. (250 I think).
  • in my latest attempt I used DEVPATH=="/devices/platform/soc@0/32c00000.bus/32e00000.display-controller/drm/card2/card2-DP-1", ACTION=="change", TAG+="systemd", ENV{SYSTEMD_USER_WANTS}="autowlrrandr.service" which as I beliefe enabled the autowlrrandr.service defined for my user.
  • the script I ran had to wait for the connection to settle - waiting is not allowed in udev, because a running script blocks any further processing of the udev rules. Another reason to use at (compatible with e.g. pmOS) or a systemd service
  • to debug udev rules it helped a lot to use logger to write to the journal like in RUN+="/usr/bin/logger -t 42-librem5-external-screen.rules status=$attr{card2-DP-1/status} enabled=$attr{card2-DP-1/enabled}",

If you’d like I’ll upload what I have to a repository.

Update: poor man’s kanshi

1 Like

This profile means “when there’s only DP-1 screen connected, enable it with scale 1.5”. That’s unlikely what you want to do, because you can’t disconnect the internal DSI-1 screen.

1 Like

I see, thanks
Following worked:

purism@pureos:~$ cat .config/kanshi/config 
profile default { 
	output DSI-1 enable 
	output DP-1 enable scale 1.5
}
1 Like

Thanks going to try this as well (gonna be lazy for few days cause kanshi worked but I’ll report back)

ok here’s what I did so far. I created my kanshi config:

profile nexdock {
 output DSI-1 
 output DP-1 mode 1920x1080@60Hz scale 1.1
}

profile default {
 output DSI-1
}

Then a systemd user unit file located at ~/.config/systemd/user/kanshi.service

[Unit]
Description=Kanshi display daemon

[Service]
ExecStart=/usr/bin/kanshi
Type=simple

[Install]
WantedBy=multi-user.target

then:

systemctl --user daemon-reload
systemctl --user enable --now kanshi

so now kanshi loads when I login (or when the system starts? whenever systemd user units are loaded anyway), no fiddling with udev rules. No idea how this will behave when I connect it to another display that is NOT my nexdock, either…

1 Like

this works nicely
Thanks

1 Like

I followed your steps, but kanshi does not work unless I activate it manually with a terminal command or a .desktop file that executes /usr/bin/kanshi. The only thing that I did differently was to set the kanshi config file to turn off my Librem 5 display when connected to an external display. I also ended up setting the scale to 1.5 (150%) and not specifying the refresh rate.

This is what my ~/.config/kanshi/config looks like:

profile docked {
        output DSI-1 disable
        output DP-1 mode 1920x1080 scale 1.5
}

profile default {
        output DSI-1 enable
}

So I have to click my .desktop file that executes /usr/bin/kanshi before I plug in my Librem 5 to an external monitor, in order for kanshi to work and apply my config file. I also have to click the .desktop file before disconnecting my Librem 5 from an external display, otherwise Phosh restarts (not a reboot).

I tested this, and it works with the NexDock and the Hoyoki USB-C Hub from the Purism shop, and it also works with the PinePhone USB-C Docking Bar that came with the PinePhone Convergence Package. I tested the USB-C hubs with my 55 inch 4k LG TV (WebOS), and I think that 150% scaling is good for both the TV and the NexDock. I decided not to specify the refresh rate in the kanshi config file so that the devices could set the proper refresh rate themselves, since the TV supports 120Hz.

Any idea why it doesn’t automatically work for me, requiring the manual activation?

I use OpenSnitch (v1.5.2) on my Librem 5. Could that be interferring somehow?

Honestly I’m not sure. I tried again today and noticed that my kanshi service was dead, so I had to restart it… Then it worked fine as I described.

I also tried to disable DSI-1 when I connect my Nexdock, but this has the unfortunate effect of making the on-screen keyboard not trigger, after I disconnect the phone from the dock, requiring a phosh restart. I had one time only like you described, I disconnected it and needed to ssh in to the phone to restart phosh.

So it’s not quite entirely stable I suppose… more testing/experimentation required.

User doesn’t have access to multi-user.target . It needs to be default.target
If you edit service then just reload daemon and enable again.
However this is still not complete because service fails on startup.
We need to add Restart=on-failure, but I’m yet to figure out proper way to add delay for restart

thanks for the heads up @librem5!

I’ve also updated my kanshi config to handle profiles with 2 different external monitors. Turns out you can provide the full name (as seen in wlr-randr) rather than just “DP-1”, so I got now:

profile dell {
 output DSI-1
 output "Dell Inc. DELL U3421WE JBNN653 (DP-1)" mode 2560x1080@60Hz scale 1.0
}
profile nexdock {
 output DSI-1
 output DP-1 mode 1920x1080@60Hz scale 1.5
}

profile default {
 output DSI-1
}

and for good measure, my kanshi.service now looks like:

[Unit]
Description=Kanshi display daemon

[Service]
ExecStart=/usr/bin/kanshi
Type=simple
Restart=on-failure

[Install]
WantedBy=default.target

Still not sure I should leave my L5 display on or off while connected to an external monitor, since it may or may not negatively affect Phosh when disconnecting… I’ll play around some more with that.

I got it working with kanshi using @patrix example, thanks!

Theres one thing still missing though from the original post:

This does not seem to be possible using kanshi. I know that in xrandr it is possible to set primary display, but neither kanshi or wlr-randr seems to have an option to set that?

I still have my kanshi config set to disable Librem 5 display when connected to an external display and enable Librem 5 display when disconnected from an external display. I have found that if I use the systemd kanshi.service, disconnecting my Librem 5 from an external display results in Phosh restarting 100% of the time.

Instead, I created a .desktop file that starts the kanshi service (not the systemd kanshi.service) with Exec=/usr/bin/kanshi. However, since kanshi seems to just stop working after a certain amount of time, I click the icon for the .desktop file whenever I am about to connect or disconnect my Librem 5 to/from an external display. This works 100% of the time and never results in Phosh restarting.

This is mildly inconvenient, but much better than having to open the settings app to manually set the display settings each time I want to connect to a display.

@dos, do you have any idea why kanshi stops working like this and needs to be restarted? Or why the systemd kanshi.service causes the Phosh restart when disconnecting Librem 5 from external display?

2 Likes