summaryrefslogtreecommitdiff
diff options
authorAndrea Azzarone <azzaronea@gmail.com>2017-09-25 16:04:00 +0000
committerBileto Bot <ci-train-bot@canonical.com>2017-09-25 16:04:00 +0000
commite38ba1338e99bf27900f3a22810eafd245f38de2 (patch)
tree6e1c42046fa498b506c71d4e001bb4eae47b6d67
parentc40c8141e66ed6e5f97bb49cdb50a2559bb640bd (diff)
parent30a7f37fa1a56bb0d7fccd1018743c8bbf8fa76c (diff)
Wait until the color buffer is cleared before suspending. (LP: #1532508)
Approved by: Marco Trevisan (TreviƱo) (bzr r4258)
-rw-r--r--lockscreen/LockScreenController.cpp40
-rw-r--r--lockscreen/LockScreenController.h7
-rw-r--r--lockscreen/SuspendInhibitorManager.cpp2
-rw-r--r--lockscreen/SuspendInhibitorManager.h1
-rw-r--r--plugins/unityshell/src/unityshell.cpp12
5 files changed, 61 insertions, 1 deletions
diff --git a/lockscreen/LockScreenController.cpp b/lockscreen/LockScreenController.cpp
index 5f0c4b924..8f6e7bc9b 100644
--- a/lockscreen/LockScreenController.cpp
+++ b/lockscreen/LockScreenController.cpp
@@ -76,6 +76,8 @@ Controller::Controller(DBusManager::Ptr const& dbus_manager,
, blank_window_animator_(IDLE_FADE_DURATION)
, test_mode_(test_mode)
, prompt_activation_(false)
+ , is_paint_inhibited_(false)
+ , buffer_cleared_(true)
{
auto* uscreen = UScreen::GetDefault();
uscreen_connection_ = uscreen->changed.connect([this] (int, std::vector<nux::Geometry> const& monitors) {
@@ -93,7 +95,13 @@ Controller::Controller(DBusManager::Ptr const& dbus_manager,
suspend_inhibitor_manager_->connected.connect(sigc::mem_fun(this, &Controller::SyncInhibitor));
suspend_inhibitor_manager_->about_to_suspend.connect([this] () {
if (Settings::Instance().lock_on_suspend())
+ {
+ InhibitPaint();
session_manager_->PromptLockScreen();
+ }
+ });
+ suspend_inhibitor_manager_->resumed.connect([this] () {
+ UninhibitPaint();
});
Settings::Instance().lock_on_suspend.changed.connect(sigc::hide(sigc::mem_fun(this, &Controller::SyncInhibitor)));
@@ -556,6 +564,36 @@ bool Controller::HasOpenMenu() const
return primary_shield_.IsValid() ? primary_shield_->IsIndicatorOpen() : false;
}
+void Controller::InhibitPaint()
+{
+ buffer_cleared_ = false;
+ is_paint_inhibited_ = true;
+}
+
+void Controller::UninhibitPaint()
+{
+ if (!is_paint_inhibited_)
+ return;
+
+ buffer_cleared_ = true;
+ is_paint_inhibited_ = false;
+ SyncInhibitor();
+}
+
+bool Controller::IsPaintInhibited() const
+{
+ return is_paint_inhibited_;
+}
+
+void Controller::MarkBufferHasCleared()
+{
+ if (buffer_cleared_)
+ return;
+
+ buffer_cleared_ = true;
+ SyncInhibitor();
+}
+
void Controller::SyncInhibitor()
{
bool locked = IsLocked() && primary_shield_.IsValid() && primary_shield_->GetOpacity() == 1.0f;
@@ -566,7 +604,7 @@ void Controller::SyncInhibitor()
if (inhibit)
suspend_inhibitor_manager_->Inhibit("Unity needs to lock the screen");
- else
+ else if (buffer_cleared_)
suspend_inhibitor_manager_->Uninhibit();
}
diff --git a/lockscreen/LockScreenController.h b/lockscreen/LockScreenController.h
index fbe2c746b..2b03de4fd 100644
--- a/lockscreen/LockScreenController.h
+++ b/lockscreen/LockScreenController.h
@@ -56,6 +56,8 @@ public:
bool IsLocked() const;
bool HasOpenMenu() const;
+ bool IsPaintInhibited() const;
+ void MarkBufferHasCleared();
private:
friend class TestLockScreenController;
@@ -82,6 +84,9 @@ private:
void OnLockScreenInputEvent(XEvent const&);
void OnBlankWindowInputEvent(XEvent const&);
+ void InhibitPaint();
+ void UninhibitPaint();
+
std::vector<nux::ObjectPtr<BaseShield>> shields_;
nux::ObjectWeakPtr<BaseShield> primary_shield_;
nux::ObjectWeakPtr<AbstractUserPromptView> prompt_view_;
@@ -104,6 +109,8 @@ private:
bool test_mode_;
bool prompt_activation_;
BlurType old_blur_type_;
+ bool is_paint_inhibited_;
+ bool buffer_cleared_;
connection::Wrapper uscreen_connection_;
connection::Wrapper hidden_window_connection_;
diff --git a/lockscreen/SuspendInhibitorManager.cpp b/lockscreen/SuspendInhibitorManager.cpp
index 8131e7d51..6135ef790 100644
--- a/lockscreen/SuspendInhibitorManager.cpp
+++ b/lockscreen/SuspendInhibitorManager.cpp
@@ -60,6 +60,8 @@ SuspendInhibitorManager::Impl::Impl(SuspendInhibitorManager *parent)
lm_proxy_->Connect("PrepareForSleep", [this] (GVariant* variant) {
if (glib::Variant(variant).GetBool())
parent_->about_to_suspend.emit();
+ else
+ parent_->resumed.emit();
});
lm_proxy_->connected.connect(sigc::mem_fun(&parent->connected, &decltype(parent->connected)::emit));
diff --git a/lockscreen/SuspendInhibitorManager.h b/lockscreen/SuspendInhibitorManager.h
index 1954a36e6..75c95f5f1 100644
--- a/lockscreen/SuspendInhibitorManager.h
+++ b/lockscreen/SuspendInhibitorManager.h
@@ -42,6 +42,7 @@ public:
sigc::signal<void> connected;
sigc::signal<void> about_to_suspend;
+ sigc::signal<void> resumed;
private:
class Impl;
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 20e644860..0ecff9515 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -1496,6 +1496,13 @@ bool UnityScreen::glPaintOutput(const GLScreenPaintAttrib& attrib,
CompOutput* output,
unsigned int mask)
{
+ if (G_UNLIKELY(lockscreen_controller_->IsPaintInhibited()))
+ {
+ CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
+ CHECKGL(glClear(GL_COLOR_BUFFER_BIT));
+ return true;
+ }
+
bool ret;
/*
@@ -1692,6 +1699,11 @@ void UnityScreen::preparePaint(int ms)
void UnityScreen::donePaint()
{
+ if (G_UNLIKELY(lockscreen_controller_->IsPaintInhibited()))
+ {
+ lockscreen_controller_->MarkBufferHasCleared();
+ }
+
/*
* It's only safe to clear the draw list if drawing actually occurred
* (i.e. the shell was not obscured behind a fullscreen window).