digitaltrails / vdu_controls

VDU controls - a control panel for monitor brightness/contrast/...
GNU General Public License v3.0
123 stars 4 forks source link

Minimize to tray upon losing focus #57

Closed nahoj closed 1 year ago

nahoj commented 1 year ago

Hi,

When opening VDU Controls from the systray, it would be nice if the window were to close again as soon as one clicks somewhere else, like your typical systray panel.

I just started using it, it's nice, thank you for making it 🙂

digitaltrails commented 1 year ago

Thanks for the feedback. I think this would be relatively easy to add, I will look into it.

I'll probably make put it under the control of an option flag so that the change doesn't ambush existing users.

digitaltrails commented 1 year ago

It is relatively easy to implement, but I also need code to prevent the main window from minimizing if any of the other dialogs are showing. For example, if the Settings dialog is visible, the main window should stay put until the dialog is closed, and perhaps it stay open afterwards. At least that's my thinking at the moment.

I'll put this under control of an option, I might set it to on by default, not sure yet.

This won't take long, but I also need to push a bunch of other changes, testing is going to hold things up, perhaps into next week.

digitaltrails commented 1 year ago

It is relatively easy to implement, ...

Haa! Easy for KDE. Not so easy for gnome, xfce. But I think I'll get there in the end.

Some notes (partly to guide my own thinking)...

In gnome and xfce, using the title bar or window-edges to move or resize the window causes Qt to flag the window as inactive. As soon as a user grabs the window by its title-bar or resize handles, the window goes inactive, and my code minimises it - not good. KDE does the right thing, the window remains active during move/resize. Deepin is based on KDe, so I think that should be OK too.

In the event of a window inactive-event, I need to detect whether the window is being moved and resized, if it is, I need to treat the window as still being active.

What seems to work is using a timer to look at the events following and inactive-event. When an inactive-event is encountered, I set up a timer to go off in 1 second from now. In the meantime I start counting move and resize events. When the timer goes off, if the move/resize count is zero and the window is still inactive, I assume it's safe to minimize.

I thought that covered everything, however... if the user just holds down the left-mouse-button in the title-bar, no move/resize events come in, only repeat inactive-events, so the window will minimise. I'm not sure what I can do about that, at least it's not a common case.

No one else seems to have encountered this AND solved it. I found some gnome related bug reports that sound similar, perhaps it's actually a gnome bug. I guess it's an edge case for Qt, it's on the dividing line between Qt and the window manager.

I also have to find out how Wayland behaves.

I hope to still resolve it in the coming week.

nahoj commented 1 year ago

Thank you for the update. For my part, I am using KDE so I would be content for something that worked only with it. Cheers.

digitaltrails commented 1 year ago

I managed to get the code for this feature working quite well on all platforms, so I've pushed it here.

The hide-on-focus-out option has to be enabled in the Settings Dialog. If a user enables the tray, a popup will suggest also enabling hide-on-focus-out (that was the easiest way to handle things without adding a lot of code or causing issues for existing users).

The code added for gnome and xfce isn't terrible and it does prove useful in KDE at times. There is about a 1 second pause before the minimise, I use Focus follows mouse (mouse precedence), and this gives me enough time to start using the vdu_controls window even if I have to move the mouse over other applications to reach it.

One of the reasons I've pushed it now is that I've accumulated a lot of other unrelated changes and everything appears to be stable at the moment.

nahoj commented 1 year ago

Neat! Thank you for implementing it, and quickly too!

One remark on upgrading: I tried to upgrade with python vdu_controls.py --install and got WARNING: skipping installation of /home/me/bin/vdu_controls, it is already present so I had to delete it by hand. I think it should be reasonably expected that installing VDU Controls overwrites a previous installation.

nahoj commented 1 year ago

I just noticed an issue on KDE: when you right-click on the title bar or click on the window icon, to go to KWin app or window settings, the window loses focus and disappears as well as the menus so you can't access them without disabling hide-on-focus-out (or being very fast, I guess).

