francma / wob

A lightweight overlay volume/backlight/progress/anything bar for Wayland.
ISC License
896 stars 49 forks source link

Feature request: Allow specifying width and height in % of screen #49

Open paper42 opened 4 years ago

paper42 commented 4 years ago

I would like to have wob with height 5px and width 90% of the screen. If I make it X pixels wide, it will not be sized correctly on my second screen which has lower resolution. How hard would it be to implement this?

francma commented 4 years ago

I'm thinking about something like xrandr's output management:

wob --output DP-1 --width 200 --height 100 --output HDMI-1 --width 10 --height 200

This shouldn't be that hard to implement and solve your issue.

Zocker1999NET commented 4 years ago

@francma Your feature idea seems nice, but I would like to have this one too, but it might be too hard to implement, I think. Background: I'm using a ThinkPad X1 Tablet Gen3 with Sway, and to implement a "Tablet Mode", like Windows does, I configured Sway to rescale the primary display's output between 1.8 (acceptable for working with keyboard) and 2 (better for touch). Without specifying the size in % (which is then reevaluated on rescaling by wob), wob's size will only be perfect for one of both modes.

francma commented 2 years ago

I've done some research on wayland protocols and I think implementing this is not possible.

Wob can operate in 3 different modes:

  1. focused (show bar on focused output)
  2. whitelist (show bar on whitelisted outputs)
  3. all (show bar on all outputs)

The problem is that in focused mode we don't choose the output, the compositor does. This means that we have no idea what the output is in order to set the correct dimensions. And I haven't found any way around this.

/**
 * @ingroup iface_zwlr_layer_shell_v1
 *
 * Create a layer surface for an existing surface. This assigns the role of
 * layer_surface, or raises a protocol error if another role is already
 * assigned.
 *
 * Creating a layer surface from a wl_surface which has a buffer attached
 * or committed is a client error, and any attempts by a client to attach
 * or manipulate a buffer prior to the first layer_surface.configure call
 * must also be treated as errors.
 *
 * You may pass NULL for output to allow the compositor to decide which
 * output to use. Generally this will be the one that the user most
 * recently interacted with.
 *
 * Clients can specify a namespace that defines the purpose of the layer
 * surface.
 */
static inline struct zwlr_layer_surface_v1 *
zwlr_layer_shell_v1_get_layer_surface(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, struct wl_surface *surface, struct wl_output *output, uint32_t layer, const char *namespace);
francma commented 11 months ago

You can try this (a little hackish) implementation https://github.com/francma/wob/pull/133

[output.ips]
match = DELL U2722DE
width = 200
height = 30

The implementation was possible thanks to surface_enter event which we get after the surface is created & commited. The "hackish" part is in that wob starts with surface of size 1x1 px and then resizes based on output it ends up on.

void layer_surface_enter(void *data, struct wl_surface *wl_surface, struct wl_output *entered_output)

I don't think I will implement sizes based on % because it would behave weird with (fractional) scaling.