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

Different images for different screens #14

Open
himdel opened this issue Aug 10, 2019 · 14 comments
Open

Different images for different screens #14

himdel opened this issue Aug 10, 2019 · 14 comments

Comments

@himdel
Copy link
Owner

himdel commented Aug 10, 2019

Allow providing a list of images to be used in sequence across outputs (iterated over in TL->TR->BL->BR direction)

@gavsiu
Copy link

gavsiu commented Jul 26, 2021

So what's the point of -screens option? I was looking for this capability as well and tried that option with no success or noticeable change.

@himdel
Copy link
Owner Author

himdel commented Jul 26, 2021

-screens is for Xinerama .. unless you're running a multihead X setup, this is not for you.

Modern linux GUIs use xrandr for multiple desktops, not xinerama screens.

I would love to add better support for xrandr screens though, so far it only knows they are there and tries to put the wallpaper on each, but if you have any ideas on how you'd want to use hsetroot with multiple screens please share :)

@lwilletts
Copy link

I know it's more of a pain but you could write an imagemagick script to take two (or more) images provided and stitch them together with how your screens are positioned using the data from xrandr

@himdel
Copy link
Owner Author

himdel commented Jul 26, 2021

@lwilletts That sounds perfectly reasonable (hsetroot already does pretty much call imagemagick anyway).

What I'm missing is a good way of specifying this...

hsetroot --output=eDP-1 image1.jpg --output=HDMI-2 image2.jpg sounds cumbersome, you'd have to always know how your outputs are called.

hsetroot image1.jpg image2.jpg would mean hsetroot has to magically figure out which image belongs on which screen.

I'm looking for something in between, something useable.. maybe going clockwise in a spiral matching the output positions or something like that :)

@gavsiu
Copy link

gavsiu commented Jul 26, 2021

hsetroot --output=eDP-1 image1.jpg --output=HDMI-2 image2.jpg is exactly what I would like.

I used to use hsetroot cause for some reason, xsetroot -solid doesn't work for me for solid color background. Then I wrote a script to choose a random wallpaper and set it with hsetroot when I didn't have a second monitor.

I finally installed feh yesterday for multi monitor support, but you can only tell it to set first monitor and second. I have a feeling my first and second monitor changes because polybar system tray doesn't always load on the same monitor and I haven't quite figured out how to fix that.

@himdel
Copy link
Owner Author

himdel commented Jul 26, 2021

Aah, well, in that case, it shouldn't be that hard to add, I'll take a look over the weekend :).

I have a feeling my first and second monitor changes because polybar system tray doesn't always load on the same monitor and I haven't quite figured out how to fix that.

That may have to do with what X considers the primary screen, you may be able to change that using xrandr --output=... --primary. (Idk about polybar, but i3 only notices the primary screen changes when I restart it.)

@himdel
Copy link
Owner Author

himdel commented Jul 28, 2021

So.. one complication, there doesn't seem to be a nice way for a C program to tell which outputs are there by name.
libXinerama doesn't return output names, while libxrandr doesn't seem to return the position/offset values.

Which would be more acceptable, depending on a ruby program using the xrandr gem to list the outputs (along the lines of #34), or having the C code call bash to run the xrandr command (https://github.com/himdel/hsetroot/blob/758a7c35a64e8a8573047c8b561b9b99beca9537/outputs_xrandr.c)? Any other ideas?
(The ruby version depends on ruby and the xrandr gem, the C version on the xrandr command having consistent output, grep and sed.)

@gavsiu
Copy link

gavsiu commented Jul 28, 2021

The C version would mean less dependencies?

@himdel
Copy link
Owner Author

himdel commented Jul 28, 2021

Yes, the C version means less dependencies,
the potential downside is that it will only work as long as xrandr outputs lines exactly like DP-2-3 connected 1920x2160+0+0 (...).

@gavsiu
Copy link

gavsiu commented Jul 28, 2021

What differs for the xrandr output? The display name might change depending on load order or something right? I'm not too familiar. I think I remember reading it can change on some systems, but I don't think I've encountered it on my laptop's + 1 external monitor.

Whichever is easier for you.

@vincentbernat
Copy link
Contributor

Have a look at the source code of xrandr. It's simple enough for you to steal the code. You have two different paths: one for getting outputs (physical screens) and one for monitors (virtual screens). Usually, there is a 1:1 mapping. For wallpapers, I think you should stick to outputs.

See https://gitlab.freedesktop.org/xorg/app/xrandr/-/blob/master/xrandr.c#L1815 and https://gitlab.freedesktop.org/xorg/app/xrandr/-/blob/master/xrandr.c#L1352. The code is a bit hard to read because xrandr is using global state. Basically, you do:

  1. XRRGetScreenResourcesCurrent() to get screen resources
  2. For each screen resource, XRRGetOutputInfo() to get the outputs
  3. For each output, also get the CRTC Info (which ontains offset and dimension) with XRRGetCrtcInfo()

@vincentbernat
Copy link
Contributor

Here is what I use with Python. This should translate to C as is.

    d = display.Display()
    screen = d.screen()
    window = screen.root.create_window(0, 0, 1, 1, 1, screen.root_depth)
    background = Image.new("RGB", (screen.width_in_pixels, screen.height_in_pixels))

    # Query randr extension
    outputs = []
    screen_resources = randr.get_screen_resources_current(window)
    for output in screen_resources.outputs:
        output_info = randr.get_output_info(window, output, screen_resources.timestamp)
        if output_info.crtc == 0:
            continue
        crtc_info = randr.get_crtc_info(window, output_info.crtc, output_info.timestamp)
        outputs.append(
            Rectangle(crtc_info.x, crtc_info.y, crtc_info.width, crtc_info.height)
        )

@Swivelgames
Copy link

Hate to be that guy, but is there still any interest in implementing this? It's a bit out of my comfort zone to contribute, but I was bashing my head against a wall with -screens until I came here and realized it wasn't currently possible.

@himdel
Copy link
Owner Author

himdel commented Sep 19, 2023

Fair :)
I'm still planning to add it (though apparently you DO have to remind me every couple of years ;)), but .. if you rely on me, it probbbly won't happen before xmas.

So, contributions welcome, but if not, we'll get there eventually? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants