Merge lp:~albaguirre/unity-system-compositor/add-power-off-delay-option into lp:unity-system-compositor

Proposed by Alberto Aguirre
Status: Merged
Approved by: Michael Terry
Approved revision: 116
Merged at revision: 116
Proposed branch: lp:~albaguirre/unity-system-compositor/add-power-off-delay-option
Merge into: lp:unity-system-compositor
Diff against target: 191 lines (+80/-31)
3 files modified
src/dbus_screen.cpp (+60/-28)
src/dbus_screen.h (+12/-1)
src/system_compositor.cpp (+8/-2)
To merge this branch: bzr merge lp:~albaguirre/unity-system-compositor/add-power-off-delay-option
Reviewer Review Type Date Requested Status
Michael Terry (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+208281@code.launchpad.net

Commit message

Add an optional delay when powering off screen.

Add an option (power-off-delay, defaulted to 0) to delay stopping the compositor and powering off the screen to allow the shell to present a shutdown animation; without delay, the shell and-or greeter will get blocked while trying to render such animation; this is due to the compositor stopping as USC receives the power state change before the shell.

This is mostly a workaround as ideally, the greeter and-or shell should coordinate when to shutdown the screen after they are given a chance to possibly show a shutdown animation.

fixes: lp: #1233564

Description of the change

Add an optional delay when powering off screen.

Add an option (power-off-delay, defaulted to 0) to delay stopping the compositor and powering off the screen to allow the shell to present a shutdown animation; without delay, the shell and-or greeter will get blocked while trying to render such animation; this is due to the compositor stopping as USC receives the power state change before the shell.

This is mostly a workaround as ideally, the greeter and-or shell should coordinate when to shutdown the screen after they are given a chance to possibly show a shutdown animation.

fixes: lp: #1233564

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michael Terry (mterry) wrote :

Seems fine, worked for me when passing --power-off-delay=500 to USC.

review: Approve
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

Note that to actually see the delay in action you need powerd to avoid touching the backlight before notifying USC:

https://code.launchpad.net/~albaguirre/powerd/let-display-turn-off-backlight/+merge/208667

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

displayConfig::configure_output

no longer exists in mir/devel

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/dbus_screen.cpp'
2--- src/dbus_screen.cpp 2014-02-04 14:43:09 +0000
3+++ src/dbus_screen.cpp 2014-02-26 06:33:04 +0000
4@@ -28,15 +28,59 @@
5 namespace mc = mir::compositor;
6 namespace mg = mir::graphics;
7
8+static void set_screen_power_mode(MirPowerMode mode, const std::shared_ptr<mir::DefaultServerConfiguration>& config)
9+{
10+ std::shared_ptr<mg::Display> display = config->the_display();
11+ std::shared_ptr<mg::DisplayConfiguration> displayConfig = display->configuration();
12+ std::shared_ptr<mc::Compositor> compositor = config->the_compositor();
13+
14+ displayConfig->for_each_output([&](const mg::DisplayConfigurationOutput displayConfigOutput) {
15+ if (displayConfigOutput.power_mode != mode) {
16+ displayConfig->configure_output(
17+ displayConfigOutput.id, //unchanged
18+ displayConfigOutput.used, //unchanged
19+ displayConfigOutput.top_left, //unchanged
20+ displayConfigOutput.current_mode_index, //unchanged
21+ displayConfigOutput.current_format,
22+ mode,
23+ displayConfigOutput.orientation //unchanged
24+ );
25+ }
26+ });
27+
28+ if (mode != MirPowerMode::mir_power_mode_on)
29+ compositor->stop();
30+
31+ display->configure(*displayConfig.get());
32+
33+ if (mode == MirPowerMode::mir_power_mode_on)
34+ compositor->start();
35+}
36+
37 // Note: this class should be created only after when the Mir DisplayServer has started
38-DBusScreen::DBusScreen(std::shared_ptr<mir::DefaultServerConfiguration> config, QObject *parent)
39- : QObject(parent)
40- , config(config)
41+DBusScreen::DBusScreen(std::shared_ptr<mir::DefaultServerConfiguration> config,
42+ int off_delay, QObject *parent)
43+ : QObject(parent),
44+ config(config),
45+ power_off_timer(off_delay > 0 ? new QTimer(this) : nullptr),
46+ power_off_mode(MirPowerMode::mir_power_mode_off),
47+ power_off_delay(off_delay)
48+
49 {
50 new DBusScreenAdaptor(this);
51 QDBusConnection bus = QDBusConnection::systemBus();
52 bus.registerObject("/com/canonical/Unity/Screen", this);
53 bus.registerService("com.canonical.Unity.Screen");
54+
55+ if (power_off_timer != nullptr) {
56+ power_off_timer->setSingleShot(true);
57+ connect(power_off_timer, SIGNAL(timeout()), this, SLOT(power_off()));
58+ }
59+}
60+
61+DBusScreen::~DBusScreen()
62+{
63+ delete power_off_timer;
64 }
65
66 bool DBusScreen::setScreenPowerMode(const QString &mode)
67@@ -46,6 +90,8 @@
68
69 if (mode == "on") {
70 newPowerMode = MirPowerMode::mir_power_mode_on;
71+ if (power_off_timer != nullptr && power_off_timer->isActive())
72+ power_off_timer->stop();
73 } else if (mode == "standby") {
74 newPowerMode = MirPowerMode::mir_power_mode_standby; // higher power "off" mode (fastest resume)
75 } else if (mode == "suspend") {
76@@ -57,31 +103,17 @@
77 return false;
78 }
79
80- std::shared_ptr<mg::Display> display = config->the_display();
81- std::shared_ptr<mg::DisplayConfiguration> displayConfig = display->configuration();
82- std::shared_ptr<mc::Compositor> compositor = config->the_compositor();
83-
84- displayConfig->for_each_output([&](const mg::DisplayConfigurationOutput displayConfigOutput) {
85- if (displayConfigOutput.power_mode != newPowerMode) {
86- displayConfig->configure_output(
87- displayConfigOutput.id, //unchanged
88- displayConfigOutput.used, //unchanged
89- displayConfigOutput.top_left, //unchanged
90- displayConfigOutput.current_mode_index, //unchanged
91- displayConfigOutput.current_format,
92- newPowerMode,
93- displayConfigOutput.orientation //unchanged
94- );
95- }
96- });
97-
98- if (newPowerMode != MirPowerMode::mir_power_mode_on)
99- compositor->stop();
100-
101- display->configure(*displayConfig.get());
102-
103- if (newPowerMode == MirPowerMode::mir_power_mode_on)
104- compositor->start();
105+ if ((newPowerMode != MirPowerMode::mir_power_mode_on) && (power_off_timer != nullptr)) {
106+ power_off_mode = newPowerMode;
107+ power_off_timer->start(power_off_delay);
108+ } else {
109+ set_screen_power_mode(newPowerMode, config);
110+ }
111
112 return true;
113 }
114+
115+void DBusScreen::power_off()
116+{
117+ set_screen_power_mode(power_off_mode, config);
118+}
119
120=== modified file 'src/dbus_screen.h'
121--- src/dbus_screen.h 2013-10-31 19:16:23 +0000
122+++ src/dbus_screen.h 2014-02-26 06:33:04 +0000
123@@ -17,8 +17,11 @@
124 #ifndef DBUS_SCREEN_H_
125 #define DBUS_SCREEN_H_
126
127+#include <mir_toolkit/common.h>
128+
129 #include <memory>
130 #include <QObject>
131+#include <QtCore>
132
133 namespace mir
134 {
135@@ -31,13 +34,21 @@
136 Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity.Screen")
137
138 public:
139- explicit DBusScreen(std::shared_ptr<mir::DefaultServerConfiguration> config, QObject *parent = 0);
140+ explicit DBusScreen(std::shared_ptr<mir::DefaultServerConfiguration> config,
141+ int off_delay, QObject *parent = 0);
142+ virtual ~DBusScreen();
143
144 public Q_SLOTS:
145 bool setScreenPowerMode(const QString &mode);
146
147+private Q_SLOTS:
148+ void power_off();
149+
150 private:
151 std::shared_ptr<mir::DefaultServerConfiguration> config;
152+ QTimer *power_off_timer;
153+ MirPowerMode power_off_mode;
154+ int power_off_delay;
155 };
156
157 #endif /* DBUS_SCREEN_H_ */
158
159=== modified file 'src/system_compositor.cpp'
160--- src/system_compositor.cpp 2014-02-10 14:55:13 +0000
161+++ src/system_compositor.cpp 2014-02-26 06:33:04 +0000
162@@ -96,7 +96,8 @@
163 ("to-dm-fd", po::value<int>(), "File descriptor of write end of pipe to display manager [int]")
164 ("blacklist", po::value<std::string>(), "Video blacklist regex to use")
165 ("version", "Show version of Unity System Compositor")
166- ("public-socket", po::value<bool>(), "Make the socket file publicly writable");
167+ ("public-socket", po::value<bool>(), "Make the socket file publicly writable")
168+ ("power-off-delay", po::value<int>(), "Delay in milliseconds before powering off screen [int]");
169 }
170
171 int from_dm_fd()
172@@ -114,6 +115,11 @@
173 return the_options()->is_set ("version");
174 }
175
176+ int power_off_delay()
177+ {
178+ return the_options()->get("power-off-delay", 0);
179+ }
180+
181 std::string blacklist()
182 {
183 auto x = the_options()->get ("blacklist", "");
184@@ -331,6 +337,6 @@
185 void SystemCompositor::qt_main(int argc, char **argv)
186 {
187 QCoreApplication app(argc, argv);
188- DBusScreen dbus_screen(config);
189+ DBusScreen dbus_screen(config, config->power_off_delay());
190 app.exec();
191 }

Subscribers

People subscribed via source and target branches