From my point of view, this isn't critical as long as one understands what's happening because this is something that I do rarely, so I don't mind temporarily disabling the option. Would be frustrating for someone who forgets about the option though.

Incidentally, you don't have a trick to make the main window always open at the bottom right of the screen, when using several screens with different resolutions, by any chance?

digitaltrails commented 1 year ago

I just noticed an issue on KDE: when you right-click on the title bar or click on the window icon, to go to KWin app or window settings, the window loses focus and disappears as well as the menus so you can't access them without disabling hide-on-focus-out (or being very fast, I guess).

I see what you mean. Hopefully some event is passed to Qt that differentiates this situation from focus out. If no events are passed through, I'm not sure I can do much.

There is a workaround. I had anticipated a need to override hide-on-focus-out when other dialogs, such as Settings, Presets, Greyscale, or Light-Meter are open. So the workaround is to open one of those dialogs before attempting any right-mouse activity.

I could possibly add some kind of pinning control. A small pin icon near top right perhaps. But, not being a standard/common control, it would need help/explaining. I'm not sure it would be that useful and might even cause confusion.

From my point of view, this isn't critical as long as one understands what's happening because this is something that I do rarely, so I don't mind temporarily disabling the option. Would be frustrating for someone who forgets about the option though.

I will at least add a note in the help and release notes.

Incidentally, you don't have a trick to make the main window always open at the bottom right of the screen, when using several screens with different resolutions, by any chance?

If the system-tray option is enabled, on initial use the window attempts to popup near the tray by assuming the mouse must be near there:

    # No previous state - guess a position near the tray. Use the mouse pos as a guess to where the
    # system tray is.  The Linux Qt x,y geometry returned by the tray icon is 0,0, so we can't use that.
    p = QCursor.pos()
    wg = self.geometry()
    # Also try to cope with the tray not being at the bottom right of the screen.
    x = p.x() - wg.width() if p.x() > wg.width() else p.x()
    y = p.y() - wg.height() if p.y() > wg.height() else p.y()
    self.setGeometry(x, y, wg.width(), wg.height())

On KDE, if you quit the application using the Quit menu option, it will save it's last position and use that on subsequent occasions. So move it where you want it to be, and then quit.

This aspect of vdu_controls is quite hacky. To get this exactly right it should be written as a KDE specific system tray application. There is a KDE specific front end to ddcutil: ddcci-plasmoid is a KDE Plasmoid written using QML/python. If you don't need Presets/Preset-Scheduling, then you should definitely check it out (I haven't yet tried it, but it looks quite nice).

digitaltrails commented 1 year ago

Neat! Thank you for implementing it, and quickly too!

One remark on upgrading: I tried to upgrade with python vdu_controls.py --install and got WARNING: skipping installation of /home/me/bin/vdu_controls, it is already present so I had to delete it by hand. I think it should be reasonably expected that installing VDU Controls overwrites a previous installation.

Thanks for the feedback on this. After I packaged it for OpenSUSE, I stopped using using install, so I had overlooked the possibility of reinstall. I was considering removing the install related options because I had imagined they weren't being used by anyone - so it's quite good that you brought this up. Hopefully it should not be too difficult to address.

digitaltrails commented 1 year ago

I see what you mean. Hopefully some event is passed to Qt that differentiates this situation from focus out. If no events are passed through, I'm not sure I can do much.

I looked at the event sequence. On right-mouse, the Qt changes the application state to inactive, my code then initiates a background QTimer that waits 1200 milliseconds, no events follow, after which my code assumes this is a focus out.

I could change the QTimer to fire later. The application does check for an environment variable VDU_CONTROLS_INACTIVE_PAUSE_MILLIS, so you could experiment to see if a longer time is satisfactory:

% VDU_CONTROLS_INACTIVE_PAUSE_MILLIS=2000 vdu_controls

or

% export VDU_CONTROLS_INACTIVE_PAUSE_MILLIS=2000
% vdu_controls

Beyond that (and adding a note on limitations), there's probably nothing I can do.

digitaltrails commented 1 year ago

