canonical / ubuntu-frame

The foundation for many embedded graphical display implementations
GNU General Public License v3.0
156 stars 21 forks source link

Add way to change display configuration without snapd #173

Open CharleeSF opened 5 months ago

CharleeSF commented 5 months ago

We are trying to create an image that does all configuration on first startup. The device should not require CLI interaction for everything to be setup correctly. Since the device is in portrait mode we need to change the ubuntu-frame configuration. However, this is only possible from command line (or through the snapd interface).

Please provide a way to interact with ubuntu-frame configuration through an interface. For example, you can provide a content interface in which ubuntu-frame drops its latest display config, and where it can pick up new display configurations.

I tried to look if something like this is already available, and it seems like something similar to what I want is done with display_file="$SNAP_DATA/frame.display". However, I cannot touch that file from another snap.

Saviq commented 5 months ago

@CharleeSF since you're building an image, you can use the default config on the gadget?

https://mir-server.io/docs/configuring-ubuntu-frame-through-a-gadget-snap

We'd rather not expose the full display config to be changed runtime, as this is meant to be static - but we're planning to expose the layout option, likely through a content interface.

CharleeSF commented 5 months ago

Ok, thanks!

The example helps :) The multi-line config option can be a bit of a struggle! Also didn't know you could specify only part of the file. I'm gonna try this.

CharleeSF commented 5 months ago

Dear @Saviq

Just wondering, the example you gave has the value "unknown-1" for the display. I was hoping that somehow ubuntu-frame would fill this in by found values, but it seems this is not the case. Rather, it seems to expect the value of the display:

Does this mean that I need to make a separate gadget snap for every hardware I have? What if I want to test my snap on Qemu? The display variables are different?

If the 'auto-infer' logic isn't working when setting default values, I think there is still value in having a way to read and write ubuntu-frame's config from another snap.

Saviq commented 5 months ago

@CharleeSF the output names are stable, and something like HDMI-1, DisplayPort-2. This is most often enough to keep a stable display config.

You can have entries for outputs not present on a piece of hardware, so if you have different hardware (say, one has HDMI, another DisplayPort, yet another an unused port so you need HDMI-2). You can have a single image populated with them all (possibly using YAML anchors to avoid duplication) and only the present, active ones will be used.

We did consider, just didn't get to, yet, matching the displays by something else than output name (model, serial number etc.). If you can describe your use case, we will take that into account.

Another option we could think of is allowing wildcards, so you could say something like:

# ...
- card-id: 0
  *:
    orientation: left
CharleeSF commented 5 months ago

Ah I see :)

How would I put that in the defautls of the gadget?

defaults:
  BPZbvWzvoMTrpec4goCXlckLe2IhfthK:
    display: |
      layouts:
        default:
          cards:
            - card-id: 0
              *:
                orientation: right

This doesn't seem to work, with error:

2024-03-19T23:22:01Z ubuntu-frame.daemon[9536]: ERROR: in display configuration file: '/var/snap/ubuntu-frame/8587/frame.display' : yaml-cpp: error at line 8, column 9: end of map not found

Saviq commented 5 months ago

Sorry, that's not something supported right now, it's just something we could consider (but would need to think properly if that's OK).

For now, you'll need to spell out the output name:

defaults:
  BPZbvWzvoMTrpec4goCXlckLe2IhfthK:
    display: |
      layouts:
        default:
          cards:
            - card-id: 0
              HDMI-1:
                orientation: right
              HDMI-2:
                orientation: right
              DisplayPort-1:
                orientation: right
              DisplayPort-2:
                orientation: right

As I understand it, you only have a single output connected - so just list out all the output names you're expecting, like above.

CharleeSF commented 5 months ago

Awesome! This worked :)

Maybe an idea to make the docs a bit more verbose about the unknown part ;)

Saviq commented 4 months ago

Reopening as we still need something like this, just not too broad.

RubilaVP commented 1 month ago

Hi @Saviq I'd be interested in a feature like this where we can specify a named config that would match certain hardware. In our case, we have the same gadget shared across several hardware but we have one particular use-case where we need the screen to be rotated.

Now, we did consider using a separate gadget snap to set orientation default for this use-case but it means managing an extra gadget that differs only in the orientation property.

In nutshell, we have 'x' types of h/w that share the same gadget but only one type needs its screen rotated.

Maybe you have some ideas on how to implement this? Is it possible for an application in a container, to be able to manage the screen rotation at all? We tried xrandr but it does not work with Xwayland.

Thanks, Rubila

Saviq commented 1 month ago

@RubilaVP One idea is to allow changing the .layout over the content interface. You could then populate the gadgets with multiple layouts within the display config, and from a custom snap of yours modify that file based on whatever conditions you have.

Another thing we want to do, in time, is match on different properties in the static display configuration - something like:

layouts:
  default:
    displays:
    - vendor: <vendor>
      model: <model>
      serial: <serial>
      # etc.
      orientation: left

Not sure if that would help in your case - you may well have the same kinds of displays you place in different orientations.


Any chance you have two outputs that you could designate as landscape / portrait?


By design, we don't want to allow clients affecting display - only the device operator should have control over that.

And yeah, xrandr will never work, XWayland is just a compatibility layer, but not intended to cover all of the X11 protocol.

RubilaVP commented 1 month ago

One idea is to allow changing the .layout over the content interface.

Can you clarify what .layout is being referred to? Is it a directory or the layout key in ubuntu-frame config or something else?

Another thing we want to do, in time, is match on different properties in the static display configuration

This would be perfect in our case as the monitor used for this particular use-case(requiring rotation) is different from rest of the estate.

Any chance you have two outputs that you could designate as landscape / portrait?

If you are suggesting something around the lines, let HDMI-1 be normal, DP-1 be portrait, DP-2 be invereted, etc. then I could give this a try but there is other hardware in the fleet that could be matched and rotated where we don't want it to.

Saviq commented 1 month ago

Can you clarify what .layout is being referred to? Is it a directory or the layout key in ubuntu-frame config or something else?

Internally, it is a file. Currently only exposed through a configuration option, but it could be exposed over a content interface.

Another thing we want to do, in time, is match on different properties in the static display configuration

This would be perfect in our case as the monitor used for this particular use-case(requiring rotation) is different from rest of the estate.

That's good to hear. Unfortunately I can't currently give you an ETA on this functionality, we don't have it road-mapped.

If you'd be willing to contribute such functionality, we'd make sure that we support you in any way we can.


I'll just restate that this is currently possible through the snapd-control - if you have a dedicated snap store, you can have an agent snap on your device, in control of the display-layout config option.

RubilaVP commented 1 month ago

The display-layout config is an interesting option. We have a dedicated snap store but I would like to avoid creating any additional snaps to serve this purpose as we have, atm, only one use-case that could benefit from this.

Right now, I am considering configuring the display-layout/orientation setting in the configure hook of gadget snap based on hardware type.

Thanks, Rubila