Merge lp:~brandontschaefer/unity/lockscreen-caps-lock-detector into lp:unity

Proposed by Brandon Schaefer
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 3775
Proposed branch: lp:~brandontschaefer/unity/lockscreen-caps-lock-detector
Merge into: lp:unity
Diff against target: 353 lines (+128/-18)
9 files modified
lockscreen/LockScreenAbstractShield.h (+1/-0)
lockscreen/LockScreenController.cpp (+1/-0)
lockscreen/LockScreenShield.cpp (+6/-0)
lockscreen/LockScreenShield.h (+3/-2)
lockscreen/UserPromptView.cpp (+100/-4)
lockscreen/UserPromptView.h (+14/-1)
tests/test_lockscreen_controller.cpp (+1/-0)
unity-shared/CompizUtils.cpp (+2/-10)
unity-shared/CompizUtils.h (+0/-1)
To merge this branch: bzr merge lp:~brandontschaefer/unity/lockscreen-caps-lock-detector
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Marco Trevisan (Treviño) Approve
Review via email: mp+213707@code.launchpad.net

Commit message

When we detect caps lock, or caps lock is pressed, render a warning icon to show its on.

Description of the change

When we detect caps lock, or caps lock is pressed, render a warning icon to show its on.

To post a comment you must log in.
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Cool, looks good to me!

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lockscreen/LockScreenAbstractShield.h'
2--- lockscreen/LockScreenAbstractShield.h 2014-03-24 21:36:55 +0000
3+++ lockscreen/LockScreenAbstractShield.h 2014-04-09 17:10:19 +0000
4@@ -47,6 +47,7 @@
5
6 using MockableBaseWindow::RemoveLayout;
7 virtual bool IsIndicatorOpen() const = 0;
8+ virtual void CheckCapsLockPrompt() = 0;
9
10 sigc::signal<void, int, int> grab_motion;
11
12
13=== modified file 'lockscreen/LockScreenController.cpp'
14--- lockscreen/LockScreenController.cpp 2014-03-24 21:36:55 +0000
15+++ lockscreen/LockScreenController.cpp 2014-04-09 17:10:19 +0000
16@@ -101,6 +101,7 @@
17
18 primary_shield_->primary = false;
19 primary_shield_ = shield;
20+ primary_shield_->CheckCapsLockPrompt();
21 shield->primary = true;
22 auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
23 motion_connection_ = shield->grab_motion.connect(move_cb);
24
25=== modified file 'lockscreen/LockScreenShield.cpp'
26--- lockscreen/LockScreenShield.cpp 2014-03-07 19:35:46 +0000
27+++ lockscreen/LockScreenShield.cpp 2014-04-09 17:10:19 +0000
28@@ -86,6 +86,12 @@
29 }
30 }
31
32+void Shield::CheckCapsLockPrompt()
33+{
34+ if (prompt_view_)
35+ prompt_view_->CheckIfCapsLockOn();
36+}
37+
38 void Shield::ShowPrimaryView()
39 {
40 GrabPointer();
41
42=== modified file 'lockscreen/LockScreenShield.h'
43--- lockscreen/LockScreenShield.h 2014-03-07 19:17:35 +0000
44+++ lockscreen/LockScreenShield.h 2014-04-09 17:10:19 +0000
45@@ -38,7 +38,8 @@
46 public:
47 Shield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, int monitor, bool is_primary);
48
49- bool IsIndicatorOpen() const;
50+ bool IsIndicatorOpen() const override;
51+ void CheckCapsLockPrompt() override;
52
53 protected:
54 bool AcceptKeyNavFocus() override;
55@@ -64,4 +65,4 @@
56 }
57 }
58
59-#endif
60\ No newline at end of file
61+#endif
62
63=== modified file 'lockscreen/UserPromptView.cpp'
64--- lockscreen/UserPromptView.cpp 2014-03-26 18:52:13 +0000
65+++ lockscreen/UserPromptView.cpp 2014-04-09 17:10:19 +0000
66@@ -21,9 +21,12 @@
67
68 #include <boost/algorithm/string/trim.hpp>
69 #include <Nux/VLayout.h>
70+#include <X11/XKBlib.h>
71
72 #include "LockScreenSettings.h"
73 #include "unity-shared/CairoTexture.h"
74+#include "unity-shared/DashStyle.h"
75+#include "unity-shared/PreviewStyle.h"
76 #include "unity-shared/TextInput.h"
77 #include "unity-shared/StaticCairoText.h"
78 #include "unity-shared/RawPixel.h"
79@@ -34,11 +37,12 @@
80 {
81 namespace
82 {
83-const RawPixel PADDING = 10_em;
84-const RawPixel LAYOUT_MARGIN = 10_em;
85-const RawPixel MSG_LAYOUT_MARGIN = 15_em;
86+const RawPixel PADDING = 10_em;
87+const RawPixel LAYOUT_MARGIN = 10_em;
88+const RawPixel MSG_LAYOUT_MARGIN = 15_em;
89 const RawPixel PROMPT_LAYOUT_MARGIN = 5_em;
90-const int PROMPT_FONT_SIZE = 13;
91+
92+const int PROMPT_FONT_SIZE = 13;
93
94 nux::AbstractPaintLayer* CrateBackgroundLayer(int width, int height)
95 {
96@@ -74,6 +78,28 @@
97 rop));
98 }
99
100+nux::AbstractPaintLayer* CreateWarningLayer(nux::BaseTexture* texture)
101+{
102+ // Create the texture layer
103+ nux::TexCoordXForm texxform;
104+
105+ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
106+ texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
107+ texxform.min_filter = nux::TEXFILTER_LINEAR;
108+ texxform.mag_filter = nux::TEXFILTER_LINEAR;
109+
110+ nux::ROPConfig rop;
111+ rop.Blend = true;
112+ rop.SrcBlend = GL_ONE;
113+ rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
114+
115+ return (new nux::TextureLayer(texture->GetDeviceTexture(),
116+ texxform,
117+ nux::color::White,
118+ true,
119+ rop));
120+}
121+
122 std::string SanitizeMessage(std::string const& message)
123 {
124 std::string msg = boost::algorithm::trim_copy(message);
125@@ -98,6 +124,7 @@
126 UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager)
127 : nux::View(NUX_TRACKER_LOCATION)
128 , session_manager_(session_manager)
129+ , caps_lock_on_(false)
130 {
131 user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
132 AddPrompt(message, /* visible */ true, promise);
133@@ -119,10 +146,32 @@
134 ResetLayout();
135 });
136
137+ dash::previews::Style& preview_style = dash::previews::Style::Instance();
138+
139+ warning_ = preview_style.GetWarningIcon();
140 ResetLayout();
141
142 user_authenticator_.AuthenticateStart(session_manager_->UserName(),
143 sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
144+
145+ // When we get to HiDPI changes here, we will need to update this width
146+ dash::Style& style = dash::Style::Instance();
147+ spin_icon_width_ = style.GetSearchSpinIcon()->GetWidth();
148+
149+ CheckIfCapsLockOn();
150+}
151+
152+void UserPromptView::CheckIfCapsLockOn()
153+{
154+ Display *dpy = nux::GetGraphicsDisplay()->GetX11Display();
155+ unsigned int state = 0;
156+ XkbGetIndicatorState(dpy, XkbUseCoreKbd, &state);
157+
158+ // Caps is on 0x1, couldn't find any #define in /usr/include/X11
159+ if ((state & 0x1) == 1)
160+ caps_lock_on_ = true;
161+ else
162+ caps_lock_on_ = false;
163 }
164
165 bool UserPromptView::InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character)
166@@ -211,6 +260,15 @@
167 nux::GetPainter().PushLayer(graphics_engine, geo, bg_layer_.get());
168 }
169
170+ if (caps_lock_on_)
171+ {
172+ for (auto const& text_entry : focus_queue_)
173+ PaintWarningIcon(graphics_engine, text_entry->GetGeometry());
174+
175+ if (focus_queue_.empty())
176+ PaintWarningIcon(graphics_engine, cached_focused_geo_);
177+ }
178+
179 if (GetLayout())
180 GetLayout()->ProcessDraw(graphics_engine, force_draw);
181
182@@ -220,6 +278,19 @@
183 graphics_engine.PopClippingRectangle();
184 }
185
186+void UserPromptView::PaintWarningIcon(nux::GraphicsEngine& graphics_engine, nux::Geometry const& geo)
187+{
188+ nux::Geometry warning_geo = {geo.x + geo.width - GetWarningIconOffset(),
189+ geo.y, warning_->GetWidth(), warning_->GetHeight()};
190+
191+ nux::GetPainter().PushLayer(graphics_engine, warning_geo, CreateWarningLayer(warning_));
192+}
193+
194+int UserPromptView::GetWarningIconOffset()
195+{
196+ return warning_->GetWidth() + spin_icon_width_;
197+}
198+
199 nux::View* UserPromptView::focus_view()
200 {
201 if (focus_queue_.empty())
202@@ -232,6 +303,26 @@
203 return focus_queue_.front();
204 }
205
206+void UserPromptView::ToggleCapsLockBool()
207+{
208+ caps_lock_on_ = !caps_lock_on_;
209+ QueueDraw();
210+}
211+
212+void UserPromptView::RecvKeyUp(unsigned keysym,
213+ unsigned long keycode,
214+ unsigned long state)
215+{
216+ if (!caps_lock_on_ && keysym == NUX_VK_CAPITAL)
217+ {
218+ ToggleCapsLockBool();
219+ }
220+ else if (caps_lock_on_ && keysym == NUX_VK_CAPITAL)
221+ {
222+ ToggleCapsLockBool();
223+ }
224+}
225+
226 void UserPromptView::AddPrompt(std::string const& message, bool visible, PromiseAuthCodePtr const& promise)
227 {
228 auto* text_input = new unity::TextInput();
229@@ -243,11 +334,15 @@
230 text_entry->SetPasswordChar("•");
231 text_entry->SetToggleCursorVisibilityOnKeyFocus(true);
232
233+ text_entry->key_up.connect(sigc::mem_fun(this, &UserPromptView::RecvKeyUp));
234+
235 text_input->SetMinimumHeight(Settings::GRID_SIZE);
236 text_input->SetMaximumHeight(Settings::GRID_SIZE);
237 prompt_layout_->AddView(text_input, 1);
238 focus_queue_.push_back(text_entry);
239
240+ CheckIfCapsLockOn();
241+
242 // Don't remove it, it helps with a11y.
243 if (focus_queue_.size() == 1)
244 nux::GetWindowCompositor().SetKeyFocusArea(text_entry);
245@@ -261,6 +356,7 @@
246
247 focus_queue_.pop_front();
248 auto* text_entry = text_input->text_entry();
249+ cached_focused_geo_ = text_entry->GetGeometry();
250 text_entry->SetInputEventSensitivity(false);
251 QueueRelayout();
252 QueueDraw();
253
254=== modified file 'lockscreen/UserPromptView.h'
255--- lockscreen/UserPromptView.h 2014-03-25 18:39:24 +0000
256+++ lockscreen/UserPromptView.h 2014-04-09 17:10:19 +0000
257@@ -29,7 +29,6 @@
258
259 #include "UserAuthenticatorPam.h"
260 #include "unity-shared/IMTextEntry.h"
261-#include "unity-shared/SearchBarSpinner.h"
262
263 namespace nux
264 {
265@@ -57,6 +56,8 @@
266 void AddMessage(std::string const& message, nux::Color const& color);
267 void AuthenticationCb(bool authenticated);
268
269+ void CheckIfCapsLockOn();
270+
271 protected:
272 void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) override;
273 void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw) override;
274@@ -65,6 +66,12 @@
275 void ResetLayout();
276
277 bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character);
278+ void RecvKeyUp(unsigned int, unsigned long, unsigned long);
279+
280+ void PaintWarningIcon(nux::GraphicsEngine& graphics_engine, nux::Geometry const& geo);
281+ void ToggleCapsLockBool();
282+
283+ int GetWarningIconOffset();
284
285 session::Manager::Ptr session_manager_;
286 UserAuthenticatorPam user_authenticator_;
287@@ -75,6 +82,12 @@
288 StaticCairoText* error_;
289 StaticCairoText* invalid_login_;
290 std::deque<IMTextEntry*> focus_queue_;
291+
292+ nux::BaseTexture* warning_;
293+ nux::Geometry cached_focused_geo_;
294+
295+ bool caps_lock_on_;
296+ int spin_icon_width_;
297 };
298
299 }
300
301=== modified file 'tests/test_lockscreen_controller.cpp'
302--- tests/test_lockscreen_controller.cpp 2014-03-21 23:08:47 +0000
303+++ tests/test_lockscreen_controller.cpp 2014-04-09 17:10:19 +0000
304@@ -68,6 +68,7 @@
305 {}
306
307 MOCK_CONST_METHOD0(IsIndicatorOpen, bool());
308+ MOCK_METHOD0(CheckCapsLockPrompt, void());
309 };
310
311 struct ShieldFactoryMock : ShieldFactoryInterface
312
313=== modified file 'unity-shared/CompizUtils.cpp'
314--- unity-shared/CompizUtils.cpp 2014-03-29 02:10:18 +0000
315+++ unity-shared/CompizUtils.cpp 2014-04-09 17:10:19 +0000
316@@ -180,8 +180,8 @@
317 if (win->region().numRects() != 1) // Non rectangular windows
318 return false;
319
320- if (win->alpha())
321- return WindowHasMotifDecorations(win);
322+ if (win->overrideRedirect() && win->alpha())
323+ return false;
324
325 return true;
326 }
327@@ -194,14 +194,6 @@
328 if (!IsWindowShadowDecorable(win))
329 return false;
330
331- return WindowHasMotifDecorations(win);
332-}
333-
334-bool WindowHasMotifDecorations(CompWindow* win)
335-{
336- if (!win)
337- return false;
338-
339 if (win->overrideRedirect())
340 return false;
341
342
343=== modified file 'unity-shared/CompizUtils.h'
344--- unity-shared/CompizUtils.h 2014-03-29 02:10:18 +0000
345+++ unity-shared/CompizUtils.h 2014-04-09 17:10:19 +0000
346@@ -113,7 +113,6 @@
347
348 bool IsWindowShadowDecorable(CompWindow*);
349 bool IsWindowFullyDecorable(CompWindow*);
350-bool WindowHasMotifDecorations(CompWindow*);
351
352 } // compiz_utils namespace
353 } // unity namespace