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

Wayland support PR (updated Lourens rich master) #568

Open
wants to merge 26 commits into
base: master
Choose a base branch
from

Conversation

breznak
Copy link

@breznak breznak commented Dec 10, 2017

Fixes #55
Replaces: #558

giucam and others added 6 commits November 24, 2015 16:13
This uses a protocol extension, not in core Wayland.
…gamma

A compositor may want to restrict the access to the gamma_control_manager
interface, to avoid clients changing the gamma without the user knowing.
With the new protocol extension redshift request permission to the
compositor to bind the gamma control global, so that the compositor
can grant/deny it, or ask the user for input.
Try to test Sway redshift support
@breznak breznak mentioned this pull request Dec 10, 2017
@breznak
Copy link
Author

breznak commented Dec 10, 2017

Known issues (please help):

src/gamma-wl.c Outdated
state->outputs = malloc(sizeof(struct output));
} else {
state->outputs = realloc(state->outputs, state->num_outputs * sizeof(struct output));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be clearer:

num_outputs++;
state->outputs = realloc(...);

@atheriel
Copy link

I'd like to test locally, but can't get this to compile (on Linux). Bootstrap and configure steps work fine, but the actual build fails with the compiler errors below. Am I doing something silly?

(snip)
make[4]: Entering directory '/redshift/src'
  CC       colorramp.o
  CC       config-ini.o
  CC       gamma-dummy.o
  CC       hooks.o
  CC       location-manual.o
  CC       options.o
  CC       pipeutils.o
  CC       redshift.o
redshift.c:118:2: error: unknown type name ‘drm_state_t’
  drm_state_t drm;
  ^~~~~~~~~~~
redshift.c:124:2: error: unknown type name ‘randr_state_t’
  randr_state_t randr;
  ^~~~~~~~~~~~~
redshift.c:127:2: error: unknown type name ‘vidmode_state_t’
  vidmode_state_t vidmode;
  ^~~~~~~~~~~~~~~
redshift.c:135:3: error: conflicting types for ‘gamma_state_t’
 } gamma_state_t;
   ^~~~~~~~~~~~~
In file included from redshift.c:61:0:
redshift.h:82:28: note: previous declaration of ‘gamma_state_t’ was here
 typedef struct gamma_state gamma_state_t;
                            ^~~~~~~~~~~~~
redshift.c:143:29: error: ‘drm_init’ undeclared here (not in a function); did you mean ‘lrint’?
   (gamma_method_init_func *)drm_init,
                             ^~~~~~~~
                             lrint
(snip -- many more undeclared-type errors)

@t-8ch
Copy link

t-8ch commented Dec 22, 2017

@atheriel I have a fixed version of this PR available at https://github.com/t-8ch/redshift/tree/wayland

@atheriel
Copy link

atheriel commented Dec 24, 2017

@t-8ch Your branch does indeed compile and work for me. I can confirm that normal invocation works (i.e. redshift -m wayland), and both redshift -x -m wayland and redshift -o -m wayland methods work as expected. And reading the adjustment method from the config file works as well.

@t-8ch
Copy link

t-8ch commented Dec 24, 2017

@breznak Wayland on Windows will not work in any case, it should be disabled in appveyor.yml (also done in my branch)

@breznak
Copy link
Author

breznak commented Dec 28, 2017

Merged the work and fixes from @t-8ch , thank you for the fixes and @atheriel for testing!

@breznak
Copy link
Author

breznak commented Dec 28, 2017

Wayland on Windows will not work in any case, it should be disabled in appveyor.yml (also done in my branch)

@t-8ch just merged the changes, the Windows CI is still failing, as expected, as you said. My point is, if redshift was used on Windows (was it ever?), then we should fallback to the "non-wayland" paths there.

configure.ac Outdated
@@ -67,6 +67,12 @@ PKG_CHECK_MODULES([XF86VM], [xxf86vm], [have_xf86vm=yes], [have_xf86vm=no])
PKG_CHECK_MODULES([XCB], [xcb], [have_xcb=yes], [have_xcb=no])
PKG_CHECK_MODULES([XCB_RANDR], [xcb-randr],
[have_xcb_randr=yes], [have_xcb_randr=no])
PKG_CHECK_MODULES([WAYLAND], [wayland-client wayland-scanner], [have_wayland=yes], [have_wayland=no])
AC_PATH_PROG([wayland_scanner], [wayland-scanner])
Copy link