Quick note: most (all?) KDE tray applications don't have a stock titlebar, they appear to have their own cut down titlebar. It's possible I could so the same, Qt allows a window to be set to have no titlebar, but then I'd have to write code to put my own back, and it would need to look/work OK across gnome, KDE, deepin, xfce, ...

This might be worth investigating (possibly only do this if hide-on-focus-out is True).

nahoj commented 1 year ago

Thanks for the workaround. In my case, I would prefer the window to always follow your initial algorithm and not remember its position. This is because I often add/remove screens (laptop open/closed, video projector on/off) in extended mode (one big virtual screen), so the coordinates for the bottom right in one configuration aren't in the bottom right in another. But I'd understand if you didn't want to do that.

It seems only natural that a regular window can't mimic a plasmoid as well as a real one. I had tried ddcci-plasmoid but I couldn't figure out how to install it with the new pipx thing on Ubuntu on my first try. But I could give it another go.

nahoj commented 1 year ago

One remark on upgrading: I tried to upgrade with python vdu_controls.py --install and got WARNING: skipping installation of /home/me/bin/vdu_controls, it is already present so I had to delete it by hand. I think it should be reasonably expected that installing VDU Controls overwrites a previous installation.

Thanks for the feedback on this. After I packaged it for OpenSUSE, I stopped using using install, so I had overlooked the possibility of reinstall. I was considering removing the install related options because I had imagined they weren't being used by anyone - so it's quite good that you brought this up. Hopefully it should not be too difficult to address.

:+1: I would say the same for the .desktop file and icon.

In the same vein, for me it's a bit too much that the tool asks for confirm to write settings files, and once per file at that. I think VDU Controls should feel some self-confidence as a piece of software and dare write its own settings when the user asks for it by clicking Save ;)

digitaltrails commented 1 year ago

One remark on upgrading: I tried to upgrade with python vdu_controls.py --install and got WARNING: skipping installation of /home/me/bin/vdu_controls, it is already present so I had to delete it by hand. I think it should be reasonably expected that installing VDU Controls overwrites a previous installation.

Thanks for the feedback on this. After I packaged it for OpenSUSE, I stopped using using install, so I had overlooked the possibility of reinstall. I was considering removing the install related options because I had imagined they weren't being used by anyone - so it's quite good that you brought this up. Hopefully it should not be too difficult to address.

👍 I would say the same for the .desktop file and icon.

In the same vein, for me it's a bit too much that the tool asks for confirm to write settings files, and once per file at that. I think VDU Controls should feel some self-confidence as a piece of software and dare write its own settings when the user asks for it by clicking Save ;)

The other files are unlikely to ever need changing, but I can do that work if they ever do.

digitaltrails commented 1 year ago

Thanks for the workaround. In my case, I would prefer the window to always follow your initial algorithm and not remember its position. This is because I often add/remove screens (laptop open/closed, video projector on/off) in extended mode (one big virtual screen), so the coordinates for the bottom right in one configuration aren't in the bottom right in another. But I'd understand if you didn't want to do that.

It would be straightforward to add an option to disable state saving and startup positioning, but window-size would also stop being preserved. During this development cycle I rewrote the command-line and config options parser to make it easy to add options. I've just now pushed a change to add a smart-window option that can be used to enable/disable "smart" main-window placement and geometry preservation.

It seems only natural that a regular window can't mimic a plasmoid as well as a real one. I had tried ddcci-plasmoid but I couldn't figure out how to install it with the new pipx thing on Ubuntu on my first try. But I could give it another go.

Agreed. It's perhaps a mistake to try to much. If vdu_controls looks too much like a plasmoid, but doesn't behave like one, that would just be confusing.

If a plasmoid is truly what is desired, it would probably be best to put efforts into making ddcci-plasmoid easier to install.

nahoj commented 1 year ago

I've just now pushed a change to add a smart-window option that can be used to enable/disable "smart" main-window placement and geometry preservation.

Thank you! When disabling "smart window", and placing a KWin window setting to always open under the mouse, it works as you would expect, it's perfect :+1: