-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Screensaver inhibitor. #1229
Screensaver inhibitor. #1229
Conversation
Thanks, this works for me with KDE (X11). Build is working on all platforms. @esbrandt want to test on Mac? I think the user configurable option should default to being enabled. |
Tested, and works for me with macos 10.11.6 |
src/util/screensaver.cpp
Outdated
|
||
IOReturn success; | ||
// FIXME (JosepMaJAZ): I have no idea how to access the NSappKitVersionNumber. | ||
/* work-around a bug in 10.7.4 and 10.7.5, so check for 10.7.x < 10.7.4 and 10.8 */ |
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.
We require at least 10.8, see 2313e72
What about a CO to set that state? Then skin-artists could introduce a button for it? In AutoDJ mode for example the Screensaver could be desired, and when starting the mixxx one could easily deactivate it? |
Ok, user configurable option implemented. Prevent on play is slightly complicated because I'm not sure what would be the correct option. On one side, the EngineDeck::isActive() looks like a good candicate to check, but adding a timer to check this regularly doesn't look like the best option. |
Thank you for adopting this :-) What means uninhibit? For me "Inhibit sreensaver" means "no screensaver". What is the use-case for uninhibit on play? You can hook this feature into mixxx/src/mixer/playerinfo.cpp Line 106 in 8d191bf
The original use-case for me was that mouse and keyboard actions are inhibiting the screensaver, but not the midi controller. So it can happen that the screensaver or power save mode is activated even though the user is controlling Mixxx via midi controller. To solve this, you could hook somewhere into the controller mapping code to inhibit the screen-saver. |
Oups!!! sorry.. obviously i meant the opposite. inhibit on play. Just fixed it in the description :D About inhibiting it only on controller usage is not something that is needed right now with this solution. Basically, the current action on all systems is to prevent the screensaver while the application is running. The original bug and what you say is about sending events to the system if there is action from the controller. |
Are there any other use cases in which it would be helpful to change whether the screensaver is inhibited while running Mixxx? If not, I think another preference option to uninhibit the screensaver prevention while AutoDJ is enabled would be a better solution than adding a button to skins. |
@@ -11,6 +11,13 @@ enum class TooltipsPreference { | |||
TOOLTIPS_ONLY_IN_LIBRARY = 2, | |||
}; | |||
|
|||
// Settings to enable or disable the prevention to run the screensaver. | |||
enum class ScreenSaverPreference { | |||
PREVENT_OFF = 0, |
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.
INHIBIT_OFF sounds more natural to me, though I am not a native speaker.
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.
Actually, to me it's the word inhibit that isn't natural. I'm using it because that's the name used in the linux part of the solution and I kept that name.
http://dictionary.cambridge.org/dictionary/english/prevent
http://dictionary.cambridge.org/dictionary/english/prevent
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 have checked google and you are probably right:
"prevent screensaver" 4550 Hits
"inhibit screensaver" 1020 Hits
src/mixxx.cpp
Outdated
// Save the current window state (position, maximized, etc) | ||
UserSettingsPointer pConfig = m_pSettingsManager->settings(); | ||
int inhibit = pConfig->getValue<int>(ConfigKey("[Config]","InhibitScreensaver")); | ||
mixxx::ScreenSaverPreference inhiPref = mixxx::ScreenSaverPreference(inhibit); |
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.
This casing form is not easy recognizable as cast.
Can we switch to
auto inhiPref = static_castmixxx::ScreenSaverPreference(inhibit);
?
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.
In this case we could also avoid casting to enum and cast to int below.
The line is not aware the new PREVENT_ON_PLAY feature.
So it may look finally like that:
if (inhiPref != static_cast<int>(mixxx::ScreenSaverPreference::PREVENT_OFF)) {
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.
use of "auto" and explicit cast sounds interesting. use of static_cast sounds in contradiction with the use of "enum class".
I would preffer the oppinion of someone else before changing that from what it is now.
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.
You can keep it, if you like.
I have just looked in
https://google.github.io/styleguide/cppguide.html#Casting
In this case your enum class has no constructor so I think static_cast<> it the best choice here.
We only user auto rarely, except if it helps not to repeat ourselves like in this case.
src/mixxx.cpp
Outdated
@@ -1079,6 +1105,15 @@ void MixxxMainWindow::slotNoMicrophoneInputConfigured() { | |||
m_pPrefDlg->showSoundHardwarePage(); | |||
} | |||
|
|||
void MixxxMainWindow::slotChangedPlayingDeck(int deck) { | |||
UserSettingsPointer pConfig = m_pSettingsManager->settings(); | |||
int inhibit = pConfig->getValue<int>(ConfigKey("[Config]","InhibitScreensaver")); |
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.
We should not parse the preferences over and over again.
Please save inhibit as member variable.
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.
Then I will need a slot to call when I change the setting from the preferences.
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.
This can be a direct call, because the DlgPrefControls holds a pointer to MixxxMainWindow.
src/util/screensaver.cpp
Outdated
|
||
namespace mixxx { | ||
|
||
bool ScreenSaverHelper::enabled = false; |
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.
prefix with "s_"
if (inhiOld == mixxx::ScreenSaverPreference::PREVENT_ON) { | ||
mixxx::ScreenSaverHelper::uninhibit(); | ||
} else if (inhiOld == mixxx::ScreenSaverPreference::PREVENT_ON_PLAY) { | ||
mixxx::ScreenSaverHelper::inhibitOnCondition(false); |
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.
can't we call a plain uninhibit in this case as well?
Maybe we need to move the check if it is already uninhibited inside the mixxx::ScreenSaverHelper::uninhibit();
and simplify this code here much.
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.
Conceptually yes, but in practice no.
Some of the implementations require that you call the pair inhibit as many times as uninhibit. (as in, calling inhibit twice and unhinibit once would not uninhibit. So just in case I try to keep that).
I probably need to find a better name for this method. What it really does is either inhibit or uninhibit, depending if the parameter is the same or different than the current status. like this:
Current status: inhibit on
inhibitOnCondition(true) -> does nothing
inhibitOnCondition(false) -> unhinibit.
Current status: inhibit off
inhibitOnCondition(true) -> inhibit
inhibitOnCondition(false) -> does nothing
The end result is always that true leaves it enabled and false leaves it disabled, but internally it decides if it has to change anything or not.
But now that I think about it, I'm not sure why i needed it as separate method. Will check and comment later.
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.
Ok, I ended incorporating the logic inside inhibit and uninhibit.
The only use case i can think of is to protecting Mixxx from curious eyes while you are at the restrooms. |
@JosepMaJAZ: do you have fun and time to add the midi inhibit feature as well? All these config options are IMHO only a bandaid for it. If not, no problem than we can do it in an other PR. Idea: We may add a What do you think? |
Yes, the OS controls are sufficient for cases like that.
I think that would be redundant. When would Mixxx be receiving MIDI signals and you would want to inhibit the screensaver but no decks would be playing? |
It is the question when the screen-saver should kick in. With the current preferences there is no chance to have the screensaver active when the deck is playing, but inhibit it during controller actions. It is "normal" that the screensaver is activated the specified time after the last user action. If this would work for use action via a controller in the same way as for actions via keyboard and mouse, there is IMHO no strong requirement for tweaking the additional preference options, it will "just work". |
@daschuer : As @Be-ing said, the controller part is not really needed, and if allowed, it's just an option to finegrain a bit more when the screensaver can activate. If I have the screensaver at some relatively high time, say 20 minutes, it is to be expected that I would use the controller at least once during that time. In itself, the option to inform the OS about actions when the controller is being used is good, but the implementation on the side of the screensaverhelper also needs to be changed ( not using continuous in windows, using the "SimulateUserActivity" on gnome... or the plain dumb method of simulating actions, which not all OSs interpret as actions": |
…verHelper to remove inhibitOnCondition
…r setting. Also fixed bug due to the new inhibitInternal methods
Ok, I finally added code to the ScreenSaverHelper to allow to trigger user activity and implemented it on Controller::receive and on MidiController::receive() . This is called always independently of the screensaver setting. This requires testing on Linux and Mac again |
Great, Thank you! |
if (userActivityInhibitTimer.elapsed() > 1000) { | ||
mixxx::ScreenSaverHelper::triggerUserActivity(); | ||
userActivityInhibitTimer.start(); | ||
} |
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.
MidiController inherits from Controller. So this code should be moved to a Controller function and called from here.
src/util/screensaver.cpp
Outdated
void ScreenSaverHelper::uninhibitInternal() | ||
{ | ||
qError("Screensaver suspending not implemented"); | ||
} |
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.
is triggerUserActivity() missing in this #else branch
src/util/screensaver.cpp
Outdated
#else | ||
void ScreenSaverHelper::inhibitInternal() | ||
{ | ||
qError("Screensaver suspending not implemented"); |
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.
This and below should be a DEBUG_ASSERT(!"Screensaver suspending not implemented") to avoid log file spam in a release version.
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.
Mmmm.... qError seemed ok thinking that the feature had to be enabled. But the default is precisely enabled, and in case of triggerAction it is always enabled.
Maybe I could have a variable to print it just once.
This case will happen on unusual versions ( Unix, special versions of linux, maybe raspberry...).
The end result is that the feature will not be available, but what is the most correct thing to do? I was thinking about disabling the setting on the preferences page, and maybe force its value on startup to allow screensaver.
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.
My idea was, that it is an error, but only one the developers should bother, that`s why I have proposed a DEBUG_ASSERT.
An
#error not implemented
will work even better.
I am nor sure if it is worth to spend extra work on this unlikely case.
Fixing the log spam issue by a boolean will work for me as well.
The preferences option work well using Ubuntu Trusty + Cinnamon. Unfortunately the contoller actvity does not work:
|
Cinnamon has its own org.cinnamon.ScreenSaver But I do not think it is a good idea to probe for all desktop environments to have this feature. I have read a bit and it looks like the freedesktop api was stripped down intentionally. But there is no word what to do instead. Ins an inhibit uninhibit cycle a good idea? Or should we better fake a key-press? |
I reached the conclusion that freedesktop is like a public interface which
each desktop can implement and provide. And yes, it is more limited than
what the desktops can do.
From your previous email, i think i have an error on the call that i could
fix. I will check that later today.
|
This is an interesting bug: It looks like we can or, if that does not work: |
I fixed the error that the D-bus call gave to you, so it should work with dbus for you now. |
Thanks! I use cinnamon on unbuntu and the gnome screensaver is installed as well. As reported in https://bugzilla.gnome.org/show_bug.cgi?id=579430 this call is required, but it is missing in If we have good results that just XResetScreenSaver works, we should only call this. |
The failed checks are an unrelated test ( midi controller presets) and the mac os build that was canceled or had some problem starting. |
Here the results:
I see two options to solve it:
In any case, we should not try to use freedesktop, since we already know that it will not work. from xdg-screensaver:
|
Ok, commited. Now only XResetScreensaver. |
Thanks for working on this! I've had the screensaver mess me up a few times when I forget to change my power settings. |
Strange: ControllerPresetValidationTest.MidiPresetsValid fails on Windows, but there is no entry why it fails. Else LGTM. Thank you for this nice complete solution. |
Sorry for not making time to send comments about this PR before it was merged! And apologies if you already discussed some of these. I skimmed the thread. Blocking?None of these APIs seem to say anything about whether they block or not -- is it wise to be calling them in the receive loop of the controller? Maybe we should proxy the message from the ControllerManager thread to the main thread. Thread SafetySince ScreenSaverHelper is called from multiple threads, do we need to worry about thread safety of these libraries we're using to interact with system? It looks like we might present the same cookie/assertion ID to the system multiple times for two concurrent calls to ScreenSaverHelper? Can anything else bad happen? I'm assuming these system functions are re-entrant, but is that a safe assumption? CleanupsWhat happens if Mixxx crashes? The OS presumably automatically releases the wakelocks we took? |
Hi ryan.
I'm not sure about the blocking mode either. On windows I think it's a
simple message, on linux the inhibit is a message but I don't know about
the user activity. On mac it's a bit more complex.
I can't ascertain if they are fully thread safe, but I don't see a scenario
right now that could be affected.
About using the same id, that's what the api tells to do, so I don't think
it's a problem.
As for cleanup, at least on windows I tested it. On linux I don't remember
testing it.
El dia 16/04/2017 7:10, "RJ Skerry-Ryan" <[email protected]> va
escriure:
… Sorry for not making time to send comments about this PR before it was
merged! And apologies if you already discussed some of these. I skimmed the
thread.
Blocking?
None of these APIs seem to say anything about whether they block or not --
is it wise to be calling them in the receive loop of the controller? Maybe
we should proxy the message from the ControllerManager thread to the main
thread.
Thread Safety
Since ScreenSaverHelper is called from multiple threads, do we need to
worry about thread safety of these libraries we're using to interact with
system? It looks like we might present the same cookie/assertion ID to the
system multiple times for two concurrent calls to ScreenSaverHelper? Can
anything else bad happen? I'm assuming these system functions are
re-entrant, but is that a safe assumption?
Cleanups
What happens if Mixxx crashes? The OS presumably automatically releases
the wakelocks we took?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1229 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AJdFf2I0zidAqJTRo5O8FSdPosrKZXvSks5rwaLagaJpZM4MpL8F>
.
|
This PR allows Mixxx to prevent the screensaver from starting while Mixxx is running.
https://bugs.launchpad.net/mixxx/+bug/1222098
Tested working on Windows and Linux with Gnome.
Needs testing on Mac (if it compiles... will wait for travis to verify that).
It has also additional code for the "screensaver extension of the X server" (libxss), but it is completely untested.
Currently, it is always on. Further refinements should include allowing the user to choose if it has to be always enabled, just when playing, or disable this feature.