@atheriel atheriel Jan 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 5 lines appear to be causing the build to fail on Travis (for non-Wayland Linux builds, macOs builds, and Windows builds), which I think is a legitimate issue. The configuration script should only look for WAYLAND_SCANNER if Wayland is available. It is not doing that at present, but I'm not familiar enough with autoconf syntax to know precisely why.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this in breznak#3

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for finding the culpit and fixing that, guys! Merged the update and triggering a new CI run here...

@@ -67,6 +67,8 @@ PKG_CHECK_MODULES([XF86VM], [xxf86vm], [have_xf86vm=yes], [have_xf86vm=no])
PKG_CHECK_MODULES([XCB], [xcb], [have_xcb=yes], [have_xcb=no])
PKG_CHECK_MODULES([XCB_RANDR], [xcb-randr],
[have_xcb_randr=yes], [have_xcb_randr=no])
PKG_CHECK_MODULES([WAYLAND], [wayland-client wayland-scanner], [have_wayland=yes], [have_wayland=no])
PKG_CHECK_VAR(WAYLAND_SCANNER, wayland-scanner, wayland_scanner)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@t-8ch there must be a bug it the precent PR merged, as now both Lin & Win CI fail on wayland detection... Could you have a look please?

@breznak breznak reopened this Jan 10, 2018
@t-8ch
Copy link

t-8ch commented Jan 10, 2018

Can you print the stacktrace?
bt in gdb.

@breznak
Copy link
Author

breznak commented Jan 10, 2018

Dear @t-8ch ,
seems the problem is in #2 wayland_free (state=0x622980) at gamma-wl.c:217

BT and BT full below:

(gdb) bt                                                                                                                                                     
#0  0x00007ffff79bcbb9 in wl_proxy_marshal () from /usr/lib/x86_64-linux-gnu/libwayland-client.so.0
#1  0x0000000000409997 in gamma_control_destroy (gamma_control=0x0) at gamma-control-client-protocol.h:206
#2  wayland_free (state=0x622980) at gamma-wl.c:217
#3  0x0000000000407b06 in method_try_start (method=0x7fffffffdb78, state=state@entry=0x7fffffffd8b0, config=config@entry=0x7fffffffd880, 
    args=<optimized out>) at redshift.c:481
#4  0x00000000004041de in main (argc=<optimized out>, argv=<optimized out>) at redshift.c:1134

and

(gdb) bt full
#0  0x00007ffff79bcbb9 in wl_proxy_marshal () from /usr/lib/x86_64-linux-gnu/libwayland-client.so.0
No symbol table info available.
#1  0x0000000000409997 in gamma_control_destroy (gamma_control=0x0) at gamma-control-client-protocol.h:206
No locals.
#2  wayland_free (state=0x622980) at gamma-wl.c:217
        output = 0x622940
        i = 0
#3  0x0000000000407b06 in method_try_start (method=0x7fffffffdb78, state=state@entry=0x7fffffffd8b0, config=config@entry=0x7fffffffd880,
    args=<optimized out>) at redshift.c:481
        r = <optimized out>
        section = <optimized out>
