-
Couldn't load subscription status.
- Fork 434
D-Bus service #54
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
base: master
Are you sure you want to change the base?
D-Bus service #54
Conversation
|
Not sure what you mean with ‘store configuration state’ in the last todo, Is this implementation able to distinguish users, X displays and |
|
Yes, it may be possible to simply use Currently this implementation only has vidmode and randr support. It is running on the D-Bus session bus so it should only apply to the session that it is running in. I think it would be reasonable to add your drm support as well even though logically the TTYs are not contained in the session and are shared with multiple users, but I guess it would be convenient for single-user systems. Ideally I think Redshift should be able to run with both drm and randr (or drm and vidmode) at the same time so that only one instance is necessary. I would also like for Redshift to be able to run with no gamma drivers. This was the purpose of the dummy driver but I think now that it should be implemented slightly differently. I am not sure I understand completely what use the Lastly, I should mention that I plan on keeping the old implementation alive so that people who are not enthusiastic about the dependency on D-Bus and glib can still use redshift from the terminal, but I think for any progress to happen on the GUI side we really need to move to a proper interface that is easy to develop for. |
|
If Redshift is improved to be able to control the monitors individually (more than just the gamma correction) than REDSHIFT_ID whould not be neccessary. Although implementing this is not too I have reevaluated the advantages of D-Bus versus domain sockets and I think that domain sockets are not sufficient for the future of Redshift. |
|
Yes, I saw that you already did some work in this direction in the multimonitor branch. What do you think is the risk of implementing individual control of monitors like that? |
|
I am afraid that the change would increase complexity without substantial gain. Currently the only problem with running one instance per monitor is that you would need one redshift-gtk instance per |
|
Ok, I agree with your point to a certain extent but having multiple IDs in REDSHIFT_ID would seem to just shift the complexity into the GUI. What do you think about keeping the current implementation around mostly unchanged and then work on getting individual monitor control into redshift-dbus instead since it seems to have a higher importance there? |
|
I agree that it is just shifting the complexity, but I do think that the over all complexity would be decreased. In any case, only implementing it in redshift-dbus would increase the complexity only more. I think it is best, if not using ID:s, to implement it in both commands and let it be possible to configure the temperature and brightness individually for the monitors in the same way as the gamma correction, and, as with the gamma correction, still allow it to be specified in [redshift] to apply to all monitors that have not hade it specified especially; and then try to separate out the implementation of the D-Bus service from redshift-dbus.c as I did in my proof of concept, ideally redshift-dbus.c and redshift.c would be the same file just one compiled with -DENABLE_DBUS and the other without it. |
|
Since it should be possible to run both DRM and RandR or vidmode at the same time, I think it makes since to also add support for running in multiple X displays. I started to implement this but I found that it would increase the complexity of |
|
Hi, I'll now try to explain how the kde interface interacts with redshift and the structure of it, and I'll explain why dbus can simplify the implementation. Currently the kde interface is written in c++ and it is made of a backend (a plasma dataengine) and a frontend a plasmoid. There can exist an infinite number of plasmoids (in the system tray, on the desktop, in different activities ecc.) that don't interfere with each other, because all of them interact with a single data engine that actually controls a single redshift process. The backend starts a KProcess to launch redshift on a shell, and it launches it with all the parameters every time bypassing so the redshift configuration file in the user home directory. The frontend is a kde plasmoid that shows an icon of redshift. When the user clicks on the icon, he can turn redshift on and off. When redshift is "on", it changes the color temperature automatically during the day as it is supposed to do. If the user scrolls the wheel on the icon instead, redshift is brought in "manual" mode. When in this mode, redshift sets a fixed temperature and won't change it anymore until the user doesn't click again on the redshift icon to bring back redshift to "auto" mode. When the mouse wheel is scrolled over the icon the temperature can be selected. While scrolling an osd appears showing the current color temperature. Some users asked me to show the current temperature also in the tooltip balloon that appears when the mouse is hoovered over the redshift icon, but I haven't implemented it yet because I can only know the current temperature when redshift is in manual mode (because I set it). When it's in "auto" mode, with the current implementation of redshift, there is no way to know the current temperature. So if the redshift-dbus implementation will export a property with the current temperature, this can be easily shown in the interface. The following paragraph explain a kde activity dependent behavior of redshift. All the parameters of redshift and the activity based behavior can be edited by the user from a settings page that can be accessed from the right-click menu of the applet. When the user change the parameters the redshift process must be terminated and started again since the parameters can't be hotswapped on the running process. If the smooth transition option is enabled the user will see a transition red-neutro (process terminated) followed by a transition neutro-red (process started). If the dbus implementation will allow the parameters hot swapping the transition can be current color -> new color that will be much more nicer. Moreover if the user edits a parameters and click "Apply" and then he edits another parameters and click "Apply" again before the red-neutro transition is over, the screen become instantly red and a new red - neutro transition begin. This is really annoying. Another problem I have is that if the user select the autostart option in order to run redshift on the startup of the pc, since I run the redshift process from within the kde backend, it happens that the process is started but the display doesn't turn red. This happens because the kde redshift dataengine, which starts the redshift process, is loaded too early and (I don't know why) redshift can't manage the display correctly. To avoid this problem I created a process called redshift autostartenabler that is started on the kde startup in an usual way. When this program is loaded,it enables the redshift dataengine to start the redshift process, so that the start time of the redshift process happens late in the desktop environment boot. This can be solved with the dbus implementation in the following way: the redshift process is started at the desktop startup (as any auto start program) and reads its parameters from the settings file of redshift, then the dbus interface allows the kde interface to hot swap the new parameters if the user changes them and start. Currently the location must be set by the user, and the proposed location the first time the kde interface is started is the location grabbed from the kde location settings. I do not understand if redshift can currently get the location from geoclue or not. As I said the kde interface is written in c++, this is due to the fact that it needs a central dataengine to manage the redshift process. Dbus should provide: |
|
A last thing. Some user asked me to implement a personal schedule for redshift, with multiple temperatures during the day so that a user can decide the hours when the color transition must happen based on his habits. As a reference, this feature have recently implemented in Flux. |
|
Still reading, but before I forget, I think that if you start redshift with |
|
Thanks. I never used the -v option, and I didn't noticed it. |
@jonls GSettings should do and be cross-platform (in theory). |
|
Thanks for the comments @simgunz. I think the draft interface will take care of the features that you need reasonably well. Recently redshift-gtk was extended to parse the |
Add a seperate executable redshift-dbus that functions like redshift but runs the main loop through Glib. In addition it registers a service on the session DBus such that it can be queried and controlled.
Try to obtain location on program start and register a signal so that the position will be updated with new information from Geoclue.
When a position is obtained from Geoclue it is saved to `$XDG_DATA_HOME/redshift/position`. This file is loaded on program start to find the initial position. If the file does not exist the default position of 0,0 is used until the correct position can be found.
|
Obtaining position from Geoclue is implemented now. |
|
As mentioned in #80 the Geoclue code causes a segfault on startup. Since the old Geoclue is no longer maintained it will be necessary to move to Geoclue2 and hope it is less broken. |
|
Some comments on the API interface. Having a cookie with inhibit/uninhibit is fine, as there are only 2 possible states so the logic is straight-forward and the behaviour is predictable for clients. However, using the same system for (Un)EnforceLocation and (Un)EnforceTemperature seems over-complex, and I don't see the benefit. If multiple clients attempt to (for example) call EnforceLocation, redshift would need to store the previous location value for each EnforceLocation call, and would need to have a non-trivial algorithm for deciding which location to revert to when UnEnforceLocation is called. A scenario: Imagine we have locations (A, B, C) and clients (X,Y). It is possible to modify how this algorithm works, but I would argue that all possible implementations are potentially confusing. Instead of this, I recommend simply having simple Get/SetLocation and Get/SetTemperature methods. If you wish to implement something like a 'try it and see' temperature slider, it would be up to the client to retrieve and store the initial temperature, and if the user cancels the client would call SetTemperature with the original value. This does introduce the possibility of overwriting a temperature that another client set in the meantime, but I argue that this is no more confusing than the scenario outlined earlier. The implementation is simpler, and the user has a greater chance of building a mental model of what is actually occurring. The temperature slider question is also interesting. If the same client calls EnforceTemperature multiple times (each time the slider is moved), that client would be issued a new cookie for every EnforceTemperature call. This seems unwieldy. Edit: I have thought about this some more, and the scenarios that arise using Get/SetLocation and Get/SetTemperature seem complicated too. Using Get/SetLocation and Get/SetTemperature would essentially over-ride the automatic setting of the location and temperature, so a mechanism to reverse the over-ride is needed. Which gets us back to the cookie-based approach. So in summary, the cookie based approach seems OK, but I'm curious how it would work if the user was operating a temperature slider. Perhaps you need an UpdateEnforcedTemperature/UpdateEnforcedLocation call that takes the cookie as an in parameter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about the capitalisation of the second Redshift in the service file name. Nor the repetition of redshift. Why not just:
data/dbus-1/services/dk.jonls.redshift.service.in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the file name here should match the well-known bus name of the Redshift service. The D-Bus spec provides an example where the well-known bus name is the same as the main interface name, and it seems that many other projects follow that convention so I copied that. The interface name is composed of a reverse-DNS part (dk.jonls.redshift) and a name (Redshift).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not make this a guint32? Cookies have no need to be negative, plus overflow behaviour for signed integers is undefined in C.
Not that it's a real problem... I couldn't imagine the system every issuing 2.1 billion cookies :).
|
In order to detect a client process terminating without releasing its cookies, you should be checking the NameOwnerChanged signal of org.freedesktop.DBus . As far as I can see, if a client process acquires a cookie and enforces the temperature, if it terminates then that temperature will remain enforced. |
|
Redshift was such a nice and slim program. It did one job and it did it well, being a good example of the KISS (keep it simple & stupid) principle. Why adding more and more unnecessary bloat? |
|
People want to to things like have changing the temperature from a GUI. |
|
@kimdouglasmason Hey sorry for the late reply and thanks for the suggestions. I agree that your idea of using NameChangeOwner is superior, I was not aware that this was possible when I wrote it. |
|
D-Bus is extremely useful and will enable us to write GUIs without depending on compiling them in. For everyone wanting the extremely minimal version, there are always compile time switches. But why does this pull request depend on GLib? There is a plain C D-Bus API that we could use! |
|
@flying-sheep The short answer is that the glib interface is much easier to use. As far as I know very few service providers actually use the C D-bus API. The first line in the documentation literally says "This manual documents the low-level D-Bus C API. If you use this low-level API directly, you're signing up for some pain". |
|
i was hoping that we could create a minimal, framework-agnostic backend that can be either started via commandline with options or as a service, and has no runtime dependencies (like a GLib event loop) when started via commandline, it just runs there in some terminal until killed or suspended via when started as service, it would be most useful when controlled by a toolkit-dependent frontend via D-Bus. (since this is still very minimal, it could be the default compile options and the version to be included in linux distributions) like it is now is still OK, i mean, most people have GLib anyway, and the rest can still be achieved. |
|
so what’s going on with this? it would be very useful for everyone, no matter the implementation |
|
I agree that the Perhaps the following behaviour would be reasonable from a user-perspective: Redshift-gtk connects to the dbus-service and settings are set according to the config-file or gui-wizard. If another program or command-line command changes the settings, the default behaviour is for Redshift-gtk to increment it's displayed profile (say from "profile1" to a temp-file-name, which shows the respective changes which are not part of the standard profile).
Imho a single daemon/instance with different settings by monitor-name/number would be a much neater structure than multiple instances per monitor if running with --enable-dbus, it sounds like it might be tricky to get it to play nice for the non-dbus version though. |
|
uh, still nothing? this is the #️⃣1️⃣ feature i’m waiting for 😞 |
|
Hi All, I have created a new branch https://github.com/dkondor/redshift/tree/dbus_new where I merged the latest master with this branch. I've been able to create a minimal working version that uses the same options and configs as regular redshift, but is able communicate via DBus. What works: What is missing: Let me know if this is a good direction; I can create a new pull request for either this branch or master. |
|
Cool! Since KDE plasma has night color functionality now, I don’t use redshift anymore and can’t test, sorry. |
|
@dkondor Thanks for working on this. I've been wanting to merge some changes to dynamically update when displays are plugged in/out before getting back to this but I haven't had time to make progress in a long time. The direction I have in mind would be to have displays represented in the D-Bus API so that changes can optionally be applied to each display individually. I agree about the Geoclue2 threading but probably not worth changing that unless we have to? I don't think |
Implements Redshift as a separate D-Bus service. It must be explicitly activated by passing
--enable-dbustoconfigureand will produce a separate executable that can be automatically activated through the service file. The D-Bus interface is draft and requires more discussion to finalize (spec: https://github.com/jonls/redshift/blob/dbus-service/src/redshift-dbus.c#L196).Current draft interface
The way the draft interface works is as follows: The properties Temperature, Period ("Day", "Night", "Transition"), and CurrentLatitude and CurrentLongitude can be read (but not written). In addition there is a property called Inhibited which tells whether Redshift is temporarily disabled (also read-only). There is a method called GetElevation which returns the current solar elevation. I am considering that this should maybe also be a property instead of a method. The properties TemperatureDay and TemperatureNight can be used to set the respective color temperatures.
A program that wants to interact with Redshift has to first acquire a cookie (integer) using the AcquireCookie method. This is needed so that two different programs won't step on each others toes. Different programs can acquire cookies, but the following methods put some restrictions on how programs with different cookies can interact with Redshift. There is an associated method ReleaseCookie which invalidates a previously acquired cookie, and undoes all interactions that the cookie has been doing. The method of using a cookie is somewhat similar to the method used by GNOME Screensaver (https://people.gnome.org/~mccann/gnome-screensaver/docs/gnome-screensaver.html#dbus-interface).
The Inhibit method can be used with a cookie to temporarily disable Redshift and it will stay disabled as long as at least one cookie is inhibiting. EnforceLocation can be used (also with a cookie) to change the location. This could be used by an external program to set the location by some method that is not supported by Redshift itself. It could also be used to manually set a location. Only one cookie can enforce the location at a time.
The EnforceTemperature method can be used to force a specific color temperature, so that the user can override the temperature manually or use a program that implements a different color temperature cycle than Redshift. For this method there is a priority parameter which basically means that two cookies can force a temperature at the same time but one will have priority over the other. I think this would be useful to have for a user interface that temporarily shows the desired color temperature when the user moves a slider, and this effect should have priority over the temperature enforcement as described previously. Lastly there are three methods, Uninhibit, UnenforceLocation and UnenforceTemperature which will undo the effect of the previous three methods.
I still haven't though about how a program would interact with the gamma method driver. Perhaps there should be a way to select a driver though the D-Bus interface, set options for driver, and see error messages if a driver fails to work.
The location is also not obtained through Geoclue yet, so the only way to use it now is to force a location through the EnforceLocation method. I'm thinking about adding writable properties called FallbackLatitude and FallbackLongitude so that Redshift will use these if Geoclue doesn't work, but I am not sure if that is the best solution.Lastly, there should also be properties for gamma and brightness I think, but these should perhaps be integrated with the gamma method interface so they can be set per screen.Todo