#4  0x00000000004041de in main (argc=<optimized out>, argv=<optimized out>) at redshift.c:1134
        r = <optimized out>
        gamma_methods = {{name = 0x40db63 "drm", autostart = 0, init = 0x408d90 <drm_init>, start = 0x4090b0 <drm_start>, free = 0x409030 <drm_free>,
            print_help = 0x408fe0 <drm_print_help>, set_option = 0x4094b0 <drm_set_option>, restore = 0x408de0 <drm_restore>,
            set_temperature = 0x408e30 <drm_set_temperature>}, {name = 0x40dffe "randr", autostart = 1, init = 0x40a560 <randr_init>,
            start = 0x40a1b0 <randr_start>, free = 0x40a150 <randr_free>, print_help = 0x40a100 <randr_print_help>,
            set_option = 0x409ea0 <randr_set_option>, restore = 0x409df0 <randr_restore>, set_temperature = 0x40a900 <randr_set_temperature>}, {
            name = 0x40e28f "vidmode", autostart = 1, init = 0x40ada0 <vidmode_init>, start = 0x40ab50 <vidmode_start>, free = 0x40ab30 <vidmode_free>,
            print_help = 0x40aae0 <vidmode_print_help>, set_option = 0x40ace0 <vidmode_set_option>, restore = 0x40ac90 <vidmode_restore>,
            set_temperature = 0x40a9a0 <vidmode_set_temperature>}, {name = 0x40decd "wayland", autostart = 1, init = 0x409d30 <wayland_init>,
            start = 0x409d60 <wayland_start>, free = 0x409950 <wayland_free>, print_help = 0x409920 <wayland_print_help>,
            set_option = 0x4095a0 <wayland_set_option>, restore = 0x4098d0 <wayland_restore>, set_temperature = 0x4095c0 <wayland_set_temperature>}, {
            name = 0x40c395 "dummy", autostart = 0, init = 0x406080 <gamma_dummy_init>, start = 0x4060f0 <gamma_dummy_start>,
            free = 0x406090 <gamma_dummy_free>, print_help = 0x406120 <gamma_dummy_print_help>, set_option = 0x4060c0 <gamma_dummy_set_option>,
            restore = 0x406150 <gamma_dummy_restore>, set_temperature = 0x4060a0 <gamma_dummy_set_temperature>}, {name = 0x0, autostart = 0, init = 0x0,
            start = 0x0, free = 0x0, print_help = 0x0, set_option = 0x0, restore = 0x0, set_temperature = 0x0}}
        location_providers = {{name = 0x40e6e1 "geoclue2", init = 0x40b580 <location_geoclue2_init>, start = 0x40b5a0 <location_geoclue2_start>,
            free = 0x40af00 <location_geoclue2_free>, print_help = 0x40aed0 <location_geoclue2_print_help>,
            set_option = 0x40aea0 <location_geoclue2_set_option>, get_fd = 0x40ae20 <location_geoclue2_get_fd>,
            handle = 0x40ae30 <location_geoclue2_handle>}, {name = 0x40c599 "manual", init = 0x4063c0 <location_manual_init>,
            start = 0x4064f0 <location_manual_start>, free = 0x4063b0 <location_manual_free>, print_help = 0x406330 <location_manual_print_help>,
            set_option = 0x4063f0 <location_manual_set_option>, get_fd = 0x406310 <location_manual_get_fd>, handle = 0x406320 <location_manual_handle>}, {
            name = 0x0, init = 0x0, start = 0x0, free = 0x0, print_help = 0x0, set_option = 0x0, get_fd = 0x0, handle = 0x0}}
        options = {config_filepath = 0x0, scheme = {high = 3, low = -6, use_time = 0, dawn = {start = -1, end = -1}, dusk = {start = -1, end = -1}, day = {
              temperature = 3000, gamma = {1, 1, 1}, brightness = 0.300000012}, night = {temperature = 3000, gamma = {1, 1, 1}, brightness = 0.300000012}},
          mode = PROGRAM_MODE_CONTINUAL, verbose = 1, temp_set = -1, use_fade = 1, preserve_gamma = 1, method = 0x7fffffffdb78, method_args = 0x0,
          provider = 0x7fffffffd9e0, provider_args = 0x0}
        config_state = {sections = 0x0}
        location_state = 0x6216e0

@t-8ch
Copy link

t-8ch commented Jan 10, 2018

@breznak
For some reason output->gamma_control == NULL. I am not sure how this happened. Can you add a guard around the call for gamma_control_destroy()?
This code is only called during shutdown, the redshift work before you stopped it?

@breznak
Copy link
Author

breznak commented Jan 10, 2018

For some reason output->gamma_control == NULL. I am not sure how this happened. Can you add a guard around the call for gamma_control_destroy()?

@t-8ch I did put the guard, but that's not the problem..the issue seems Why is it NULL?
Now it ends with Failed to start adjustment method wayland.

This code is only called during shutdown, the redshift work before you stopped it?

Well, I have "system" redshift (xrandr), which I killed. The redshift from this branch "worked" in a sense that I had the backtrace... The compiled redshift works OK on X.

$ ./src/redshift -b 0.3 -t 3000:3000  -m wayland -v
Trying location provider `geoclue2'...
Using provider `geoclue2'.
Solar elevations: day above 3.0, night below -6.0
Temperatures: 3000K at day, 3000K at night
Brightness: 0.30:0.30
Gamma (Daytime): 1.000, 1.000, 1.000
Gamma (Night): 1.000, 1.000, 1.000
Failed to start adjustment method wayland.

@t-8ch
Copy link

t-8ch commented Jan 10, 2018

@breznak The guard leads at least to a correct diagnosis.
Ah, you are on KDE. I don't think KDE uses the orbital protocol to allow setting of gamma ramps.
(They have their own stuff).
It works for me on the sway window manager.

@breznak
Copy link
Author

breznak commented Jan 10, 2018

Ah, you are on KDE. I don't think KDE uses the orbital protocol to allow setting of gamma ramps.

Yup. So there goes down ... #55 (comment)
Is there a common gamma protocol for wayland? If not, I'd question what value will this sw bring in the future? As KDE,Gnome will have their "redshift", and all others will have to be implemented here (Sway, randr/X, OSX,...)

Can we at least steal the gamma correction code from Gnome,KDE to make them supported here as well, as an alternative?

@t-8ch
Copy link

t-8ch commented Jan 10, 2018

AFAIK the compositors of Gnome and KDE have this included directly and don't expose any interface (yet alone a stable one) to change it from the outside.
So the best we can do is to have a common protocol for the rest of the wayland ecosystem which may become some sort of standard in the future.

@martinetd
Copy link

Thanks for keeping interest in this PR, redshift is awesome and I wouldn't live without it anymore 👍

This isn't 100% reliable for me in one-shot mode, I get this trace on the client:

[1273199.014]  -> [email protected]_gamma_control(new id gamma_control@3, wl_output@5)
[1273199.018]  -> [email protected](new id wl_callback@6)
[1273199.314] [email protected]_id(6)
[1273199.323] [email protected]_size(512)
[1273199.326] [email protected](236)
[1273199.355]  -> [email protected]_gamma(array, array, array)
[1273199.361]  -> [email protected](new id wl_callback@6)
[1273199.372]  -> [email protected]()
[1273199.375]  -> [email protected]()

But server sometimes takes the destroy event before set_gamma (I sometimes never see set_gamma in logs on server side)

The problem is that when we call wayland_free, we don't wait for the callback to finish but just destroy it to get on with it -- and then destroy the gamma control before set_gamma got through.
We should wait for it instead of destroying it, this patch solves the issue for me:

diff --git a/src/gamma-wl.c b/src/gamma-wl.c
index b0617d6..8e7a427 100644
--- a/src/gamma-wl.c
+++ b/src/gamma-wl.c
@@ -207,8 +207,11 @@ wayland_restore(wayland_state_t *state)
 static void
 wayland_free(wayland_state_t *state)
 {
-
-	if (state->callback) {
+	int ret = 0;
+	while (state->callback && ret >= 0) {
+		ret = wl_display_dispatch(state->display);
+	}
+	if (state->callback) { /* ret < 0, log error? */
 		wl_callback_destroy(state->callback);
 	}
 

An alternative would be to not try to be asynchronous and just use wl_display_roundtrip() at the end of wayland_set_temperature, to ensure that when this function returns the temperature has indeed been set, instead of the promise that it will be set that we currently have.
I don't really care either way, both work as long as it's done properly ;)

@breznak
Copy link
Author

breznak commented Feb 12, 2018

@martinetd thanks for the report and fix! Could you please make a commit in your branch, so I can easily bring it here?
EDIT:
Otherwise I'll make the PR but later, busy with conference right now

This prevents destroying gamma control before gamma_control_set_gamma()
has been effectively handled by the wayland server, otherwise we risk
not setting gamma at all in one-shot mode (or miss the last set
temperature call)
@martinetd
Copy link

martinetd commented Feb 12, 2018

Eh, I don't particularily like forking a project for a single commit, but I guess that's the github way... :)
Opened breznak/pull/7 - I have added an error message (Ignoring error on wayland connection while waiting to disconnect: %d) and a comment to explain why we wait in the code. Feel free to adjust to your liking or request changes there.

gamma-wl: wait for sync callback on destroy
@jonls
Copy link
Owner

jonls commented May 6, 2018

Which window managers are supported? As far as I know this is not generic Wayland support, right? Can we give the adjustment method a name that reflects this?

Some questions:

  • Where did the orbital protocol XML come from? Where is the protocol developed and documented?
  • Same questions for the gamma control protocol. Is there any ongoing work to get the gamma control protocol adopted more broadly?
  • What happens if this is run under a window manager that doesn't support the protocols? Does it fail and generate an error message? or does it just not do anything?
  • I've been looking into supporting hotplugging displays while Redshift is running. Would it be easy to support this on Wayland with this adjustment method?

@martinetd
Copy link

  • This isn't generic wayland support, you are correct. Gnome and KDE afaik do not support a standard way of doing this, small compositors have implemented this instead (as far as I know, orbital aside, there are sway (stable wlc version), and wlroots-based compositors (waymonad, sway master, bspwc, etc). Might be missing some.)
  • I think the orbital protocols are developped within the orbital repo itself, you can find them here: https://github.com/giucam/orbital/tree/master/protocol
  • gamma control also seems to come from orbital (well, the author/copyright matches at least); I don't see any history though so not sure if it is a "I got it right on first try" or if development happens elsewhere.
    I'm not aware of any ongoing work to get it used by major DEs unfortunately but might be missing something :/ It looks like @maandree started some discussion a while ago but didn't get a very positive feedback.
  • If gamma-control isn't implemented and -m wayland is specified, redshift fails starting with Failed to start adjustment method wayland. If nothing is specified it looks like it tries to user randr method (which does nothing in rootston (https://github.com/swaywm/wlroots) when I tried, but pretends it succeeded?)
    If the orbital authorized isn't implemented it works anyway, that is optional.
  • I think hotplugging displays already works for this implementation, we get events when outputs are added/removed and it looks like the list is kept up to date (we set gamma for every output). It'd be easy to configure per-output settings too.

@t-8ch
Copy link

t-8ch commented Jun 7, 2018

@jonls Would you be open for a external, dlopen() based method that could be used to give new methods like this one in the hands of users earlier.
Like:
redshift -m external:path/to/method.so

@ddevault ddevault mentioned this pull request Jun 28, 2018
@minus7
Copy link

minus7 commented Jul 22, 2018

This implementation doesn't work if your gamma ramps are larger than wayland's internal buffer of 4096 bytes (swaywm/wlroots#1135). @emersion has updated the protocol to use a fd to pass the gamma ramps instead of passing them as arguments (swaywm/wlr-protocols#24; see changes e.g. here). I adapted the changed protocol in the wayland branch in my fork if anyone wants to give it a try.

Related PRs for wlroots and sway: swaywm/wlr-protocols#24 swaywm/wlroots#1157 swaywm/sway#2325

@emersion
Copy link

Gnome and KDE afaik do not support a standard way of doing this

FYI GNOME and KDE probably won't ever support a standard protocol because they now have this functionality built-in in the compositor.

@Russell-Jones-OxPhys
Copy link

Russell-Jones-OxPhys commented Jul 28, 2018

@emersion Do you have confirmation that those projects won't accept a common protocol to allow third party implementations? I don't see why they wouldn't per se.

janlucaklees added a commit to janlucaklees/dotfiles-old that referenced this pull request Jan 2, 2019
Installed new redshift version from here: jonls/redshift#568
Tweaked systemd service files and now it's finally working as I wanted
it to.
@varac
Copy link

varac commented May 5, 2019

What's the state of this PR ? I'd love to use redshift on wayland/sway!

@atheriel
Copy link

@varac #663 works quite well under sway, and is actively kept up-to-date with master.

@breznak
Copy link
Author

breznak commented Mar 21, 2020

I'd love to use redshift on wayland

btw, wayland (or atleast on KDE) has it's way of "Night mode"

@WhyNotHugo
Copy link
Contributor

As per #55, gammastep seems to be the way to go if using wayland.
Doesn't look like this PR is gonna get merged anytime soo.

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

Successfully merging this pull request may close these issues.

Feature: Add Wayland support