Merge lp:~gordallott/unity/hud into lp:unity

Proposed by Gord Allott
Status: Superseded
Proposed branch: lp:~gordallott/unity/hud
Merge into: lp:unity
Diff against target: 4111 lines (+3217/-162)
36 files modified
CMakeLists.txt (+2/-2)
UnityCore/CMakeLists.txt (+2/-0)
UnityCore/GLibDBusProxy.cpp (+0/-1)
UnityCore/Hud.cpp (+239/-0)
UnityCore/Hud.h (+127/-0)
manual-tests/Hud.txt (+57/-0)
plugins/unityshell/src/DashController.cpp (+5/-3)
plugins/unityshell/src/DashStyle.cpp (+1/-0)
plugins/unityshell/src/HudButton.cpp (+182/-0)
plugins/unityshell/src/HudButton.h (+76/-0)
plugins/unityshell/src/HudController.cpp (+364/-0)
plugins/unityshell/src/HudController.h (+113/-0)
plugins/unityshell/src/HudIcon.cpp (+91/-0)
plugins/unityshell/src/HudIcon.h (+69/-0)
plugins/unityshell/src/HudSearchBar.cpp (+404/-0)
plugins/unityshell/src/HudSearchBar.h (+116/-0)
plugins/unityshell/src/HudView.cpp (+377/-0)
plugins/unityshell/src/HudView.h (+115/-0)
plugins/unityshell/src/IconTexture.cpp (+23/-10)
plugins/unityshell/src/Launcher.cpp (+44/-26)
plugins/unityshell/src/Launcher.h (+2/-2)
plugins/unityshell/src/PanelMenuView.cpp (+2/-2)
plugins/unityshell/src/PanelView.cpp (+2/-2)
plugins/unityshell/src/PlacesHomeView.cpp (+1/-1)
plugins/unityshell/src/UBusMessages.h (+7/-3)
plugins/unityshell/src/WindowButtons.cpp (+21/-13)
plugins/unityshell/src/unityshell.cpp (+77/-39)
plugins/unityshell/src/unityshell.h (+8/-1)
plugins/unityshell/unityshell.xml.in (+46/-41)
standalone-clients/CMakeLists.txt (+33/-0)
standalone-clients/StandaloneHud.cpp (+170/-0)
tests/CMakeLists.txt (+13/-10)
tests/test_hud.cpp (+104/-0)
tests/test_service_hud.c (+268/-0)
tests/test_service_hud.h (+46/-0)
tests/test_service_main.c (+10/-6)
To merge this branch: bzr merge lp:~gordallott/unity/hud
Reviewer Review Type Date Requested Status
Michal Hruby (community) Needs Information
Review via email: mp+90082@code.launchpad.net

This proposal has been superseded by a proposal from 2012-01-25.

To post a comment you must log in.
Revision history for this message
Michal Hruby (mhr3) wrote :

50 - self->owner_->connected.emit();

Why is this needed?

review: Needs Information

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2011-12-19 22:18:53 +0000
3+++ CMakeLists.txt 2012-01-25 11:34:37 +0000
4@@ -8,7 +8,7 @@
5 #
6 set (PROJECT_NAME "unity")
7 set (UNITY_MAJOR 5)
8-set (UNITY_MINOR 0)
9+set (UNITY_MINOR 1)
10 set (UNITY_MICRO 0)
11 set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}")
12 set (UNITY_API_VERSION "5.0")
13@@ -110,7 +110,7 @@
14 SET (BOOT_LOGGER_FLAG "-DENABLE_LOGGER")
15 endif (BOOT_LOGGER)
16
17-SET (MAINTAINER_CFLAGS "-Werror -Wall -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self -Warray-bounds")
18+SET (MAINTAINER_CFLAGS "-Wall -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self -Warray-bounds")
19 option (DISABLE_MAINTAINER_CFLAGS "Disable maintainer CFlags" OFF)
20 if (DISABLE_MAINTAINER_CFLAGS)
21 SET (MAINTAINER_CFLAGS "")
22
23=== modified file 'UnityCore/CMakeLists.txt'
24--- UnityCore/CMakeLists.txt 2012-01-17 16:02:39 +0000
25+++ UnityCore/CMakeLists.txt 2012-01-25 11:34:37 +0000
26@@ -21,6 +21,7 @@
27 GLibSignal-inl.h
28 GLibWrapper.h
29 GLibWrapper-inl.h
30+ Hud.h
31 IndicatorEntry.h
32 Indicator.h
33 Indicators.h
34@@ -53,6 +54,7 @@
35 GLibDBusProxy.cpp
36 GLibSignal.cpp
37 GLibWrapper.cpp
38+ Hud.cpp
39 Indicator.cpp
40 IndicatorEntry.cpp
41 Indicators.cpp
42
43=== modified file 'UnityCore/GLibDBusProxy.cpp'
44--- UnityCore/GLibDBusProxy.cpp 2012-01-16 15:19:47 +0000
45+++ UnityCore/GLibDBusProxy.cpp 2012-01-25 11:34:37 +0000
46@@ -144,7 +144,6 @@
47 LOG_DEBUG(logger) << self->name_ << " appeared";
48
49 self->connected_ = true;
50- self->owner_->connected.emit();
51 }
52
53 void DBusProxy::Impl::OnNameVanished(GDBusConnection* connection,
54
55=== added file 'UnityCore/Hud.cpp'
56--- UnityCore/Hud.cpp 1970-01-01 00:00:00 +0000
57+++ UnityCore/Hud.cpp 2012-01-25 11:34:37 +0000
58@@ -0,0 +1,239 @@
59+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
60+/*
61+ * Copyright (C) 2011 Canonical Ltd
62+ *
63+ * This program is free software: you can redistribute it and/or modify
64+ * it under the terms of the GNU General Public License version 3 as
65+ * published by the Free Software Foundation.
66+ *
67+ * This program is distributed in the hope that it will be useful,
68+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
69+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
70+ * GNU General Public License for more details.
71+ *
72+ * You should have received a copy of the GNU General Public License
73+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
74+ *
75+ * Authored by: Gordon Allott <gord.allott@canonical.com>
76+ */
77+//
78+#include "Hud.h"
79+
80+#include <gio/gio.h>
81+#include <glib.h>
82+#include <NuxCore/Logger.h>
83+#include "GLibWrapper.h"
84+#include "GLibDBusProxy.h"
85+
86+#include "config.h"
87+
88+#include <sigc++/bind.h>
89+
90+namespace unity
91+{
92+namespace hud
93+{
94+
95+namespace
96+{
97+nux::logging::Logger logger("unity.hud.hud");
98+const int request_number_of_results = 6;
99+}
100+
101+// Impl classes
102+class HudImpl
103+{
104+public:
105+ HudImpl(std::string const& dbus_name,
106+ std::string const& dbus_path,
107+ Hud *parent)
108+ : query_key_(NULL)
109+ , proxy_(dbus_name, dbus_path, "com.canonical.hud")
110+ , parent_(parent)
111+ {
112+ LOG_DEBUG(logger) << "Hud init with name: " << dbus_name << "and path: " << dbus_path;
113+ proxy_.connected.connect([&]() {
114+ LOG_DEBUG(logger) << "Hud Connected";
115+ parent_->connected = true;
116+ });
117+
118+ proxy_.Connect("UpdatedQuery", sigc::mem_fun(this, &HudImpl::UpdateQueryCallback));
119+ }
120+
121+ void QueryCallback(GVariant* data);
122+ void UpdateQueryCallback(GVariant* data);
123+ void BuildQueries(GVariant* query_array);
124+ void ExecuteByKey(GVariant* key, unsigned int timestamp);
125+ void ExecuteQueryByStringCallback(GVariant* query, unsigned int timestamp);
126+ void CloseQuery();
127+
128+ GVariant* query_key_;
129+ Hud::Queries queries_;
130+ glib::DBusProxy proxy_;
131+ Hud* parent_;
132+};
133+
134+void HudImpl::ExecuteByKey(GVariant* key, unsigned int timestamp)
135+{
136+ LOG_DEBUG(logger) << "Executing by Key";
137+
138+ GVariantBuilder tuple;
139+ g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE);
140+ g_variant_builder_add_value(&tuple, g_variant_new_variant(key));
141+ g_variant_builder_add_value(&tuple, g_variant_new_uint32(timestamp));
142+
143+ proxy_.Call("ExecuteQuery", g_variant_builder_end(&tuple));
144+}
145+
146+void HudImpl::ExecuteQueryByStringCallback(GVariant* query, unsigned int timestamp)
147+{
148+ queries_.clear();
149+
150+ GVariant* query_key = g_variant_get_child_value(query, 2);
151+ query_key_ = query_key;
152+
153+ GVariant* queries = g_variant_get_child_value(query, 1);
154+ BuildQueries(queries);
155+ g_variant_unref(queries);
156+
157+ if (queries_.empty() == false)
158+ {
159+ // we now execute based off the first result
160+ ExecuteByKey(queries_.front()->key, timestamp);
161+ CloseQuery();
162+ }
163+}
164+
165+void HudImpl::QueryCallback(GVariant* query)
166+{
167+ queries_.clear();
168+
169+ // extract the information from the GVariants
170+ GVariant* target = g_variant_get_child_value(query, 0);
171+ g_variant_unref(target);
172+
173+ GVariant* query_key = g_variant_get_child_value(query, 2);
174+ query_key_ = query_key;
175+
176+ GVariant* queries = g_variant_get_child_value(query, 1);
177+ BuildQueries(queries);
178+ g_variant_unref(queries);
179+
180+ parent_->queries_updated.emit(queries_);
181+}
182+
183+void HudImpl::UpdateQueryCallback(GVariant* query)
184+{
185+ // as we are expecting an update, we want to check
186+ // and make sure that we are the actual recievers of
187+ // the signal
188+
189+ GVariant* query_key = g_variant_get_child_value(query, 2);
190+ if (g_variant_equal(query_key_, query_key))
191+ {
192+ GVariant* queries = g_variant_get_child_value(query, 1);
193+ BuildQueries(queries);
194+ g_variant_unref(queries);
195+ }
196+}
197+
198+void HudImpl::BuildQueries(GVariant* query_array)
199+{
200+ GVariantIter iter;
201+ g_variant_iter_init(&iter, query_array);
202+ glib::String formatted_text;
203+ glib::String icon;
204+ glib::String item_icon;
205+ glib::String completion_text;
206+ glib::String shortcut;
207+ GVariant* key = NULL;
208+
209+ while (g_variant_iter_loop(&iter, "(sssssv)",
210+ &formatted_text, &icon, &item_icon, &completion_text, &shortcut, &key))
211+ {
212+ queries_.push_back(Query::Ptr(new Query(std::string(formatted_text),
213+ std::string(icon),
214+ std::string(item_icon),
215+ std::string(completion_text),
216+ std::string(shortcut),
217+ key)));
218+ }
219+}
220+
221+void HudImpl::CloseQuery()
222+{
223+ if (query_key_ == NULL)
224+ {
225+ LOG_WARN(logger) << "Attempted to close the hud connection without starting it";
226+ }
227+ else
228+ {
229+ GVariant* paramaters = g_variant_new("(v)", query_key_);
230+ proxy_.Call("CloseQuery", paramaters);
231+ g_variant_unref(query_key_);
232+ query_key_ = NULL;
233+ queries_.clear();
234+ }
235+}
236+
237+
238+Hud::Hud(std::string const& dbus_name,
239+ std::string const& dbus_path)
240+ : connected(false)
241+ , pimpl_(new HudImpl(dbus_name, dbus_path, this))
242+{
243+ pimpl_->parent_ = this;
244+}
245+
246+Hud::~Hud()
247+{
248+ delete pimpl_;
249+}
250+
251+void Hud::RequestQuery(std::string const& search_string)
252+{
253+ LOG_DEBUG(logger) << "Getting Query: " << search_string;
254+ if (pimpl_->query_key_ != NULL)
255+ {
256+ CloseQuery();
257+ }
258+
259+ GVariant* paramaters = g_variant_new("(si)",
260+ search_string.c_str(),
261+ request_number_of_results);
262+ pimpl_->proxy_.Call("StartQuery", paramaters, sigc::mem_fun(this->pimpl_, &HudImpl::QueryCallback));
263+}
264+
265+
266+void Hud::ExecuteQuery(Query::Ptr query, unsigned int timestamp)
267+{
268+ LOG_DEBUG(logger) << "Executing query: " << query->formatted_text;
269+ pimpl_->ExecuteByKey(query->key, timestamp);
270+}
271+
272+void Hud::ExecuteQueryBySearch(std::string execute_string, unsigned int timestamp)
273+{
274+ //Does a search then executes the result based on that search
275+ LOG_DEBUG(logger) << "Executing by string" << execute_string;
276+ if (pimpl_->query_key_ != NULL)
277+ {
278+ CloseQuery();
279+ }
280+
281+ GVariant* paramaters = g_variant_new("(si)",
282+ execute_string.c_str(),
283+ 1);
284+
285+ auto functor = sigc::mem_fun(this->pimpl_, &HudImpl::ExecuteQueryByStringCallback);
286+
287+ pimpl_->proxy_.Call("StartQuery", paramaters, sigc::bind(functor, timestamp));
288+}
289+
290+void Hud::CloseQuery()
291+{
292+ //Send close hint to the hud
293+ pimpl_->CloseQuery();
294+}
295+
296+}
297+}
298
299=== added file 'UnityCore/Hud.h'
300--- UnityCore/Hud.h 1970-01-01 00:00:00 +0000
301+++ UnityCore/Hud.h 2012-01-25 11:34:37 +0000
302@@ -0,0 +1,127 @@
303+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
304+/*
305+ * Copyright (C) 2011 Canonical Ltd
306+ *
307+ * This program is free software: you can redistribute it and/or modify
308+ * it under the terms of the GNU General Public License version 3 as
309+ * published by the Free Software Foundation.
310+ *
311+ * This program is distributed in the hope that it will be useful,
312+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
314+ * GNU General Public License for more details.
315+ *
316+ * You should have received a copy of the GNU General Public License
317+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
318+ *
319+ * Authored by: Gordon Allott <gord.allott@canonical.com>
320+ */
321+
322+#ifndef UNITY_HUD_H
323+#define UNITY_HUD_H
324+
325+#include <deque>
326+#include <string>
327+#include <memory>
328+#include <NuxCore/Property.h>
329+#include <glib/gvariant.h>
330+
331+namespace unity
332+{
333+namespace hud
334+{
335+
336+
337+class Query
338+{
339+public:
340+ typedef std::shared_ptr<Query> Ptr;
341+
342+ Query(std::string const& formatted_text_, std::string const& icon_name_,
343+ std::string const& item_icon_, std::string const& completion_text_,
344+ std::string const& shortcut_, GVariant* key_)
345+ : formatted_text(formatted_text_)
346+ , icon_name(icon_name_)
347+ , item_icon(item_icon_)
348+ , completion_text(completion_text_)
349+ , shortcut(shortcut_)
350+ , key(key_)
351+ {
352+ g_variant_ref(key);
353+ }
354+
355+ ~Query()
356+ {
357+ g_variant_unref(key);
358+ }
359+
360+ Query(const Query &rhs);
361+ Query& operator=(Query);
362+
363+ std::string formatted_text; // Pango formatted text
364+ std::string icon_name; // icon name using standard lookups
365+ std::string item_icon; // Future API
366+ std::string completion_text; // Non formatted text f or completion
367+ std::string shortcut; // Shortcut key
368+ GVariant *key;
369+};
370+
371+
372+class HudImpl;
373+class Hud
374+{
375+public:
376+ typedef std::shared_ptr<Hud> Ptr;
377+ typedef std::deque<Query::Ptr> Queries;
378+
379+ /*
380+ * Constructor for the hud
381+ * \param dbus_name string that specifies the name of the hud service
382+ * \param dbus_path string that specifies the path of the hud service
383+ */
384+ Hud(std::string const& dbus_name,
385+ std::string const& dbus_path);
386+
387+ ~Hud();
388+
389+ Hud(const Hud &rhs);
390+ Hud& operator=(Hud);
391+
392+ nux::Property<std::string> target;
393+ nux::Property<bool> connected;
394+
395+ /*
396+ * Queries the service for new suggestions, will fire off the
397+ * suggestion_search_finished signal when the suggestions are returned
398+ */
399+ void RequestQuery(std::string const& search_string);
400+
401+ /*
402+ * Executes a Query
403+ */
404+ void ExecuteQuery(Query::Ptr query, unsigned int timestamp);
405+
406+ /*
407+ * Executes a query that returns from a search,
408+ * Implicitly calls CloseQuery();
409+ */
410+ void ExecuteQueryBySearch(std::string execute_string, unsigned int timestamp);
411+
412+ /*
413+ * Closes the query connection, call when the hud closes
414+ */
415+ void CloseQuery();
416+
417+ /*
418+ * Returns a deque of Query types when the service provides them
419+ */
420+ sigc::signal<void, Queries> queries_updated;
421+
422+private:
423+ HudImpl *pimpl_;
424+};
425+
426+}
427+}
428+
429+#endif /* UNITY_HUD_H */
430
431=== added file 'manual-tests/Hud.txt'
432--- manual-tests/Hud.txt 1970-01-01 00:00:00 +0000
433+++ manual-tests/Hud.txt 2012-01-25 11:34:37 +0000
434@@ -0,0 +1,57 @@
435+For reference, the term Tap means to press the indicated key and release it, within a timeframe of 50ms
436+
437+Hud Invocate
438+-----------
439+This test makes sure that the hud presents itself, the launcher hides
440+and the panel changes
441+
442+#. Tap Alt
443+
444+Outcome
445+ The hud interface presents itself with no other interface such as the dash present.
446+ The Launcher hides, the panel becomes transparent with a colour tint matching the hud
447+
448+Hud Search
449+-----------
450+This test makes sure that the hud will search and activate items.
451+
452+#. Ensure the devices indicator is present
453+#. Tap Alt
454+#. Type "system" to search for the "System settings..." item in the devices indicator
455+#. Press return to activate the search query.
456+
457+Outcome
458+ The system settings interface presents itself, the hud disappears.
459+ If the hud does not disappear, this test failed. If the system settings interface
460+ did not present itself, this test did *not* fail.
461+
462+
463+Hud Key-Navigation
464+-----------
465+This test ensures the hud key navigation is intact
466+
467+#. Ensure the messaging indicator is present
468+#. Tap Alt
469+#. Type "Message" to search for items from the messaging indicator
470+#. Press down twice
471+#. Press return
472+
473+Outcome
474+ The item selected will activate and the hud with disappear.
475+ If the hud does not disappear, this test failed.
476+ If the buttons under the search box do not highlight, this test failed.
477+
478+
479+Hud Dismiss
480+----------
481+This test ensures that the hud is dismissable
482+
483+#. Tap Alt
484+#. Type "test"
485+#. Press escape
486+#. Click anywhere on the screen that is not the hud interface
487+
488+Outcome
489+ After pressing escape in step three, the text "test" should be removed from the hud search
490+ After step four, the hud should dismiss itself and not be present.
491+
492
493=== modified file 'plugins/unityshell/src/DashController.cpp'
494--- plugins/unityshell/src/DashController.cpp 2011-12-08 01:23:11 +0000
495+++ plugins/unityshell/src/DashController.cpp 2012-01-25 11:34:37 +0000
496@@ -242,7 +242,8 @@
497
498 StartShowHideTimeline();
499
500- ubus_manager_.SendMessage(UBUS_PLACE_VIEW_SHOWN);
501+ GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE);
502+ ubus_manager_.SendMessage(UBUS_OVERLAY_SHOWN, info);
503 }
504
505 void Controller::HideDash(bool restore)
506@@ -262,8 +263,9 @@
507 PluginAdapter::Default ()->restoreInputFocus ();
508
509 StartShowHideTimeline();
510-
511- ubus_manager_.SendMessage(UBUS_PLACE_VIEW_HIDDEN);
512+
513+ GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE);
514+ ubus_manager_.SendMessage(UBUS_OVERLAY_HIDDEN, info);
515 }
516
517 void Controller::StartShowHideTimeline()
518
519=== modified file 'plugins/unityshell/src/DashStyle.cpp'
520--- plugins/unityshell/src/DashStyle.cpp 2012-01-19 11:57:37 +0000
521+++ plugins/unityshell/src/DashStyle.cpp 2012-01-25 11:34:37 +0000
522@@ -1428,6 +1428,7 @@
523 pango_layout_get_extents(layout, &ink, &log);
524 x = horizMargin; // let pango alignment handle the x position
525 y = ((double) h - pango_units_to_double(log.height)) / 2.0;
526+
527 cairo_move_to(cr, x, y);
528 pango_cairo_show_layout(cr, layout);
529
530
531=== added file 'plugins/unityshell/src/HudButton.cpp'
532--- plugins/unityshell/src/HudButton.cpp 1970-01-01 00:00:00 +0000
533+++ plugins/unityshell/src/HudButton.cpp 2012-01-25 11:34:37 +0000
534@@ -0,0 +1,182 @@
535+/*
536+ * Copyright 2011 Canonical Ltd.
537+ *
538+ * This program is free software: you can redistribute it and/or modify it
539+ * under the terms of the GNU Lesser General Public License version 3, as
540+ * published by the Free Software Foundation.
541+ *
542+ * This program is distributed in the hope that it will be useful, but
543+ * WITHOUT ANY WARRANTY; without even the implied warranties of
544+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
545+ * PURPOSE. See the applicable version of the GNU Lesser General Public
546+ * License for more details.
547+ *
548+ * You should have received a copy of both the GNU Lesser General Public
549+ * License version 3 along with this program. If not, see
550+ * <http://www.gnu.org/licenses/>
551+ *
552+ * Authored by: Gordon Allott <gord.allott@canonical.com>
553+ *
554+ */
555+#include "config.h"
556+
557+#include <pango/pango.h>
558+#include <pango/pangocairo.h>
559+#include <gdk/gdk.h>
560+#include <gtk/gtk.h>
561+
562+#include <Nux/Nux.h>
563+#include <NuxCore/Logger.h>
564+#include <NuxImage/CairoGraphics.h>
565+#include <NuxGraphics/NuxGraphics.h>
566+#include <UnityCore/GLibWrapper.h>
567+#include "DashStyle.h"
568+
569+#include "HudButton.h"
570+
571+namespace
572+{
573+nux::logging::Logger logger("unity.hud.HudButton");
574+}
575+
576+namespace unity
577+{
578+namespace hud
579+{
580+
581+
582+HudButton::HudButton (nux::TextureArea *image, NUX_FILE_LINE_DECL)
583+ : nux::Button (image, NUX_FILE_LINE_PARAM)
584+ , is_focused_(false)
585+{
586+ InitTheme();
587+ OnKeyNavFocusChange.connect([this](nux::Area *area){ QueueDraw(); });
588+}
589+
590+HudButton::HudButton (const std::string label_, NUX_FILE_LINE_DECL)
591+ : nux::Button (NUX_FILE_LINE_PARAM)
592+ , is_focused_(false)
593+{
594+ InitTheme();
595+}
596+
597+HudButton::HudButton (const std::string label_, nux::TextureArea *image, NUX_FILE_LINE_DECL)
598+ : nux::Button (image, NUX_FILE_LINE_PARAM)
599+ , is_focused_(false)
600+{
601+ InitTheme();
602+}
603+
604+HudButton::HudButton (NUX_FILE_LINE_DECL)
605+ : nux::Button (NUX_FILE_LINE_PARAM)
606+ , is_focused_(false)
607+{
608+ InitTheme();
609+}
610+
611+HudButton::~HudButton() {
612+}
613+
614+void HudButton::InitTheme()
615+{
616+ SetMinimumHeight(42);
617+ if (!active_)
618+ {
619+ nux::Geometry const& geo = GetGeometry();
620+
621+ prelight_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_PRELIGHT)));
622+ active_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_PRESSED)));
623+ normal_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_NORMAL)));
624+ }
625+}
626+
627+void HudButton::RedrawTheme(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state)
628+{
629+ dash::Style::Instance().Button(cr, faked_state, label_, dash::Alignment::LEFT);
630+}
631+
632+bool HudButton::AcceptKeyNavFocus()
633+{
634+ return true;
635+}
636+
637+
638+long HudButton::ComputeContentSize ()
639+{
640+ long ret = nux::Button::ComputeContentSize();
641+ nux::Geometry const& geo = GetGeometry();
642+
643+ if (cached_geometry_ != geo)
644+ {
645+ prelight_->Invalidate(geo);
646+ active_->Invalidate(geo);
647+ normal_->Invalidate(geo);
648+
649+ cached_geometry_ = geo;
650+ }
651+
652+ return ret;
653+}
654+
655+void HudButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
656+{
657+ nux::Geometry const& geo = GetGeometry();
658+
659+ gPainter.PaintBackground(GfxContext, geo);
660+ // set up our texture mode
661+ nux::TexCoordXForm texxform;
662+ texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
663+ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
664+
665+ // clear what is behind us
666+ unsigned int alpha = 0, src = 0, dest = 0;
667+ GfxContext.GetRenderStates().GetBlend(alpha, src, dest);
668+ GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
669+
670+ nux::Color col = nux::color::Black;
671+ col.alpha = 0;
672+ GfxContext.QRP_Color(geo.x,
673+ geo.y,
674+ geo.width,
675+ geo.height,
676+ col);
677+
678+ nux::BaseTexture* texture = normal_->GetTexture();
679+ if (HasKeyFocus())
680+ texture = active_->GetTexture();
681+ else if (HasKeyFocus())
682+ texture = prelight_->GetTexture();
683+ else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRESSED)
684+ texture = active_->GetTexture();
685+
686+ GfxContext.QRP_1Tex(geo.x,
687+ geo.y,
688+ geo.width,
689+ geo.height,
690+ texture->GetDeviceTexture(),
691+ texxform,
692+ nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
693+
694+ GfxContext.GetRenderStates().SetBlend(alpha, src, dest);
695+}
696+
697+void HudButton::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) {
698+}
699+
700+void HudButton::PostDraw(nux::GraphicsEngine& GfxContext, bool force_draw) {
701+ nux::Button::PostDraw(GfxContext, force_draw);
702+}
703+
704+void HudButton::SetQuery(Query::Ptr query)
705+{
706+ query_ = query;
707+ label_ = query->formatted_text;
708+ label = query->formatted_text;
709+}
710+
711+Query::Ptr HudButton::GetQuery()
712+{
713+ return query_;
714+}
715+}
716+}
717
718=== added file 'plugins/unityshell/src/HudButton.h'
719--- plugins/unityshell/src/HudButton.h 1970-01-01 00:00:00 +0000
720+++ plugins/unityshell/src/HudButton.h 2012-01-25 11:34:37 +0000
721@@ -0,0 +1,76 @@
722+/*
723+ * Copyright 2011 Canonical Ltd.
724+ *
725+ * This program is free software: you can redistribute it and/or modify it
726+ * under the terms of the GNU Lesser General Public License version 3, as
727+ * published by the Free Software Foundation.
728+ *
729+ * This program is distributed in the hope that it will be useful, but
730+ * WITHOUT ANY WARRANTY; without even the implied warranties of
731+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
732+ * PURPOSE. See the applicable version of the GNU Lesser General Public
733+ * License for more details.
734+ *
735+ * You should have received a copy of both the GNU Lesser General Public
736+ * License version 3 along with this program. If not, see
737+ * <http://www.gnu.org/licenses/>
738+ *
739+ * Authored by: Gordon Allott <gord.allott@canonical.com>
740+ *
741+ */
742+
743+
744+
745+#ifndef FILTERBASICBUTTON_H
746+#define FILTERBASICBUTTON_H
747+
748+#include <Nux/Nux.h>
749+#include <Nux/CairoWrapper.h>
750+#include <Nux/Button.h>
751+#include <Nux/TextureArea.h>
752+#include <UnityCore/Hud.h>
753+
754+namespace unity {
755+
756+namespace hud {
757+class HudButton : public nux::Button {
758+ typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr;
759+ typedef nux::ObjectPtr<HudButton> Ptr;
760+public:
761+ HudButton (nux::TextureArea *image, NUX_FILE_LINE_PROTO);
762+ HudButton (const std::string label, NUX_FILE_LINE_PROTO);
763+ HudButton (const std::string label, nux::TextureArea *image, NUX_FILE_LINE_PROTO);
764+ HudButton (NUX_FILE_LINE_PROTO);
765+ virtual ~HudButton();
766+
767+ void SetQuery(Query::Ptr query);
768+ std::shared_ptr<Query> GetQuery();
769+
770+ nux::Property<std::string> label;
771+ nux::Property<std::string> hint;
772+
773+protected:
774+ virtual bool AcceptKeyNavFocus();
775+ virtual long ComputeContentSize();
776+ virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
777+ virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
778+ virtual void PostDraw(nux::GraphicsEngine& GfxContext, bool force_draw);
779+
780+ void InitTheme ();
781+ void RedrawTheme(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state);
782+ typedef std::unique_ptr<nux::CairoWrapper> NuxCairoPtr;
783+
784+ NuxCairoPtr prelight_;
785+ NuxCairoPtr active_;
786+ NuxCairoPtr normal_;
787+
788+private:
789+ std::string label_;
790+
791+ Query::Ptr query_;
792+ nux::Geometry cached_geometry_;
793+ bool is_focused_;
794+};
795+}
796+}
797+#endif // FILTERBASICBUTTON_H
798
799=== added file 'plugins/unityshell/src/HudController.cpp'
800--- plugins/unityshell/src/HudController.cpp 1970-01-01 00:00:00 +0000
801+++ plugins/unityshell/src/HudController.cpp 2012-01-25 11:34:37 +0000
802@@ -0,0 +1,364 @@
803+/*
804+ * Copyright (C) 2010 Canonical Ltd
805+ *
806+ * This program is free software: you can redistribute it and/or modify
807+ * it under the terms of the GNU General Public License version 3 as
808+ * published by the Free Software Foundation.
809+ *
810+ * This program is distributed in the hope that it will be useful,
811+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
812+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
813+ * GNU General Public License for more details.
814+ *
815+ * You should have received a copy of the GNU General Public License
816+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
817+ *
818+ * Authored by: Gord Allott <gord.allott@canonical.com>
819+ */
820+
821+#include "HudController.h"
822+
823+#include <NuxCore/Logger.h>
824+#include <Nux/HLayout.h>
825+#include "PluginAdapter.h"
826+#include "UBusMessages.h"
827+#include "UScreen.h"
828+namespace unity
829+{
830+namespace hud
831+{
832+
833+namespace
834+{
835+nux::logging::Logger logger("unity.hud.controller");
836+}
837+
838+Controller::Controller()
839+ : launcher_width(66)
840+ , panel_height(24)
841+ , hud_service_("com.canonical.hud", "/com/canonical/hud")
842+ , window_(0)
843+ , visible_(false)
844+ , need_show_(false)
845+ , timeline_id_(0)
846+ , last_opacity_(0.0f)
847+ , start_time_(0)
848+{
849+ LOG_DEBUG(logger) << "hud startup";
850+ SetupRelayoutCallbacks();
851+
852+ ubus.RegisterInterest(UBUS_HUD_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud));
853+
854+ //!!FIXME!! - just hijacks the dash close request so we get some more requests than normal,
855+ ubus.RegisterInterest(UBUS_PLACE_VIEW_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud));
856+
857+ PluginAdapter::Default()->compiz_screen_ungrabbed.connect(sigc::mem_fun(this, &Controller::OnScreenUngrabbed));
858+
859+ hud_service_.queries_updated.connect(sigc::mem_fun(this, &Controller::OnQueriesFinished));
860+ EnsureHud();
861+}
862+
863+Controller::~Controller()
864+{
865+ if (window_)
866+ window_->UnReference();
867+ window_ = 0;
868+
869+ g_source_remove(timeline_id_);
870+ g_source_remove(ensure_id_);
871+}
872+
873+void Controller::SetupWindow()
874+{
875+ window_ = new nux::BaseWindow("Hud");
876+ window_->SinkReference();
877+ window_->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
878+ window_->SetConfigureNotifyCallback(&Controller::OnWindowConfigure, this);
879+ window_->ShowWindow(false);
880+ window_->SetOpacity(0.0f);
881+ window_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow));
882+}
883+
884+void Controller::SetupHudView()
885+{
886+ LOG_DEBUG(logger) << "SetupHudView called";
887+ view_ = new View();
888+
889+ layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
890+ layout_->AddView(view_, 1);
891+ window_->SetLayout(layout_);
892+
893+ view_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow));
894+
895+ LOG_DEBUG(logger) << "connecting to signals";
896+ view_->search_changed.connect(sigc::mem_fun(this, &Controller::OnSearchChanged));
897+ view_->search_activated.connect(sigc::mem_fun(this, &Controller::OnSearchActivated));
898+ view_->query_activated.connect(sigc::mem_fun(this, &Controller::OnQueryActivated));
899+ view_->query_selected.connect(sigc::mem_fun(this, &Controller::OnQuerySelected));
900+}
901+
902+void Controller::SetupRelayoutCallbacks()
903+{
904+ GdkScreen* screen = gdk_screen_get_default();
905+
906+ sig_manager_.Add(new glib::Signal<void, GdkScreen*>(screen,
907+ "monitors-changed", sigc::mem_fun(this, &Controller::Relayout)));
908+ sig_manager_.Add(new glib::Signal<void, GdkScreen*>(screen,
909+ "size-changed", sigc::mem_fun(this, &Controller::Relayout)));
910+}
911+
912+void Controller::EnsureHud()
913+{
914+ if (window_)
915+ return;
916+
917+ LOG_DEBUG(logger) << "Initializing Hud";
918+
919+ SetupWindow();
920+ SetupHudView();
921+ Relayout();
922+ ensure_id_ = 0;
923+}
924+
925+nux::BaseWindow* Controller::window() const
926+{
927+ return window_;
928+}
929+
930+// We update the @geo that's sent in with our desired width and height
931+void Controller::OnWindowConfigure(int window_width, int window_height,
932+ nux::Geometry& geo, void* data)
933+{
934+ Controller* self = static_cast<Controller*>(data);
935+ geo = self->GetIdealWindowGeometry();
936+}
937+
938+nux::Geometry Controller::GetIdealWindowGeometry()
939+{
940+ UScreen *uscreen = UScreen::GetDefault();
941+ int primary_monitor = uscreen->GetPrimaryMonitor();
942+ auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor);
943+
944+ // We want to cover as much of the screen as possible to grab any mouse events outside
945+ // of our window
946+ return nux::Geometry (monitor_geo.x,
947+ monitor_geo.y + panel_height,
948+ monitor_geo.width,
949+ monitor_geo.height - panel_height);
950+}
951+
952+void Controller::Relayout(GdkScreen*screen)
953+{
954+ EnsureHud();
955+ nux::Geometry content_geo = view_->GetGeometry();
956+ nux::Geometry geo = GetIdealWindowGeometry();
957+
958+ window_->SetGeometry(geo);
959+ layout_->SetMinMaxSize(content_geo.width, content_geo.height);
960+ view_->SetWindowGeometry(window_->GetAbsoluteGeometry(), window_->GetGeometry());
961+ view_->Relayout();
962+}
963+
964+void Controller::OnMouseDownOutsideWindow(int x, int y,
965+ unsigned long bflags, unsigned long kflags)
966+{
967+ LOG_DEBUG(logger) << "OnMouseDownOutsideWindow called";
968+ HideHud();
969+}
970+
971+void Controller::OnScreenUngrabbed()
972+{
973+ LOG_DEBUG(logger) << "OnScreenUngrabbed called";
974+ if (need_show_)
975+ {
976+ EnsureHud();
977+ ShowHud();
978+ }
979+}
980+
981+void Controller::OnExternalShowHud(GVariant* variant)
982+{
983+ EnsureHud();
984+ visible_ ? HideHud() : ShowHud();
985+}
986+
987+void Controller::OnExternalHideHud(GVariant* variant)
988+{
989+ LOG_DEBUG(logger) << "External Hiding the hud";
990+ EnsureHud();
991+ HideHud();
992+}
993+
994+void Controller::ShowHideHud()
995+{
996+ EnsureHud();
997+ visible_ ? HideHud() : ShowHud();
998+}
999+
1000+void Controller::ShowHud()
1001+{
1002+ LOG_DEBUG(logger) << "Showing the hud";
1003+ EnsureHud();
1004+ view_->AboutToShow();
1005+
1006+ window_->ShowWindow(true);
1007+ window_->PushToFront();
1008+ window_->EnableInputWindow(true, "Hud", true, false);
1009+ window_->SetInputFocus();
1010+ nux::GetWindowCompositor().SetKeyFocusArea(view_->default_focus());
1011+ window_->CaptureMouseDownAnyWhereElse(true);
1012+ view_->CaptureMouseDownAnyWhereElse(true);
1013+ window_->QueueDraw();
1014+
1015+ view_->ResetToDefault();
1016+ hud_service_.RequestQuery("");
1017+
1018+ need_show_ = false;
1019+ visible_ = true;
1020+
1021+ StartShowHideTimeline();
1022+ view_->SetWindowGeometry(window_->GetAbsoluteGeometry(), window_->GetGeometry());
1023+
1024+ // hide the launcher
1025+ GVariant* message_data = g_variant_new("(b)", TRUE);
1026+ ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data);
1027+
1028+ GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE);
1029+ ubus.SendMessage(UBUS_OVERLAY_SHOWN, info);
1030+}
1031+void Controller::HideHud(bool restore)
1032+{
1033+ LOG_DEBUG (logger) << "hiding the hud";
1034+ if (visible_ == false)
1035+ return;
1036+
1037+ EnsureHud();
1038+ view_->AboutToHide();
1039+ window_->CaptureMouseDownAnyWhereElse(false);
1040+ window_->EnableInputWindow(false, "Hud", true, false);
1041+ visible_ = false;
1042+
1043+ StartShowHideTimeline();
1044+
1045+ restore = true;
1046+ if (restore)
1047+ PluginAdapter::Default ()->restoreInputFocus ();
1048+
1049+ hud_service_.CloseQuery();
1050+
1051+ //unhide the launcher
1052+ GVariant* message_data = g_variant_new("(b)", FALSE);
1053+ ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data);
1054+
1055+ GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE);
1056+ ubus.SendMessage(UBUS_OVERLAY_HIDDEN, info);
1057+}
1058+
1059+void Controller::StartShowHideTimeline()
1060+{
1061+ EnsureHud();
1062+
1063+ if (timeline_id_)
1064+ g_source_remove(timeline_id_);
1065+
1066+ timeline_id_ = g_timeout_add(15, (GSourceFunc)Controller::OnViewShowHideFrame, this);
1067+ last_opacity_ = window_->GetOpacity();
1068+ start_time_ = g_get_monotonic_time();
1069+
1070+}
1071+
1072+gboolean Controller::OnViewShowHideFrame(Controller* self)
1073+{
1074+#define _LENGTH_ 90000
1075+ float diff = g_get_monotonic_time() - self->start_time_;
1076+ float progress = diff / (float)_LENGTH_;
1077+ float last_opacity = self->last_opacity_;
1078+
1079+ if (self->visible_)
1080+ {
1081+ self->window_->SetOpacity(last_opacity + ((1.0f - last_opacity) * progress));
1082+ }
1083+ else
1084+ {
1085+ self->window_->SetOpacity(last_opacity - (last_opacity * progress));
1086+ }
1087+
1088+ if (diff > _LENGTH_)
1089+ {
1090+ self->timeline_id_ = 0;
1091+
1092+ // Make sure the state is right
1093+ self->window_->SetOpacity(self->visible_ ? 1.0f : 0.0f);
1094+ if (!self->visible_)
1095+ {
1096+ self->window_->ShowWindow(false);
1097+ }
1098+
1099+ return FALSE;
1100+ }
1101+
1102+ return TRUE;
1103+}
1104+
1105+void Controller::OnActivateRequest(GVariant* variant)
1106+{
1107+ EnsureHud();
1108+ ShowHud();
1109+}
1110+
1111+void Controller::OnSearchChanged(std::string search_string)
1112+{
1113+ LOG_DEBUG(logger) << "Search Changed";
1114+ hud_service_.RequestQuery(search_string);
1115+}
1116+
1117+void Controller::OnSearchActivated(std::string search_string)
1118+{
1119+ unsigned int timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
1120+ hud_service_.ExecuteQueryBySearch(search_string, timestamp);
1121+ HideHud();
1122+}
1123+
1124+void Controller::OnQueryActivated(Query::Ptr query)
1125+{
1126+ LOG_DEBUG(logger) << "Activating query, " << query->formatted_text;
1127+ unsigned int timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
1128+ hud_service_.ExecuteQuery(query, timestamp);
1129+ HideHud();
1130+}
1131+
1132+void Controller::OnQuerySelected(Query::Ptr query)
1133+{
1134+ LOG_DEBUG(logger) << "Selected query, " << query->formatted_text;
1135+ view_->SetIcon(query->icon_name);
1136+}
1137+
1138+
1139+void Controller::OnQueriesFinished(Hud::Queries queries)
1140+{
1141+ view_->SetQueries(queries);
1142+ std::string icon_name = "";
1143+ for (auto query = queries.begin(); query != queries.end(); query++)
1144+ {
1145+ if (!(*query)->icon_name.empty())
1146+ {
1147+ icon_name = (*query)->icon_name;
1148+ break;
1149+ }
1150+ }
1151+
1152+ view_->SetIcon(icon_name);
1153+}
1154+
1155+// Introspectable
1156+const gchar* Controller::GetName()
1157+{
1158+ return "unity.hud.Controller";
1159+}
1160+
1161+void Controller::AddProperties(GVariantBuilder* builder)
1162+{}
1163+
1164+
1165+}
1166+}
1167
1168=== added file 'plugins/unityshell/src/HudController.h'
1169--- plugins/unityshell/src/HudController.h 1970-01-01 00:00:00 +0000
1170+++ plugins/unityshell/src/HudController.h 2012-01-25 11:34:37 +0000
1171@@ -0,0 +1,113 @@
1172+/*
1173+ * Copyright (C) 2010 Canonical Ltd
1174+ *
1175+ * This program is free software: you can redistribute it and/or modify
1176+ * it under the terms of the GNU General Public License version 3 as
1177+ * published by the Free Software Foundation.
1178+ *
1179+ * This program is distributed in the hope that it will be useful,
1180+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1181+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1182+ * GNU General Public License for more details.
1183+ *
1184+ * You should have received a copy of the GNU General Public License
1185+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1186+ *
1187+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1188+ */
1189+
1190+#ifndef UNITY_HUD_CONTROLLER_H_
1191+#define UNITY_HUD_CONTROLLER_H_
1192+
1193+#include <memory>
1194+
1195+#include <gdk/gdk.h>
1196+#include <UnityCore/GLibSignal.h>
1197+#include <UnityCore/Hud.h>
1198+
1199+#include <NuxCore/Property.h>
1200+#include <NuxGraphics/GraphicsEngine.h>
1201+#include <Nux/Nux.h>
1202+#include <Nux/BaseWindow.h>
1203+
1204+#include "HudView.h"
1205+#include "UBusWrapper.h"
1206+
1207+namespace unity
1208+{
1209+namespace hud
1210+{
1211+
1212+class Controller
1213+{
1214+public:
1215+ typedef std::shared_ptr<Controller> Ptr;
1216+
1217+ Controller();
1218+ ~Controller();
1219+
1220+ nux::BaseWindow* window() const;
1221+
1222+ nux::Property<int> launcher_width;
1223+ nux::Property<int> panel_height;
1224+
1225+ void ShowHideHud();
1226+ void ShowHud();
1227+ void HideHud(bool restore_focus = true);
1228+
1229+protected:
1230+ const gchar* GetName();
1231+ void AddProperties(GVariantBuilder* builder);
1232+
1233+private:
1234+ void EnsureHud();
1235+ void SetupWindow();
1236+ void SetupHudView();
1237+ void SetupRelayoutCallbacks();
1238+ void RegisterUBusInterests();
1239+
1240+ nux::Geometry GetIdealWindowGeometry();
1241+ void Relayout(GdkScreen*screen=NULL);
1242+
1243+ void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags);
1244+ void OnScreenUngrabbed();
1245+ void OnExternalShowHud(GVariant* variant);
1246+ void OnExternalHideHud(GVariant* variant);
1247+ void OnActivateRequest(GVariant* variant);
1248+
1249+ void OnSearchChanged(std::string search_string);
1250+ void OnSearchActivated(std::string search_string);
1251+ void OnQueryActivated(Query::Ptr query);
1252+ void OnQuerySelected(Query::Ptr query);
1253+
1254+
1255+private:
1256+ void StartShowHideTimeline();
1257+ static gboolean OnViewShowHideFrame(Controller* self);
1258+
1259+ static void OnWindowConfigure(int width, int height, nux::Geometry& geo, void* data);
1260+
1261+ void OnQueriesFinished(Hud::Queries queries);
1262+
1263+private:
1264+ UBusManager ubus;
1265+ Hud hud_service_;
1266+ glib::SignalManager sig_manager_;
1267+ nux::BaseWindow* window_;
1268+ bool visible_;
1269+ bool need_show_;
1270+
1271+ guint timeline_id_;
1272+ float last_opacity_;
1273+ gint64 start_time_;
1274+
1275+ View* view_;
1276+ guint ensure_id_;
1277+
1278+ nux::Layout* layout_;
1279+};
1280+
1281+
1282+}
1283+}
1284+#endif
1285
1286=== added file 'plugins/unityshell/src/HudIcon.cpp'
1287--- plugins/unityshell/src/HudIcon.cpp 1970-01-01 00:00:00 +0000
1288+++ plugins/unityshell/src/HudIcon.cpp 2012-01-25 11:34:37 +0000
1289@@ -0,0 +1,91 @@
1290+/*
1291+ * Copyright (C) 2010 Canonical Ltd
1292+ *
1293+ * This program is free software: you can redistribute it and/or modify
1294+ * it under the terms of the GNU General Public License version 3 as
1295+ * published by the Free Software Foundation.
1296+ *
1297+ * This program is distributed in the hope that it will be useful,
1298+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1299+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1300+ * GNU General Public License for more details.
1301+ *
1302+ * You should have received a copy of the GNU General Public License
1303+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1304+ *
1305+ * Authored by: Gord Allott <gord.allott@canonical.com>
1306+ */
1307+
1308+
1309+#include "HudIcon.h"
1310+
1311+//FIXME - we should be using the LauncherRenderer method of rendering icons here instead of compositing ourself
1312+// to make sure we get the correct average background colour and running indicator
1313+
1314+namespace unity
1315+{
1316+namespace hud
1317+{
1318+
1319+Icon::Icon(nux::BaseTexture* texture, guint width, guint height)
1320+ : unity::IconTexture(texture, width, height)
1321+{
1322+ Init();
1323+}
1324+
1325+Icon::Icon(const char* icon_name, unsigned int size, bool defer_icon_loading)
1326+ : unity::IconTexture(icon_name, size, defer_icon_loading)
1327+{
1328+ Init();
1329+}
1330+
1331+Icon::~Icon()
1332+{
1333+}
1334+
1335+void Icon::Init()
1336+{
1337+ SetMinimumWidth(54);
1338+ SetMinimumHeight(54);
1339+ background_ = nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_back_54.png", -1, true);
1340+ gloss_ = nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_shine_54.png", -1, true);
1341+ edge_ = nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_edge_54.png", -1, true);
1342+}
1343+
1344+void Icon::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
1345+{
1346+ nux::Geometry geo = GetGeometry();
1347+ // set up our texture mode
1348+ nux::TexCoordXForm texxform;
1349+
1350+ GfxContext.QRP_1Tex(geo.x,
1351+ geo.y,
1352+ background_->GetWidth(),
1353+ background_->GetHeight(),
1354+ background_->GetDeviceTexture(),
1355+ texxform,
1356+ nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
1357+
1358+ GfxContext.QRP_1Tex(geo.x,
1359+ geo.y,
1360+ gloss_->GetWidth(),
1361+ gloss_->GetHeight(),
1362+ gloss_->GetDeviceTexture(),
1363+ texxform,
1364+ nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
1365+
1366+ GfxContext.QRP_1Tex(geo.x,
1367+ geo.y,
1368+ edge_->GetWidth(),
1369+ edge_->GetHeight(),
1370+ edge_->GetDeviceTexture(),
1371+ texxform,
1372+ nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
1373+
1374+ unity::IconTexture::Draw(GfxContext, force_draw);
1375+}
1376+
1377+
1378+}
1379+}
1380+
1381
1382=== added file 'plugins/unityshell/src/HudIcon.h'
1383--- plugins/unityshell/src/HudIcon.h 1970-01-01 00:00:00 +0000
1384+++ plugins/unityshell/src/HudIcon.h 2012-01-25 11:34:37 +0000
1385@@ -0,0 +1,69 @@
1386+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1387+/*
1388+ * Copyright (C) 2010 Canonical Ltd
1389+ *
1390+ * This program is free software: you can redistribute it and/or modify
1391+ * it under the terms of the GNU General Public License version 3 as
1392+ * published by the Free Software Foundation.
1393+ *
1394+ * This program is distributed in the hope that it will be useful,
1395+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1396+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1397+ * GNU General Public License for more details.
1398+ *
1399+ * You should have received a copy of the GNU General Public License
1400+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1401+ *
1402+ * Authored by: Gord Allott <gord.allott@canonical.com>
1403+ *
1404+ */
1405+
1406+#ifndef HUDICON_H
1407+#define HUDICON_H
1408+
1409+#include <set>
1410+#include <string>
1411+
1412+#include "config.h"
1413+
1414+#include <Nux/Nux.h>
1415+#include <Nux/BaseWindow.h>
1416+#include <NuxCore/Math/MathInc.h>
1417+
1418+#include <sigc++/trackable.h>
1419+#include <sigc++/signal.h>
1420+#include <sigc++/functors/ptr_fun.h>
1421+#include <sigc++/functors/mem_fun.h>
1422+
1423+#include <gtk/gtk.h>
1424+
1425+#include "IconTexture.h"
1426+#include "Introspectable.h"
1427+
1428+namespace unity
1429+{
1430+namespace hud
1431+{
1432+
1433+class Icon : public unity::IconTexture
1434+{
1435+public:
1436+ typedef nux::ObjectPtr<IconTexture> Ptr;
1437+ Icon(nux::BaseTexture* texture, guint width, guint height);
1438+ Icon(const char* icon_name, unsigned int size, bool defer_icon_loading = false);
1439+ ~Icon();
1440+
1441+protected:
1442+ void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
1443+ void Init();
1444+
1445+ nux::ObjectPtr<nux::BaseTexture> background_;
1446+ nux::ObjectPtr<nux::BaseTexture> gloss_;
1447+ nux::ObjectPtr<nux::BaseTexture> edge_;
1448+};
1449+
1450+}
1451+
1452+}
1453+
1454+#endif /* HUDICON_H */
1455
1456=== added file 'plugins/unityshell/src/HudSearchBar.cpp'
1457--- plugins/unityshell/src/HudSearchBar.cpp 1970-01-01 00:00:00 +0000
1458+++ plugins/unityshell/src/HudSearchBar.cpp 2012-01-25 11:34:37 +0000
1459@@ -0,0 +1,404 @@
1460+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1461+/*
1462+ * Copyright (C) 2010-2011 Canonical Ltd
1463+ *
1464+ * This program is free software: you can redistribute it and/or modify
1465+ * it under the terms of the GNU General Public License version 3 as
1466+ * published by the Free Software Foundation.
1467+ *
1468+ * This program is distributed in the hope that it will be useful,
1469+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1470+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1471+ * GNU General Public License for more detais.
1472+ *
1473+ * You shoud have received a copy of the GNU General Public License
1474+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1475+ *
1476+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1477+ */
1478+
1479+/* FIXME!! - port this to the DashSearchBar and rename both to SearchBar */
1480+
1481+#include "config.h"
1482+
1483+#include <Nux/Nux.h>
1484+#include <Nux/BaseWindow.h>
1485+#include <Nux/HLayout.h>
1486+#include <Nux/Layout.h>
1487+#include <Nux/WindowCompositor.h>
1488+
1489+#include <NuxImage/CairoGraphics.h>
1490+#include <NuxImage/ImageSurface.h>
1491+#include <Nux/StaticText.h>
1492+
1493+#include <NuxGraphics/GLThread.h>
1494+#include <NuxGraphics/RenderingPipe.h>
1495+
1496+#include <glib.h>
1497+#include <glib/gi18n-lib.h>
1498+
1499+#include "HudSearchBar.h"
1500+#include <UnityCore/Variant.h>
1501+
1502+#include "DashStyle.h"
1503+
1504+#define LIVE_SEARCH_TIMEOUT 250
1505+// Create a texture from the CairoGraphics object.
1506+//
1507+// Returns a new BaseTexture that has a ref count of 1.
1508+static nux::BaseTexture* texture_from_cairo_graphics(nux::CairoGraphics& cg)
1509+{
1510+ nux::NBitmapData* bitmap = cg.GetBitmap();
1511+ nux::BaseTexture* tex = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
1512+ tex->Update(bitmap);
1513+ delete bitmap;
1514+ return tex;
1515+}
1516+
1517+namespace unity
1518+{
1519+namespace hud
1520+{
1521+
1522+NUX_IMPLEMENT_OBJECT_TYPE(SearchBar);
1523+
1524+SearchBar::SearchBar(NUX_FILE_LINE_DECL)
1525+ : View(NUX_FILE_LINE_PARAM)
1526+ , search_hint("")
1527+ , showing_filters(false)
1528+ , can_refine_search(false)
1529+ , live_search_timeout_(0)
1530+{
1531+nux::BaseTexture* icon = dash::Style::Instance().GetSearchMagnifyIcon();
1532+
1533+ bg_layer_ = new nux::ColorLayer(nux::Color(0xff595853), true);
1534+
1535+ layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
1536+ layout_->SetHorizontalInternalMargin(0);
1537+ layout_->SetVerticalExternalMargin(8);
1538+ layout_->SetHorizontalExternalMargin(10);
1539+ SetLayout(layout_);
1540+
1541+ spinner_ = new dash::SearchBarSpinner();
1542+ spinner_->SetMinMaxSize(icon->GetWidth(), icon->GetHeight());
1543+ spinner_->mouse_click.connect(sigc::mem_fun(this, &SearchBar::OnClearClicked));
1544+ layout_->AddView(spinner_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
1545+
1546+ hint_ = new nux::StaticCairoText(" ");
1547+ hint_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 0.5f));
1548+ hint_->SetMaximumWidth(570);
1549+
1550+ pango_entry_ = new dash::IMTextEntry();
1551+ pango_entry_->sigTextChanged.connect(sigc::mem_fun(this, &SearchBar::OnSearchChanged));
1552+ pango_entry_->activated.connect([&]() { activated.emit(); });
1553+ pango_entry_->cursor_moved.connect([&](int i) { QueueDraw(); });
1554+ pango_entry_->mouse_down.connect(sigc::mem_fun(this, &SearchBar::OnMouseButtonDown));
1555+ pango_entry_->end_key_focus.connect(sigc::mem_fun(this, &SearchBar::OnEndKeyFocus));
1556+ pango_entry_->SetMaximumWidth(570);
1557+
1558+ layered_layout_ = new nux::LayeredLayout();
1559+ layered_layout_->AddLayer(hint_);
1560+ layered_layout_->AddLayer(pango_entry_);
1561+ layered_layout_->SetPaintAll(true);
1562+ layered_layout_->SetActiveLayerN(1);
1563+ layered_layout_->SetMinimumWidth(420);
1564+ layered_layout_->SetMaximumWidth(645);
1565+ layout_->AddView(layered_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
1566+
1567+ std::string filter_str = _("Filter results");
1568+ filter_str+= " ▸";
1569+ show_filters_ = new nux::StaticCairoText(filter_str.c_str());
1570+ show_filters_->SetVisible(false);
1571+ show_filters_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
1572+ show_filters_->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT);
1573+ show_filters_->mouse_click.connect([&] (int x, int y, unsigned long b, unsigned long k) { showing_filters = !showing_filters; });
1574+
1575+ nux::Layout *filter_layout = new nux::HLayout();
1576+ filter_layout->SetHorizontalExternalMargin(12);
1577+ filter_layout->AddLayout(new nux::SpaceLayout(0, 10000, 0, 1), 1);
1578+ filter_layout->AddView(show_filters_, 0, nux::MINOR_POSITION_RIGHT);
1579+
1580+ layout_->AddView(filter_layout, 1, nux::MINOR_POSITION_RIGHT, nux::MINOR_SIZE_FIX);
1581+
1582+ sig_manager_.Add(new Signal<void, GtkSettings*, GParamSpec*>
1583+ (gtk_settings_get_default(),
1584+ "notify::gtk-font-name",
1585+ sigc::mem_fun(this, &SearchBar::OnFontChanged)));
1586+ OnFontChanged(gtk_settings_get_default());
1587+
1588+ search_hint.changed.connect([&](std::string const& s) { OnSearchHintChanged(); });
1589+ search_string.SetGetterFunction(sigc::mem_fun(this, &SearchBar::get_search_string));
1590+ search_string.SetSetterFunction(sigc::mem_fun(this, &SearchBar::set_search_string));
1591+ im_active.SetGetterFunction(sigc::mem_fun(this, &SearchBar::get_im_active));
1592+ showing_filters.changed.connect(sigc::mem_fun(this, &SearchBar::OnShowingFiltersChanged));
1593+ can_refine_search.changed.connect([&] (bool can_refine) { show_filters_->SetVisible(can_refine); });
1594+}
1595+
1596+SearchBar::~SearchBar()
1597+{
1598+ delete bg_layer_;
1599+
1600+ if (live_search_timeout_)
1601+ g_source_remove(live_search_timeout_);
1602+}
1603+
1604+void SearchBar::OnFontChanged(GtkSettings* settings, GParamSpec* pspec)
1605+{
1606+ static const int HOW_LARGE = 8;
1607+ gchar* font_name = NULL;
1608+ PangoFontDescription* desc;
1609+ gint size;
1610+ gchar* font_desc;
1611+
1612+ g_object_get(settings, "gtk-font-name", &font_name, NULL);
1613+
1614+ desc = pango_font_description_from_string(font_name);
1615+ pango_entry_->SetFontFamily(pango_font_description_get_family(desc));
1616+
1617+ size = pango_font_description_get_size(desc);
1618+ size /= pango_font_description_get_size_is_absolute(desc) ? 1 : PANGO_SCALE;
1619+ pango_entry_->SetFontSize(size + HOW_LARGE);
1620+
1621+ pango_entry_->SetFontOptions(gdk_screen_get_font_options(gdk_screen_get_default()));
1622+
1623+ font_desc = g_strdup_printf("%s %d", pango_font_description_get_family(desc), size + HOW_LARGE);
1624+ hint_->SetFont(font_desc);
1625+
1626+ g_free(font_desc);
1627+ font_desc = g_strdup_printf("%s %d", pango_font_description_get_family(desc), size + HOW_LARGE/2);
1628+ show_filters_->SetFont(font_desc);
1629+
1630+ pango_font_description_free(desc);
1631+ g_free(font_name);
1632+ g_free(font_desc);
1633+}
1634+
1635+void SearchBar::OnSearchHintChanged()
1636+{
1637+ std::string hint = search_hint;
1638+ gchar* tmp = g_markup_escape_text(hint.c_str(), -1);
1639+
1640+ gchar* markup = g_strdup_printf("%s", tmp);
1641+ hint_->SetText(markup);
1642+
1643+ g_free(markup);
1644+ g_free(tmp);
1645+}
1646+
1647+void SearchBar::OnSearchChanged(nux::TextEntry* text_entry)
1648+{
1649+ // We don't want to set a new search string on every new character, so we add a sma
1650+ // timeout to see if the user is typing a sentence. If more characters are added, we
1651+ // keep restarting the timeout unti the user has actuay paused.
1652+ if (live_search_timeout_)
1653+ g_source_remove(live_search_timeout_);
1654+
1655+ live_search_timeout_ = g_timeout_add(LIVE_SEARCH_TIMEOUT,
1656+ (GSourceFunc)&OnLiveSearchTimeout,
1657+ this);
1658+
1659+ //spinner_->SetState(is_empty ? unity::dash::STATE_READY : unity::dash::STATE_SEARCHING);
1660+
1661+ pango_entry_->QueueDraw();
1662+ hint_->QueueDraw();
1663+ QueueDraw();
1664+
1665+ search_changed.emit(pango_entry_->GetText());
1666+}
1667+
1668+gboolean SearchBar::OnLiveSearchTimeout(SearchBar* sef)
1669+{
1670+ sef->live_search_reached.emit(sef->pango_entry_->GetText());
1671+ sef->live_search_timeout_ = 0;
1672+ return FALSE;
1673+}
1674+
1675+void SearchBar::OnShowingFiltersChanged(bool is_showing)
1676+{
1677+ std::string filter_str = _("Filter results");
1678+ filter_str += " <small>";
1679+ filter_str += is_showing ? "▾" : "▸";
1680+ filter_str += "</small>";
1681+ show_filters_->SetText(filter_str.c_str());
1682+}
1683+
1684+void SearchBar::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
1685+{
1686+ nux::Geometry geo = GetGeometry();
1687+
1688+ UpdateBackground();
1689+ GfxContext.PushClippingRectangle(geo);
1690+
1691+ nux::GetPainter().PaintBackground(GfxContext, geo);
1692+
1693+ bg_layer_->SetGeometry(nux::Geometry(geo.x, geo.y, last_width_, geo.height));
1694+ nux::GetPainter().RenderSinglePaintLayer(GfxContext,
1695+ bg_layer_->GetGeometry(),
1696+ bg_layer_);
1697+
1698+ GfxContext.PopClippingRectangle();
1699+}
1700+
1701+void SearchBar::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
1702+{
1703+ nux::Geometry geo = GetGeometry();
1704+
1705+ GfxContext.PushClippingRectangle(geo);
1706+
1707+ if (!IsFullRedraw())
1708+ gPainter.PushLayer(GfxContext, bg_layer_->GetGeometry(), bg_layer_);
1709+
1710+ layout_->ProcessDraw(GfxContext, force_draw);
1711+
1712+ if (!IsFullRedraw())
1713+ gPainter.PopBackground();
1714+ GfxContext.PopClippingRectangle();
1715+}
1716+
1717+void SearchBar::OnClearClicked(int x, int y, unsigned long button_fags,
1718+ unsigned long key_fags)
1719+{
1720+ pango_entry_->SetText("");
1721+ spinner_->SetState(unity::dash::STATE_READY);
1722+ live_search_reached.emit("");
1723+}
1724+
1725+void SearchBar::OnEntryActivated()
1726+{
1727+ activated.emit();
1728+}
1729+
1730+void
1731+SearchBar::SearchFinished()
1732+{
1733+ spinner_->SetState(unity::dash::STATE_CLEAR);
1734+}
1735+
1736+void SearchBar::UpdateBackground()
1737+{
1738+#define PADDING 12
1739+#define RADIUS 5
1740+ int x, y, width, height;
1741+ nux::Geometry geo = GetGeometry();
1742+ geo.width = layered_layout_->GetGeometry().width;
1743+
1744+ if (geo.width == last_width_ && geo.height == last_height_)
1745+ return;
1746+
1747+ last_width_ = geo.width;
1748+ last_height_ = geo.height;
1749+
1750+ x = y = PADDING;
1751+ width = last_width_ - (2 * PADDING);
1752+ height = last_height_ - (2 * PADDING);
1753+
1754+ nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, last_width_, last_height_);
1755+ cairo_t* cr = cairo_graphics.GetContext();
1756+
1757+ cairo_graphics.DrawRoundedRectangle(cr,
1758+ 1.0f,
1759+ x,
1760+ y,
1761+ RADIUS,
1762+ width,
1763+ height,
1764+ true);
1765+
1766+ cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
1767+ cairo_set_line_width(cr, 1.0);
1768+ cairo_stroke_preserve(cr);
1769+ cairo_graphics.BlurSurface (3, cairo_get_target (cr));
1770+
1771+ cairo_operator_t op = CAIRO_OPERATOR_OVER;
1772+ op = cairo_get_operator (cr);
1773+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1774+ cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.5f);
1775+ cairo_fill_preserve(cr);
1776+ cairo_set_operator (cr, op);
1777+ cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.5f);
1778+ cairo_fill_preserve(cr);
1779+ cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 0.8f);
1780+ //cairo_set_line_width(cr, 1.0);
1781+ cairo_stroke(cr);
1782+
1783+ cairo_destroy(cr);
1784+ nux::BaseTexture* texture2D = texture_from_cairo_graphics(cairo_graphics);
1785+
1786+ nux::TexCoordXForm texxform;
1787+ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
1788+ texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
1789+ if (bg_layer_)
1790+ delete bg_layer_;
1791+
1792+ nux::ROPConfig rop;
1793+ rop.Blend = true;
1794+ rop.SrcBlend = GL_ONE;
1795+ rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
1796+
1797+ bg_layer_ = new nux::TextureLayer(texture2D->GetDeviceTexture(),
1798+ texxform,
1799+ nux::color::White,
1800+ true,
1801+ rop);
1802+
1803+ texture2D->UnReference();
1804+}
1805+
1806+void SearchBar::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key)
1807+{
1808+ search_hint = "";
1809+}
1810+
1811+void SearchBar::OnEndKeyFocus()
1812+{
1813+ //search_hint = _("Search");
1814+}
1815+
1816+nux::TextEntry* SearchBar::text_entry() const
1817+{
1818+ return pango_entry_;
1819+}
1820+
1821+std::string SearchBar::get_search_string() const
1822+{
1823+ return pango_entry_->GetText();
1824+}
1825+
1826+bool SearchBar::set_search_string(std::string const& string)
1827+{
1828+ pango_entry_->SetText(string.c_str());
1829+ spinner_->SetState(string == "" ? unity::dash::STATE_READY : unity::dash::STATE_CLEAR);
1830+ return true;
1831+}
1832+
1833+bool SearchBar::get_im_active() const
1834+{
1835+ return pango_entry_->im_active();
1836+}
1837+
1838+//
1839+// Key navigation
1840+//
1841+bool
1842+SearchBar::AcceptKeyNavFocus()
1843+{
1844+ return false;
1845+}
1846+
1847+const gchar* SearchBar::GetName()
1848+{
1849+ return "SearchBar";
1850+}
1851+
1852+const gchar* SearchBar::GetChildsName()
1853+{
1854+ return "";
1855+}
1856+
1857+void SearchBar::AddProperties(GVariantBuilder* builder)
1858+{
1859+ unity::variant::BuilderWrapper(builder).add(GetGeometry());
1860+}
1861+
1862+}
1863+}
1864
1865=== added file 'plugins/unityshell/src/HudSearchBar.h'
1866--- plugins/unityshell/src/HudSearchBar.h 1970-01-01 00:00:00 +0000
1867+++ plugins/unityshell/src/HudSearchBar.h 2012-01-25 11:34:37 +0000
1868@@ -0,0 +1,116 @@
1869+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1870+/*
1871+ * Copyright (C) 2010 Canonical Ltd
1872+ *
1873+ * This program is free software: you can redistribute it and/or modify
1874+ * it under the terms of the GNU General Public License version 3 as
1875+ * published by the Free Software Foundation.
1876+ *
1877+ * This program is distributed in the hope that it will be useful,
1878+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1879+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1880+ * GNU General Public License for more details.
1881+ *
1882+ * You should have received a copy of the GNU General Public License
1883+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1884+ *
1885+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1886+ */
1887+
1888+#ifndef HUD_SEARCH_BAR_H
1889+#define HUD_SEARCH_BAR_H
1890+
1891+#include <gtk/gtk.h>
1892+
1893+#include <NuxCore/Property.h>
1894+#include <Nux/LayeredLayout.h>
1895+#include <Nux/TextureArea.h>
1896+#include <Nux/View.h>
1897+#include <Nux/TextureArea.h>
1898+#include <NuxGraphics/GraphicsEngine.h>
1899+#include <Nux/EditTextBox.h>
1900+#include <Nux/TextEntry.h>
1901+#include <UnityCore/GLibSignal.h>
1902+
1903+#include "DashSearchBarSpinner.h"
1904+#include "IMTextEntry.h"
1905+#include "StaticCairoText.h"
1906+
1907+namespace unity
1908+{
1909+namespace hud
1910+{
1911+
1912+using namespace unity::glib;
1913+
1914+class SearchBar : public nux::View
1915+{
1916+ NUX_DECLARE_OBJECT_TYPE(SearchBar, nux::View);
1917+ typedef nux::ObjectPtr<SearchBar> Ptr;
1918+public:
1919+ SearchBar(NUX_FILE_LINE_PROTO);
1920+ ~SearchBar();
1921+
1922+ void SearchFinished();
1923+ nux::TextEntry* text_entry() const;
1924+
1925+ nux::RWProperty<std::string> search_string;
1926+ nux::Property<std::string> search_hint;
1927+ nux::Property<bool> showing_filters;
1928+ nux::Property<bool> can_refine_search;
1929+ nux::ROProperty<bool> im_active;
1930+
1931+ sigc::signal<void> activated;
1932+ sigc::signal<void, std::string const&> search_changed;
1933+ sigc::signal<void, std::string const&> live_search_reached;
1934+
1935+private:
1936+
1937+ void OnFontChanged(GtkSettings* settings, GParamSpec* pspec=NULL);
1938+ void OnSearchHintChanged();
1939+
1940+ void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
1941+ void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
1942+
1943+ void OnMouseButtonDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
1944+ void OnEndKeyFocus();
1945+
1946+ void UpdateBackground();
1947+ void OnSearchChanged(nux::TextEntry* text_entry);
1948+ void OnClearClicked(int x, int y, unsigned long button_flags, unsigned long key_flags);
1949+ void OnEntryActivated();
1950+ void OnShowingFiltersChanged(bool is_showing);
1951+
1952+ std::string get_search_string() const;
1953+ bool set_search_string(std::string const& string);
1954+ bool get_im_active() const;
1955+
1956+ static gboolean OnLiveSearchTimeout(SearchBar* self);
1957+
1958+ const gchar* GetName();
1959+ const gchar* GetChildsName();
1960+ void AddProperties(GVariantBuilder* builder);
1961+ bool AcceptKeyNavFocus();
1962+
1963+private:
1964+ glib::SignalManager sig_manager_;
1965+
1966+ nux::AbstractPaintLayer* bg_layer_;
1967+ nux::HLayout* layout_;
1968+ nux::LayeredLayout* layered_layout_;
1969+ nux::StaticCairoText* hint_;
1970+ unity::dash::IMTextEntry* pango_entry_;
1971+ nux::StaticCairoText* show_filters_;
1972+
1973+ int last_width_;
1974+ int last_height_;
1975+
1976+ guint live_search_timeout_;
1977+
1978+ unity::dash::SearchBarSpinner* spinner_;
1979+};
1980+
1981+}
1982+}
1983+
1984+#endif
1985
1986=== added file 'plugins/unityshell/src/HudView.cpp'
1987--- plugins/unityshell/src/HudView.cpp 1970-01-01 00:00:00 +0000
1988+++ plugins/unityshell/src/HudView.cpp 2012-01-25 11:34:37 +0000
1989@@ -0,0 +1,377 @@
1990+/*
1991+ * Copyright (C) 2010 Canonical Ltd
1992+ *
1993+ * This program is free software: you can redistribute it and/or modify
1994+ * it under the terms of the GNU General Public License version 3 as
1995+ * published by the Free Software Foundation.
1996+ *
1997+ * This program is distributed in the hope that it will be useful,
1998+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1999+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2000+ * GNU General Public License for more details.
2001+ *
2002+ * You should have received a copy of the GNU General Public License
2003+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2004+ *
2005+ * Authored by: Gord Allott <gord.allott@canonical.com>
2006+ */
2007+
2008+#include "HudView.h"
2009+
2010+#include <math.h>
2011+
2012+#include <gio/gdesktopappinfo.h>
2013+#include <glib/gi18n-lib.h>
2014+#include <gtk/gtk.h>
2015+#include <Nux/Button.h>
2016+#include <iostream>
2017+#include <sstream>
2018+
2019+#include <NuxCore/Logger.h>
2020+#include <UnityCore/GLibWrapper.h>
2021+#include <UnityCore/RadioOptionFilter.h>
2022+#include <Nux/HLayout.h>
2023+#include <Nux/LayeredLayout.h>
2024+
2025+#include <NuxCore/Logger.h>
2026+#include "HudButton.h"
2027+#include "UBusMessages.h"
2028+#include "DashStyle.h"
2029+
2030+namespace unity
2031+{
2032+namespace hud
2033+{
2034+
2035+namespace
2036+{
2037+nux::logging::Logger logger("unity.hud.view");
2038+int icon_size = 42;
2039+const std::string default_text = _("Type your command");
2040+}
2041+
2042+NUX_IMPLEMENT_OBJECT_TYPE(View);
2043+
2044+View::View()
2045+ : nux::View(NUX_TRACKER_LOCATION)
2046+ , button_views_(NULL)
2047+{
2048+ renderer_.SetOwner(this);
2049+ renderer_.need_redraw.connect([this] () {
2050+ QueueDraw();
2051+ });
2052+
2053+ nux::ROPConfig rop;
2054+ rop.Blend = true;
2055+ rop.SrcBlend = GL_ONE;
2056+ rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
2057+
2058+ SetupViews();
2059+ search_bar_->key_down.connect (sigc::mem_fun (this, &View::OnKeyDown));
2060+
2061+ search_bar_->activated.connect ([&]() {
2062+ search_activated.emit(search_bar_->search_string);
2063+ });
2064+
2065+ mouse_down.connect(sigc::mem_fun(this, &View::OnMouseButtonDown));
2066+
2067+ Relayout();
2068+
2069+}
2070+
2071+View::~View()
2072+{
2073+}
2074+
2075+void View::ResetToDefault()
2076+{
2077+ search_bar_->search_string = "";
2078+ search_bar_->search_hint = default_text;
2079+}
2080+
2081+void View::Relayout()
2082+{
2083+ nux::Geometry geo = GetGeometry();
2084+ content_geo_ = GetBestFitGeometry(geo);
2085+ LOG_DEBUG(logger) << "content_geo: " << content_geo_.width << "x" << content_geo_.height;
2086+
2087+ layout_->SetMinMaxSize(content_geo_.width, content_geo_.height);
2088+
2089+ QueueDraw();
2090+}
2091+
2092+long View::PostLayoutManagement(long LayoutResult)
2093+{
2094+ Relayout();
2095+ return LayoutResult;
2096+}
2097+
2098+
2099+nux::View* View::default_focus() const
2100+{
2101+ return search_bar_->text_entry();
2102+}
2103+
2104+void View::SetQueries(Hud::Queries queries)
2105+{
2106+ queries_ = queries_;
2107+ button_views_->Clear();
2108+ int found_items = 0;
2109+ for (auto query = queries.begin(); query != queries.end(); query++)
2110+ {
2111+ if (found_items > 5)
2112+ break;
2113+
2114+ HudButton *button = new HudButton();
2115+ button->SetQuery(*query);
2116+ button_views_->AddView(button, 0, nux::MINOR_POSITION_LEFT);
2117+
2118+ button->click.connect([&](nux::View* view) {
2119+ query_activated.emit(dynamic_cast<HudButton*>(view)->GetQuery());
2120+ });
2121+
2122+ button->OnKeyNavFocusActivate.connect([&](nux::Area *area) {
2123+ query_activated.emit(dynamic_cast<HudButton*>(area)->GetQuery());
2124+ });
2125+
2126+ button->OnKeyNavFocusChange.connect([&](nux::Area *area){
2127+ query_selected.emit(dynamic_cast<HudButton*>(area)->GetQuery());
2128+ });
2129+
2130+ found_items++;
2131+ }
2132+
2133+ QueueRelayout();
2134+ QueueDraw();
2135+}
2136+
2137+void View::SetIcon(std::string icon_name)
2138+{
2139+ LOG_DEBUG(logger) << "Setting icon to " << icon_name;
2140+ icon_->SetByIconName(icon_name.c_str(), icon_size);
2141+ QueueDraw();
2142+}
2143+
2144+// Gives us the width and height of the contents that will give us the best "fit",
2145+// which means that the icons/views will not have uneccessary padding, everything will
2146+// look tight
2147+nux::Geometry View::GetBestFitGeometry(nux::Geometry const& for_geo)
2148+{
2149+ dash::Style& style = dash::Style::Instance();
2150+ int width = 0, height = 0;
2151+ int tile_width = style.GetTileWidth();
2152+ int half = for_geo.width / 2;
2153+
2154+ while ((width += tile_width) + (19 * 2) < half)
2155+ ;
2156+
2157+ width = MAX(width, tile_width * 6);
2158+
2159+ width += 19 + 32;
2160+
2161+ height = search_bar_->GetGeometry().height;
2162+ height += 6;
2163+ height += (style.GetTextLineHeight() + (12*2)) * 6;
2164+ height += 6;
2165+
2166+ LOG_DEBUG (logger) << "best fit is, " << width << ", " << height;
2167+
2168+ return nux::Geometry(0, 0, width, height);
2169+}
2170+
2171+void View::AboutToShow()
2172+{
2173+ renderer_.AboutToShow();
2174+}
2175+
2176+void View::AboutToHide()
2177+{
2178+ renderer_.AboutToHide();
2179+}
2180+
2181+void View::SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo)
2182+{
2183+ window_geometry_ = geo;
2184+ window_geometry_.x = 0;
2185+ window_geometry_.y = 0;
2186+ absolute_window_geometry_ = absolute_geo;
2187+}
2188+
2189+void View::SetupViews()
2190+{
2191+ layout_ = new nux::HLayout();
2192+ layout_->AddLayout(new nux::SpaceLayout(8,8,8,8), 0);
2193+
2194+ icon_ = new Icon("", icon_size, true);
2195+ //icon_->SetBaseSize(icon_size, icon_size);
2196+ //icon_->SetMinMaxSize(icon_size, icon_size);
2197+
2198+ nux::Layout* icon_layout = new nux::VLayout();
2199+ icon_layout->SetVerticalExternalMargin(12);
2200+ icon_layout->AddView(icon_.GetPointer(), 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL);
2201+ layout_->AddLayout(icon_layout, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT);
2202+
2203+
2204+ content_layout_ = new nux::VLayout();
2205+ layout_->AddLayout(content_layout_.GetPointer(), 1, nux::MINOR_POSITION_TOP);
2206+ SetLayout(layout_.GetPointer());
2207+
2208+ // add the search bar to the composite
2209+ search_bar_ = new unity::hud::SearchBar();
2210+ search_bar_->search_hint = default_text;
2211+ search_bar_->search_changed.connect(sigc::mem_fun(this, &View::OnSearchChanged));
2212+ content_layout_->AddView(search_bar_.GetPointer(), 0, nux::MINOR_POSITION_LEFT);
2213+
2214+ button_views_ = new nux::VLayout();
2215+ button_views_->SetHorizontalExternalMargin(12);
2216+ content_layout_->AddLayout(button_views_.GetPointer(), 1, nux::MINOR_POSITION_LEFT);
2217+}
2218+
2219+void View::OnSearchChanged(std::string const& search_string)
2220+{
2221+ LOG_DEBUG(logger) << "got search change";
2222+ search_changed.emit(search_string);
2223+ if (search_string.empty())
2224+ {
2225+ search_bar_->search_hint = default_text;
2226+ }
2227+ else
2228+ {
2229+ search_bar_->search_hint = "";
2230+ }
2231+}
2232+
2233+
2234+void View::OnKeyDown (unsigned long event_type, unsigned long keysym,
2235+ unsigned long event_state, const TCHAR* character,
2236+ unsigned short key_repeat_count)
2237+{
2238+ if (keysym == NUX_VK_ESCAPE)
2239+ {
2240+ LOG_DEBUG(logger) << "got escape key";
2241+ ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST);
2242+ }
2243+}
2244+
2245+void View::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key)
2246+{
2247+ if (!content_geo_.IsPointInside(x, y))
2248+ {
2249+ ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST);
2250+ }
2251+}
2252+
2253+void View::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)
2254+{
2255+ renderer_.DrawFull(gfx_context, layout_->GetGeometry(), absolute_window_geometry_, window_geometry_);
2256+}
2257+
2258+void View::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw)
2259+{
2260+ renderer_.DrawInner(gfx_context, layout_->GetGeometry(), absolute_window_geometry_, window_geometry_);
2261+
2262+ if (IsFullRedraw())
2263+ {
2264+ nux::GetPainter().PushBackgroundStack();
2265+ layout_->ProcessDraw(gfx_context, force_draw);
2266+ nux::GetPainter().PopBackgroundStack();
2267+ }
2268+ else
2269+ {
2270+ layout_->ProcessDraw(gfx_context, force_draw);
2271+ }
2272+
2273+ renderer_.DrawInnerCleanup(gfx_context, layout_->GetGeometry(), absolute_window_geometry_, window_geometry_);
2274+}
2275+
2276+// Keyboard navigation
2277+bool View::AcceptKeyNavFocus()
2278+{
2279+ return false;
2280+}
2281+
2282+// Introspectable
2283+const gchar* View::GetName()
2284+{
2285+ return "unity.hud.View";
2286+}
2287+
2288+void View::AddProperties(GVariantBuilder* builder)
2289+{}
2290+
2291+bool View::InspectKeyEvent(unsigned int eventType,
2292+ unsigned int key_sym,
2293+ const char* character)
2294+{
2295+ if ((eventType == nux::NUX_KEYDOWN) && (key_sym == NUX_VK_ESCAPE))
2296+ {
2297+ if (search_bar_->search_string == "")
2298+ {
2299+ ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST);
2300+ }
2301+ else
2302+ {
2303+ search_bar_->search_string = "";
2304+ search_bar_->search_hint = default_text;
2305+ }
2306+ return true;
2307+ }
2308+ return false;
2309+}
2310+
2311+nux::Area* View::FindKeyFocusArea(unsigned int key_symbol,
2312+ unsigned long x11_key_code,
2313+ unsigned long special_keys_state)
2314+{
2315+ // Do what nux::View does, but if the event isn't a key navigation,
2316+ // designate the text entry to process it.
2317+
2318+ nux::KeyNavDirection direction = nux::KEY_NAV_NONE;
2319+ switch (x11_key_code)
2320+ {
2321+ case NUX_VK_UP:
2322+ direction = nux::KEY_NAV_UP;
2323+ break;
2324+ case NUX_VK_DOWN:
2325+ direction = nux::KEY_NAV_DOWN;
2326+ break;
2327+ case NUX_VK_LEFT:
2328+ direction = nux::KEY_NAV_LEFT;
2329+ break;
2330+ case NUX_VK_RIGHT:
2331+ direction = nux::KEY_NAV_RIGHT;
2332+ break;
2333+ case NUX_VK_LEFT_TAB:
2334+ direction = nux::KEY_NAV_TAB_PREVIOUS;
2335+ break;
2336+ case NUX_VK_TAB:
2337+ direction = nux::KEY_NAV_TAB_NEXT;
2338+ break;
2339+ case NUX_VK_ENTER:
2340+ case NUX_KP_ENTER:
2341+ // Not sure if Enter should be a navigation key
2342+ direction = nux::KEY_NAV_ENTER;
2343+ break;
2344+ default:
2345+ direction = nux::KEY_NAV_NONE;
2346+ break;
2347+ }
2348+
2349+ if (has_key_focus_)
2350+ {
2351+ return this;
2352+ }
2353+ else if (direction == nux::KEY_NAV_NONE)
2354+ {
2355+ // then send the event to the search entry
2356+ return search_bar_->text_entry();
2357+ }
2358+ else if (next_object_to_key_focus_area_)
2359+ {
2360+ return next_object_to_key_focus_area_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state);
2361+ }
2362+ return NULL;
2363+}
2364+
2365+}
2366+}
2367
2368=== added file 'plugins/unityshell/src/HudView.h'
2369--- plugins/unityshell/src/HudView.h 1970-01-01 00:00:00 +0000
2370+++ plugins/unityshell/src/HudView.h 2012-01-25 11:34:37 +0000
2371@@ -0,0 +1,115 @@
2372+/*
2373+ * Copyright (C) 2010 Canonical Ltd
2374+ *
2375+ * This program is free software: you can redistribute it and/or modify
2376+ * it under the terms of the GNU General Public License version 3 as
2377+ * published by the Free Software Foundation.
2378+ *
2379+ * This program is distributed in the hope that it will be useful,
2380+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2381+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2382+ * GNU General Public License for more details.
2383+ *
2384+ * You should have received a copy of the GNU General Public License
2385+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2386+ *
2387+ * Authored by: Gordon Allott <gord.allott@canonical.com>
2388+ */
2389+
2390+#ifndef UNITY_HUD_VIEW_H_
2391+#define UNITY_HUD_VIEW_H_
2392+
2393+#include <string>
2394+
2395+#include <NuxGraphics/GraphicsEngine.h>
2396+#include <Nux/Nux.h>
2397+#include <Nux/PaintLayer.h>
2398+#include <Nux/View.h>
2399+#include <Nux/VLayout.h>
2400+#include <StaticCairoText.h>
2401+
2402+#include <glib.h>
2403+
2404+#include <UnityCore/Hud.h>
2405+
2406+#include "UBusWrapper.h"
2407+#include "HudIcon.h"
2408+#include "HudSearchBar.h"
2409+#include "OverlayRenderer.h"
2410+
2411+namespace unity
2412+{
2413+namespace hud
2414+{
2415+
2416+class View : public nux::View
2417+{
2418+ NUX_DECLARE_OBJECT_TYPE(HudView, nux::View);
2419+ typedef nux::ObjectPtr<View> Ptr;
2420+public:
2421+ View();
2422+ ~View();
2423+
2424+ void ResetToDefault();
2425+
2426+ void Relayout();
2427+ nux::View* default_focus() const;
2428+
2429+ void SetQueries(Hud::Queries queries);
2430+ void SetIcon(std::string icon_name);
2431+
2432+ void AboutToShow();
2433+ void AboutToHide();
2434+
2435+ void SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo);
2436+
2437+ sigc::signal<void, std::string> search_changed;
2438+ sigc::signal<void, std::string> search_activated;
2439+ sigc::signal<void, Query::Ptr> query_activated;
2440+ sigc::signal<void, Query::Ptr> query_selected;
2441+
2442+protected:
2443+ virtual Area* FindKeyFocusArea(unsigned int key_symbol,
2444+ unsigned long x11_key_code,
2445+ unsigned long special_keys_state);
2446+
2447+ void SetupViews();
2448+ void OnSearchChanged(std::string const& search_string);
2449+ virtual long PostLayoutManagement(long LayoutResult);
2450+private:
2451+ void OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key);
2452+ void OnKeyDown (unsigned long event_type, unsigned long event_keysym,
2453+ unsigned long event_state, const TCHAR* character,
2454+ unsigned short key_repeat_count);
2455+ void Draw(nux::GraphicsEngine& gfx_context, bool force_draw);
2456+ void DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw);
2457+ bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character);
2458+ bool AcceptKeyNavFocus();
2459+ nux::Geometry GetBestFitGeometry(nux::Geometry const& for_geo);
2460+
2461+ const gchar* GetName();
2462+ void AddProperties(GVariantBuilder* builder);
2463+
2464+private:
2465+ UBusManager ubus;
2466+ nux::ObjectPtr<nux::Layout> layout_;
2467+ nux::ObjectPtr<nux::Layout> content_layout_;
2468+ nux::ObjectPtr<nux::VLayout> button_views_;
2469+
2470+ //FIXME - replace with dash search bar once modifications to dash search bar land
2471+ SearchBar::Ptr search_bar_;
2472+ Icon::Ptr icon_;
2473+ bool visible_;
2474+
2475+ Hud::Queries queries_;
2476+ nux::Geometry content_geo_;
2477+ OverlayRenderer renderer_;
2478+ nux::Geometry window_geometry_;
2479+ nux::Geometry absolute_window_geometry_;
2480+};
2481+
2482+
2483+}
2484+}
2485+#endif
2486+
2487
2488=== modified file 'plugins/unityshell/src/IconTexture.cpp'
2489--- plugins/unityshell/src/IconTexture.cpp 2011-11-08 18:21:44 +0000
2490+++ plugins/unityshell/src/IconTexture.cpp 2012-01-25 11:34:37 +0000
2491@@ -24,6 +24,7 @@
2492 #include <pango/pangocairo.h>
2493
2494 #include <Nux/Nux.h>
2495+#include <NuxCore/Logger.h>
2496 #include <NuxGraphics/GLThread.h>
2497 #include <UnityCore/GLibWrapper.h>
2498 #include <UnityCore/Variant.h>
2499@@ -37,6 +38,7 @@
2500 namespace
2501 {
2502 const char* const DEFAULT_ICON = "text-x-preview";
2503+nux::logging::Logger logger("unity.icontexture");
2504 }
2505
2506 using namespace unity;
2507@@ -67,7 +69,7 @@
2508 {
2509 _icon_name = g_strdup(icon_name ? icon_name : DEFAULT_ICON);
2510
2511- if (!g_strcmp0(_icon_name, "") == 0 && !defer_icon_loading)
2512+ if (g_strcmp0(_icon_name, "") != 0 && !defer_icon_loading)
2513 LoadIcon();
2514 }
2515
2516@@ -78,25 +80,33 @@
2517
2518 void IconTexture::SetByIconName(const char* icon_name, unsigned int size)
2519 {
2520- g_free(_icon_name);
2521- _icon_name = g_strdup(icon_name);
2522- _size = size;
2523- LoadIcon();
2524+ if (g_strcmp0(icon_name, "") != 0)
2525+ {
2526+ g_free(_icon_name);
2527+ _icon_name = g_strdup(icon_name);
2528+ _size = size;
2529+ LoadIcon();
2530+ }
2531 }
2532
2533 void IconTexture::SetByFilePath(const char* file_path, unsigned int size)
2534 {
2535- g_free(_icon_name);
2536- _icon_name = g_strdup(file_path);
2537- _size = size;
2538+ if (g_strcmp0(file_path, "") != 0)
2539+ {
2540+ g_free(_icon_name);
2541+ _icon_name = g_strdup(file_path);
2542+ _size = size;
2543
2544- LoadIcon();
2545+ LoadIcon();
2546+ }
2547 }
2548
2549 void IconTexture::LoadIcon()
2550 {
2551 static const char* const DEFAULT_GICON = ". GThemedIcon text-x-preview";
2552-
2553+ if (_icon_name == NULL)
2554+ return;
2555+
2556 if (_loading)
2557 return;
2558 _loading = true;
2559@@ -144,6 +154,7 @@
2560 _texture_height,
2561 sigc::mem_fun(this, &IconTexture::CreateTextureCallback));
2562 QueueDraw();
2563+ _loading = false;
2564 }
2565
2566 void IconTexture::IconLoaded(std::string const& icon_name, unsigned size,
2567@@ -162,6 +173,8 @@
2568 if (icon_name != DEFAULT_ICON)
2569 SetByIconName(DEFAULT_ICON, _size);
2570 }
2571+
2572+ QueueDraw();
2573 }
2574
2575 void IconTexture::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
2576
2577=== modified file 'plugins/unityshell/src/Launcher.cpp'
2578--- plugins/unityshell/src/Launcher.cpp 2012-01-23 13:07:40 +0000
2579+++ plugins/unityshell/src/Launcher.cpp 2012-01-25 11:34:37 +0000
2580@@ -282,8 +282,8 @@
2581 _drag_window = NULL;
2582 _offscreen_drag_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(2, 2, 1, nux::BITFMT_R8G8B8A8);
2583
2584- ubus.RegisterInterest(UBUS_PLACE_VIEW_SHOWN, sigc::mem_fun(this, &Launcher::OnPlaceViewShown));
2585- ubus.RegisterInterest(UBUS_PLACE_VIEW_HIDDEN, sigc::mem_fun(this, &Launcher::OnPlaceViewHidden));
2586+ ubus.RegisterInterest(UBUS_OVERLAY_SHOWN, sigc::mem_fun(this, &Launcher::OnOverlayShown));
2587+ ubus.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::mem_fun(this, &Launcher::OnOverlayHidden));
2588 ubus.RegisterInterest(UBUS_LAUNCHER_ACTION_DONE, sigc::mem_fun(this, &Launcher::OnActionDone));
2589 ubus.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, sigc::mem_fun(this, &Launcher::OnBGColorChanged));
2590 ubus.RegisterInterest(UBUS_LAUNCHER_LOCK_HIDE, sigc::mem_fun(this, &Launcher::OnLockHideChanged));
2591@@ -1490,34 +1490,52 @@
2592 }
2593 }
2594
2595-void Launcher::OnPlaceViewShown(GVariant* data)
2596+void Launcher::OnOverlayShown(GVariant* data)
2597 {
2598- LauncherModel::iterator it;
2599-
2600- _dash_is_open = true;
2601- bg_effect_helper_.enabled = true;
2602- _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, true);
2603- _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, true);
2604-
2605- DesaturateIcons();
2606+ // check the type of overlay
2607+ gchar* overlay_identity = NULL;
2608+ gboolean can_maximise = FALSE;
2609+ g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING,
2610+ &overlay_identity, &can_maximise);
2611+
2612+ if (!g_strcmp0(overlay_identity, "dash"))
2613+ {
2614+ LauncherModel::iterator it;
2615+
2616+ _dash_is_open = true;
2617+ bg_effect_helper_.enabled = true;
2618+ _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, true);
2619+ _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, true);
2620+
2621+ DesaturateIcons();
2622+ }
2623 }
2624
2625-void Launcher::OnPlaceViewHidden(GVariant* data)
2626+void Launcher::OnOverlayHidden(GVariant* data)
2627 {
2628- LauncherModel::iterator it;
2629-
2630- _dash_is_open = false;
2631- bg_effect_helper_.enabled = false;
2632- _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, false);
2633- _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, false);
2634-
2635- // as the leave event is no more received when the place is opened
2636- // FIXME: remove when we change the mouse grab strategy in nux
2637- nux::Point pt = nux::GetWindowCompositor().GetMousePosition();
2638-
2639- SetStateMouseOverLauncher(GetAbsoluteGeometry().IsInside(pt));
2640-
2641- SaturateIcons();
2642+ // check the type of overlay
2643+ gchar* overlay_identity = NULL;
2644+ gboolean can_maximise = FALSE;
2645+ g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING,
2646+ &overlay_identity, &can_maximise);
2647+
2648+ if (!g_strcmp0(overlay_identity, "dash"))
2649+ {
2650+ LauncherModel::iterator it;
2651+
2652+ _dash_is_open = false;
2653+ bg_effect_helper_.enabled = false;
2654+ _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, false);
2655+ _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, false);
2656+
2657+ // as the leave event is no more received when the place is opened
2658+ // FIXME: remove when we change the mouse grab strategy in nux
2659+ nux::Point pt = nux::GetWindowCompositor().GetMousePosition();
2660+
2661+ SetStateMouseOverLauncher(GetAbsoluteGeometry().IsInside(pt));
2662+
2663+ SaturateIcons();
2664+ }
2665 }
2666
2667 void Launcher::OnActionDone(GVariant* data)
2668
2669=== modified file 'plugins/unityshell/src/Launcher.h'
2670--- plugins/unityshell/src/Launcher.h 2012-01-23 13:07:40 +0000
2671+++ plugins/unityshell/src/Launcher.h 2012-01-25 11:34:37 +0000
2672@@ -350,8 +350,8 @@
2673
2674 void OnIconNeedsRedraw(AbstractLauncherIcon* icon);
2675
2676- void OnPlaceViewHidden(GVariant* data);
2677- void OnPlaceViewShown(GVariant* data);
2678+ void OnOverlayHidden(GVariant* data);
2679+ void OnOverlayShown(GVariant* data);
2680
2681 void DesaturateIcons();
2682 void SaturateIcons();
2683
2684=== modified file 'plugins/unityshell/src/PanelMenuView.cpp'
2685--- plugins/unityshell/src/PanelMenuView.cpp 2012-01-12 13:36:44 +0000
2686+++ plugins/unityshell/src/PanelMenuView.cpp 2012-01-25 11:34:37 +0000
2687@@ -155,10 +155,10 @@
2688
2689 // Register for all the interesting events
2690 UBusServer* ubus = ubus_server_get_default();
2691- _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_SHOWN,
2692+ _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_OVERLAY_SHOWN,
2693 (UBusCallback)PanelMenuView::OnPlaceViewShown,
2694 this));
2695- _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_HIDDEN,
2696+ _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_OVERLAY_HIDDEN,
2697 (UBusCallback)PanelMenuView::OnPlaceViewHidden,
2698 this));
2699
2700
2701=== modified file 'plugins/unityshell/src/PanelView.cpp'
2702--- plugins/unityshell/src/PanelView.cpp 2012-01-16 07:34:25 +0000
2703+++ plugins/unityshell/src/PanelView.cpp 2012-01-25 11:34:37 +0000
2704@@ -103,11 +103,11 @@
2705 (UBusCallback)&PanelView::OnBackgroundUpdate,
2706 this);
2707
2708- _handle_dash_hidden = ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_HIDDEN,
2709+ _handle_dash_hidden = ubus_server_register_interest(ubus, UBUS_OVERLAY_HIDDEN,
2710 (UBusCallback)&PanelView::OnDashHidden,
2711 this);
2712
2713- _handle_dash_shown = ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_SHOWN,
2714+ _handle_dash_shown = ubus_server_register_interest(ubus, UBUS_OVERLAY_SHOWN,
2715 (UBusCallback)&PanelView::OnDashShown,
2716 this);
2717 // request the latest colour from bghash
2718
2719=== modified file 'plugins/unityshell/src/PlacesHomeView.cpp'
2720--- plugins/unityshell/src/PlacesHomeView.cpp 2011-12-14 20:04:23 +0000
2721+++ plugins/unityshell/src/PlacesHomeView.cpp 2012-01-25 11:34:37 +0000
2722@@ -106,7 +106,7 @@
2723 (style.GetHomeTileHeight() * 2) + 32);
2724
2725 _ubus_handle = ubus_server_register_interest(ubus_server_get_default(),
2726- UBUS_PLACE_VIEW_SHOWN,
2727+ UBUS_OVERLAY_SHOWN,
2728 (UBusCallback) &PlacesHomeView::DashVisible,
2729 this);
2730
2731
2732=== modified file 'plugins/unityshell/src/UBusMessages.h'
2733--- plugins/unityshell/src/UBusMessages.h 2012-01-17 15:41:30 +0000
2734+++ plugins/unityshell/src/UBusMessages.h 2012-01-25 11:34:37 +0000
2735@@ -34,9 +34,11 @@
2736 #define UBUS_PLACE_ENTRY_ACTIVATE_REQUEST "PLACE_ENTRY_ACTIVATE_REQUEST"
2737 #define UBUS_DASH_ABOUT_TO_SHOW "DASH_ABOUT_TO_SHOW"
2738
2739-// Signal send when places are shown or hidden
2740-#define UBUS_PLACE_VIEW_HIDDEN "PLACE_VIEW_HIDDEN"
2741-#define UBUS_PLACE_VIEW_SHOWN "PLACE_VIEW_SHOWN"
2742+// Signal sent when an overlay interface is shown, includes a gvariant
2743+// gvariant format is (sb), (interface-name, can_maximize?)
2744+#define UBUS_OVERLAY_FORMAT_STRING "(sb)"
2745+#define UBUS_OVERLAY_HIDDEN "OVERLAY_HIDDEN"
2746+#define UBUS_OVERLAY_SHOWN "OVERLAY_SHOWN"
2747
2748 #define UBUS_PLACE_VIEW_QUEUE_DRAW "PLACE_VIEW_QUEUE_DRAW"
2749
2750@@ -76,6 +78,8 @@
2751 // FIXME - fix the nux focus api so we don't need this
2752 #define UBUS_RESULT_VIEW_KEYNAV_CHANGED "RESULT_VIEW_KEYNAV_CHANGED"
2753
2754+#define UBUS_HUD_CLOSE_REQUEST "HUD_CLOSE_REQUEST"
2755+
2756 // Signals sent when the switcher is shown, hidden or changes selection
2757 #define UBUS_SWITCHER_SHOWN "SWITCHER_SHOWN"
2758 #define UBUS_SWITCHER_SELECTION_CHANGED "SWITCHER_SELECTION_CHANGED"
2759
2760=== modified file 'plugins/unityshell/src/WindowButtons.cpp'
2761--- plugins/unityshell/src/WindowButtons.cpp 2011-12-14 20:04:23 +0000
2762+++ plugins/unityshell/src/WindowButtons.cpp 2012-01-25 11:34:37 +0000
2763@@ -54,7 +54,7 @@
2764 _normal_dash_tex(NULL),
2765 _prelight_dash_tex(NULL),
2766 _pressed_dash_tex(NULL),
2767- _dash_is_open(false),
2768+ _overlay_is_open(false),
2769 _mouse_is_down(false),
2770 _place_shown_interest(0),
2771 _place_hidden_interest(0),
2772@@ -66,11 +66,11 @@
2773 dash::Settings::Instance().changed.connect(sigc::mem_fun(this, &WindowButton::UpdateDashUnmaximize));
2774
2775 UBusServer* ubus = ubus_server_get_default();
2776- _place_shown_interest = ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_SHOWN,
2777- (UBusCallback)&WindowButton::OnPlaceViewShown,
2778+ _place_shown_interest = ubus_server_register_interest(ubus, UBUS_OVERLAY_SHOWN,
2779+ (UBusCallback)&WindowButton::OnOverlayShown,
2780 this);
2781- _place_hidden_interest = ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_HIDDEN,
2782- (UBusCallback)&WindowButton::OnPlaceViewHidden,
2783+ _place_hidden_interest = ubus_server_register_interest(ubus, UBUS_OVERLAY_HIDDEN,
2784+ (UBusCallback)&WindowButton::OnOverlayHidden,
2785 this);
2786
2787 /* FIXME HasMouseFocus() doesn't seem to work correctly, so we use this workaround */
2788@@ -106,7 +106,7 @@
2789
2790 GfxContext.PushClippingRectangle(geo);
2791
2792- if (_dash_is_open)
2793+ if (_overlay_is_open)
2794 {
2795 //FIXME should use HasMouseFocus()
2796 if (_mouse_is_down && IsMouseInside())
2797@@ -163,7 +163,7 @@
2798 _prelight_dash_tex = GetDashWindowButton(_type, panel::WindowState::PRELIGHT);
2799 _pressed_dash_tex = GetDashWindowButton(_type, panel::WindowState::PRESSED);
2800
2801- if (_dash_is_open)
2802+ if (_overlay_is_open)
2803 {
2804 if (_normal_dash_tex)
2805 SetMinMaxSize(_normal_dash_tex->GetWidth(), _normal_dash_tex->GetHeight());
2806@@ -190,6 +190,7 @@
2807 if (_pressed_dash_tex)
2808 _pressed_dash_tex->UnReference();
2809
2810+ //!!FIXME!! - don't have disabled instances of the (un)maximize buttons
2811 if (dash::Settings::Instance().GetFormFactor() == dash::FormFactor::DESKTOP)
2812 {
2813 // get maximize buttons
2814@@ -208,7 +209,7 @@
2815 // still check if the dash is really opened,
2816 // someone could change the form factor through dconf
2817 // when the dash is closed
2818- if (_dash_is_open)
2819+ if (_overlay_is_open)
2820 {
2821 if (_normal_dash_tex)
2822 SetMinMaxSize(_normal_dash_tex->GetWidth(), _normal_dash_tex->GetHeight());
2823@@ -239,28 +240,35 @@
2824 nux::BaseTexture* _normal_dash_tex;
2825 nux::BaseTexture* _prelight_dash_tex;
2826 nux::BaseTexture* _pressed_dash_tex;
2827- bool _dash_is_open;
2828+ bool _overlay_is_open;
2829+ bool _overlay_can_maximize;
2830 bool _mouse_is_down;
2831 guint32 _place_shown_interest;
2832 guint32 _place_hidden_interest;
2833 double _opacity;
2834
2835- static void OnPlaceViewShown(GVariant* data, void* val)
2836+ static void OnOverlayShown(GVariant* data, void* val)
2837 {
2838+ gchar* overlay_identity = NULL;
2839+ gboolean can_maximise = FALSE;
2840+ g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING,
2841+ &overlay_identity, &can_maximise);
2842 WindowButton* self = (WindowButton*)val;
2843
2844- self->_dash_is_open = true;
2845+ self->_overlay_is_open = true;
2846 if (self->_normal_dash_tex)
2847 self->SetMinMaxSize(self->_normal_dash_tex->GetWidth(), self->_normal_dash_tex->GetHeight());
2848
2849+ self->_overlay_can_maximize = (can_maximise) ? true : false;
2850+
2851 self->QueueDraw();
2852 }
2853
2854- static void OnPlaceViewHidden(GVariant* data, void* val)
2855+ static void OnOverlayHidden(GVariant* data, void* val)
2856 {
2857 WindowButton* self = (WindowButton*)val;
2858
2859- self->_dash_is_open = false;
2860+ self->_overlay_is_open = false;
2861 if (self->_normal_tex)
2862 self->SetMinMaxSize(self->_normal_tex->GetWidth(), self->_normal_tex->GetHeight());
2863
2864
2865=== modified file 'plugins/unityshell/src/unityshell.cpp'
2866--- plugins/unityshell/src/unityshell.cpp 2012-01-20 06:47:42 +0000
2867+++ plugins/unityshell/src/unityshell.cpp 2012-01-25 11:34:37 +0000
2868@@ -118,6 +118,7 @@
2869 , dash_is_open_ (false)
2870 , grab_index_ (0)
2871 , painting_tray_ (false)
2872+ , last_hud_show_time_(0)
2873 {
2874 Timer timer;
2875 gfloat version;
2876@@ -206,9 +207,9 @@
2877
2878 nux::NuxInitialize(0);
2879 wt = nux::CreateFromForeignWindow(cScreen->output(),
2880- glXGetCurrentContext(),
2881- &UnityScreen::initUnity,
2882- this);
2883+ glXGetCurrentContext(),
2884+ &UnityScreen::initUnity,
2885+ this);
2886
2887 wt->RedrawRequested.connect(sigc::mem_fun(this, &UnityScreen::onRedrawRequested));
2888
2889@@ -243,6 +244,9 @@
2890 uScreen->_fbo->onScreenSizeChanged (geometry);
2891 }
2892
2893+ optionSetShowHudInitiate(boost::bind(&UnityScreen::ShowHudInitiate, this, _1, _2, _3));
2894+ optionSetShowHudTerminate(boost::bind(&UnityScreen::ShowHudTerminate, this, _1, _2, _3));
2895+
2896 optionSetBackgroundColorNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
2897 optionSetLauncherHideModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
2898 optionSetBacklightModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
2899@@ -301,19 +305,19 @@
2900
2901 UBusServer* ubus = ubus_server_get_default();
2902 _ubus_handles[0] = ubus_server_register_interest(ubus,
2903- UBUS_LAUNCHER_START_KEY_NAV,
2904- (UBusCallback)&UnityScreen::OnLauncherStartKeyNav,
2905- this);
2906+ UBUS_LAUNCHER_START_KEY_NAV,
2907+ (UBusCallback)&UnityScreen::OnLauncherStartKeyNav,
2908+ this);
2909
2910 _ubus_handles[1] = ubus_server_register_interest(ubus,
2911- UBUS_LAUNCHER_END_KEY_NAV,
2912- (UBusCallback)&UnityScreen::OnLauncherEndKeyNav,
2913- this);
2914+ UBUS_LAUNCHER_END_KEY_NAV,
2915+ (UBusCallback)&UnityScreen::OnLauncherEndKeyNav,
2916+ this);
2917
2918 _ubus_handles[2] = ubus_server_register_interest(ubus,
2919- UBUS_QUICKLIST_END_KEY_NAV,
2920- (UBusCallback)&UnityScreen::OnQuicklistEndKeyNav,
2921- this);
2922+ UBUS_QUICKLIST_END_KEY_NAV,
2923+ (UBusCallback)&UnityScreen::OnQuicklistEndKeyNav,
2924+ this);
2925
2926 g_idle_add_full (G_PRIORITY_DEFAULT, &UnityScreen::initPluginActions, this, NULL);
2927 super_keypressed_ = false;
2928@@ -328,11 +332,11 @@
2929
2930 BackgroundEffectHelper::updates_enabled = true;
2931
2932- ubus_manager_.RegisterInterest(UBUS_PLACE_VIEW_SHOWN, [&](GVariant * args) {
2933+ ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, [&](GVariant * args) {
2934 dash_is_open_ = true;
2935 RaiseInputWindows();
2936 });
2937- ubus_manager_.RegisterInterest(UBUS_PLACE_VIEW_HIDDEN, [&](GVariant * args) { dash_is_open_ = false; });
2938+ ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, [&](GVariant * args) { dash_is_open_ = false; });
2939 LOG_INFO(logger) << "UnityScreen constructed: " << timer.ElapsedSeconds() << "s";
2940 }
2941 }
2942@@ -372,7 +376,7 @@
2943 sout << "<Alt>" << XKeysymToString(above_tab_keysym);
2944
2945 screen->removeAction(&optionGetAltTabNextWindow());
2946-
2947+
2948 CompAction action = CompAction();
2949 action.keyFromString(sout.str());
2950 action.setState (CompAction::StateInitKey | CompAction::StateAutoGrab);
2951@@ -387,7 +391,7 @@
2952 sout << "<Alt><Shift>" << XKeysymToString(above_tab_keysym);
2953
2954 screen->removeAction(&optionGetAltTabPrevWindow());
2955-
2956+
2957 CompAction action = CompAction();
2958 action.keyFromString(sout.str());
2959 action.setState (CompAction::StateInitKey | CompAction::StateAutoGrab);
2960@@ -638,9 +642,9 @@
2961 uTrayWindow->gWindow->glAddGeometrySetCurrentIndex ( MAXSHORT);
2962 uTrayWindow->gWindow->glDrawGeometrySetCurrentIndex (MAXSHORT);
2963 uTrayWindow->gWindow->glDraw (oTransform, attrib, infiniteRegion,
2964- PAINT_WINDOW_TRANSFORMED_MASK |
2965- PAINT_WINDOW_BLEND_MASK |
2966- PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK);
2967+ PAINT_WINDOW_TRANSFORMED_MASK |
2968+ PAINT_WINDOW_BLEND_MASK |
2969+ PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK);
2970 uTrayWindow->gWindow->glDrawGeometrySetCurrentIndex (oldGlDrawGeometryIndex);
2971 uTrayWindow->gWindow->glAddGeometrySetCurrentIndex (oldGlAddGeometryIndex);
2972 uTrayWindow->gWindow->glDrawSetCurrentIndex (oldGlDrawIndex);
2973@@ -673,8 +677,8 @@
2974 bool UnityScreen::forcePaintOnTop ()
2975 {
2976 return !allowWindowPaint ||
2977- ((switcher_controller_->Visible() ||
2978- dash_is_open_) && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
2979+ ((switcher_controller_->Visible() ||
2980+ dash_is_open_) && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
2981 }
2982
2983 void UnityWindow::paintThumbnail (nux::Geometry const& bounding, float alpha)
2984@@ -801,7 +805,7 @@
2985 {
2986 if (mShowdesktopHandler)
2987 if (mShowdesktopHandler->animate (ms))
2988- {
2989+ {
2990 delete mShowdesktopHandler;
2991 mShowdesktopHandler = NULL;
2992 return true;
2993@@ -830,7 +834,7 @@
2994 return false;
2995
2996 if (w->state () & (CompWindowStateSkipPagerMask |
2997- CompWindowStateSkipTaskbarMask))
2998+ CompWindowStateSkipTaskbarMask))
2999 return false;
3000
3001 if ((w->state () & CompWindowStateHiddenMask))
3002@@ -1225,7 +1229,7 @@
3003 PluginAdapter::Default()->NotifyCompizEvent(plugin, event, option);
3004 compiz::CompizMinimizedWindowHandler<UnityScreen, UnityWindow>::handleCompizEvent (plugin, event, option);
3005
3006- if (dash_is_open_ &&
3007+ if (dash_is_open_ &&
3008 strcmp(event, "start_viewport_switch") == 0)
3009 {
3010 ubus_server_send_message(ubus_server_get_default(), UBUS_PLACE_VIEW_CLOSE_REQUEST, NULL);
3011@@ -1433,7 +1437,7 @@
3012 grab_index_ = screen->pushGrab (screen->invisibleCursor(), "unity-switcher");
3013 if (!grab_index_)
3014 return false;
3015-
3016+
3017 std::vector<unity::launcher::AbstractLauncherIcon*> results = launcher_controller_->GetAltTabIcons();
3018
3019 screen->addAction(&optionGetAltTabRight());
3020@@ -1524,7 +1528,7 @@
3021 altTabInitiateCommon(action, state, options);
3022 switcher_controller_->Select(1); // always select the current application
3023 }
3024-
3025+
3026 switcher_controller_->NextDetail();
3027
3028 action->setState(action->state() | CompAction::StateTermKey);
3029@@ -1535,7 +1539,7 @@
3030 {
3031 if (switcher_controller_->Visible())
3032 switcher_controller_->PrevDetail();
3033-
3034+
3035 return false;
3036 }
3037
3038@@ -1584,6 +1588,35 @@
3039 PluginAdapter::Default ()->restoreInputFocus ();
3040 }
3041
3042+bool UnityScreen::ShowHudInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
3043+{
3044+ // to receive the Terminate event
3045+ if (state & CompAction::StateInitKey)
3046+ action->setState(action->state() | CompAction::StateTermKey);
3047+
3048+ last_hud_show_time_ = g_get_monotonic_time();
3049+
3050+ return false;
3051+}
3052+
3053+bool UnityScreen::ShowHudTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
3054+{
3055+ if (optionGetShowHud().key().toString() == action->key().toString())
3056+ {
3057+ if (switcher_controller_->Visible())
3058+ return false; // early exit if the switcher is open
3059+
3060+ gint64 current_time = g_get_monotonic_time();
3061+ if (current_time - last_hud_show_time_ < 150 * 1000)
3062+ {
3063+ // less than 50 ms have passed, thats a tap
3064+ hud_controller_->ShowHideHud();
3065+ last_hud_show_time_ = 0;
3066+ }
3067+ }
3068+ return false;
3069+}
3070+
3071 void UnityScreen::OnQuicklistEndKeyNav(GVariant* data, void* value)
3072 {
3073 UnityScreen* self = reinterpret_cast<UnityScreen*>(value);
3074@@ -1676,7 +1709,7 @@
3075 bool result = screen->initPluginForScreen(p);
3076 if (p->vTable->name() == "unityshell")
3077 initAltTabNextWindow();
3078-
3079+
3080 return result;
3081 }
3082
3083@@ -1689,8 +1722,8 @@
3084 return "Unity";
3085 }
3086
3087-bool isNuxWindow (CompWindow* value)
3088-{
3089+bool isNuxWindow (CompWindow* value)
3090+{
3091 std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
3092 auto id = value->id();
3093
3094@@ -1717,7 +1750,7 @@
3095 void UnityScreen::RaiseInputWindows()
3096 {
3097 std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
3098-
3099+
3100 for (auto window : xwns)
3101 {
3102 CompWindow* cwin = screen->findWindow(window);
3103@@ -1842,7 +1875,7 @@
3104 if (!window->onCurrentDesktop ())
3105 return false;
3106
3107- /* Only withdrawn windows
3108+ /* Only withdrawn windows
3109 * which are marked hidden
3110 * are excluded */
3111 if (!window->shaded () &&
3112@@ -1850,8 +1883,8 @@
3113 (window->state () & CompWindowStateHiddenMask))
3114 return false;
3115
3116- if (window->geometry ().x () + window->geometry ().width () <= 0 ||
3117- window->geometry ().y () + window->geometry ().height () <= 0 ||
3118+ if (window->geometry ().x () + window->geometry ().width () <= 0 ||
3119+ window->geometry ().y () + window->geometry ().height () <= 0 ||
3120 window->geometry ().x () >= (int) screen->width ()||
3121 window->geometry ().y () >= (int) screen->height ())
3122 return false;
3123@@ -1957,7 +1990,7 @@
3124 !(lastState & CompWindowStateFullscreenMask))
3125 UnityScreen::get (screen)->fullscreen_windows_.push_back(window);
3126 else if (lastState & CompWindowStateFullscreenMask &&
3127- !(window->state () & CompWindowStateFullscreenMask))
3128+ !(window->state () & CompWindowStateFullscreenMask))
3129 UnityScreen::get (screen)->fullscreen_windows_.remove(window);
3130
3131 PluginAdapter::Default()->NotifyStateChange(window, window->state(), lastState);
3132@@ -2136,9 +2169,9 @@
3133 {
3134 case UnityshellOptions::BackgroundColor:
3135 {
3136- nux::Color override_color (optionGetBackgroundColorRed() / 65535.0f,
3137- optionGetBackgroundColorGreen() / 65535.0f,
3138- optionGetBackgroundColorBlue() / 65535.0f,
3139+ nux::Color override_color (optionGetBackgroundColorRed() / 65535.0f,
3140+ optionGetBackgroundColorGreen() / 65535.0f,
3141+ optionGetBackgroundColorBlue() / 65535.0f,
3142 optionGetBackgroundColorAlpha() / 65535.0f);
3143
3144 override_color.red = override_color.red / override_color.alpha;
3145@@ -2185,6 +2218,7 @@
3146
3147 launcher.SetIconSize(optionGetIconSize() + 6, optionGetIconSize());
3148 dash_controller_->launcher_width = optionGetIconSize() + 18;
3149+ hud_controller_->launcher_width = optionGetIconSize() + 18;
3150
3151 if (p)
3152 {
3153@@ -2360,6 +2394,10 @@
3154 /* Setup Places */
3155 dash_controller_.reset(new dash::Controller());
3156 dash_controller_->on_realize.connect(sigc::mem_fun(this, &UnityScreen::OnDashRealized));
3157+
3158+ /* Setup Hud */
3159+ hud_controller_.reset(new hud::Controller());
3160+ LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s";
3161
3162 // Setup Shortcut Hint
3163 InitHints();
3164@@ -2515,7 +2553,7 @@
3165
3166 if (mShowdesktopHandler)
3167 delete mShowdesktopHandler;
3168-
3169+
3170 if (focusdesktop_handle_)
3171 g_source_remove(focusdesktop_handle_);
3172
3173
3174=== modified file 'plugins/unityshell/src/unityshell.h'
3175--- plugins/unityshell/src/unityshell.h 2012-01-20 06:47:42 +0000
3176+++ plugins/unityshell/src/unityshell.h 2012-01-25 11:34:37 +0000
3177@@ -56,6 +56,8 @@
3178 #include <compiztoolbox/compiztoolbox.h>
3179 #include <dlfcn.h>
3180
3181+#include "HudController.h"
3182+
3183 namespace unity
3184 {
3185
3186@@ -192,6 +194,9 @@
3187 bool altTabNextWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3188 bool altTabPrevWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3189
3190+ /* handle hud key activations */
3191+ bool ShowHudInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3192+ bool ShowHudTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3193 bool launcherSwitcherForwardInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3194 bool launcherSwitcherPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3195 bool launcherSwitcherTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3196@@ -260,6 +265,7 @@
3197 dash::Controller::Ptr dash_controller_;
3198 panel::Controller::Ptr panel_controller_;
3199 switcher::Controller::Ptr switcher_controller_;
3200+ hud::Controller::Ptr hud_controller_;
3201
3202 shortcut::Controller::Ptr shortcut_controller_;
3203 std::list<shortcut::AbstractHint*> hints_;
3204@@ -313,6 +319,7 @@
3205 CompWindowList fullscreen_windows_;
3206 bool painting_tray_;
3207 unsigned int tray_paint_mask_;
3208+ gint64 last_hud_show_time_;
3209
3210 ScreenEffectFramebufferObject::GLXGetProcAddressProc glXGetProcAddressP;
3211
3212@@ -381,7 +388,7 @@
3213 UnityMinimizedHandler *mMinimizeHandler;
3214
3215 UnityShowdesktopHandler *mShowdesktopHandler;
3216-
3217+
3218 private:
3219
3220 guint focusdesktop_handle_;
3221
3222=== modified file 'plugins/unityshell/unityshell.xml.in'
3223--- plugins/unityshell/unityshell.xml.in 2012-01-19 16:21:14 +0000
3224+++ plugins/unityshell/unityshell.xml.in 2012-01-25 11:34:37 +0000
3225@@ -40,8 +40,13 @@
3226 </requirement>
3227 </deps>
3228 <options>
3229- <group>
3230+ <group>
3231 <_short>Behaviour</_short>
3232+ <option name="show_hud" type="key">
3233+ <_short>Key to show the HUD</_short>
3234+ <_long>Make the HUD appear with this key</_long>
3235+ <default>&lt;Alt&gt;</default>
3236+ </option>
3237 <option name="launcher_reveal_edge" type="edge">
3238 <_short>Reveal Mode</_short>
3239 <_long>From which edge should the launcher reveal.</_long>
3240@@ -56,7 +61,7 @@
3241 <max>1000</max>
3242 <default>150</default>
3243 </option>
3244- <option name="launcher_hide_mode" type="int">
3245+ <option name="launcher_hide_mode" type="int">
3246 <_short>Hide Launcher</_short>
3247 <_long>Make the launcher hide automatically after some time of inactivity: always or just when the focussed window is not over the launcher</_long>
3248 <min>0</min>
3249@@ -78,16 +83,16 @@
3250 <value>3</value>
3251 <_name>Dodge Active Window</_name>
3252 </desc>
3253- </option>
3254- <option name="show_launcher" type="key">
3255+ </option>
3256+ <option name="show_launcher" type="key">
3257 <_short>Key to show the launcher</_short>
3258 <_long>Make the launcher appear with that key</_long>
3259 <default>&lt;Super&gt;</default>
3260 </option>
3261 <option name="keyboard_focus" type="key">
3262- <_short>Key to put keyboard-focus on launcher</_short>
3263- <_long>Set the keyboard-focus on the launcher so it can be navigated with the cursor-keys</_long>
3264- <default>&lt;Alt&gt;F1</default>
3265+ <_short>Key to put keyboard-focus on launcher</_short>
3266+ <_long>Set the keyboard-focus on the launcher so it can be navigated with the cursor-keys</_long>
3267+ <default>&lt;Alt&gt;F1</default>
3268 </option>
3269 <option name="execute_command" type="key">
3270 <_short>Key to execute a command</_short>
3271@@ -132,37 +137,37 @@
3272 <_long>fixme</_long>
3273 <default>&lt;Alt&gt;&lt;Shift&gt;Tab</default>
3274 </option>
3275- <option name="alt_tab_right" type="key">
3276- <_short>Go right in the switcher</_short>
3277- <_long>fixme</_long>
3278- <default>&lt;Alt&gt;Right</default>
3279- <passive_grab>false</passive_grab>
3280- <internal/>
3281- </option>
3282- <option name="alt_tab_left" type="key">
3283- <_short>Go left in the switcher</_short>
3284- <_long>fixme</_long>
3285- <default>&lt;Alt&gt;Left</default>
3286- <passive_grab>false</passive_grab>
3287- <internal/>
3288- </option>
3289+ <option name="alt_tab_right" type="key">
3290+ <_short>Go right in the switcher</_short>
3291+ <_long>fixme</_long>
3292+ <default>&lt;Alt&gt;Right</default>
3293+ <passive_grab>false</passive_grab>
3294+ <internal/>
3295+ </option>
3296+ <option name="alt_tab_left" type="key">
3297+ <_short>Go left in the switcher</_short>
3298+ <_long>fixme</_long>
3299+ <default>&lt;Alt&gt;Left</default>
3300+ <passive_grab>false</passive_grab>
3301+ <internal/>
3302+ </option>
3303 <option name="alt_tab_detail_start" type="key">
3304- <_short>Key to expose the windows in the switcher</_short>
3305- <_long>fixme</_long>
3306- <default>&lt;Alt&gt;Down</default>
3307- <passive_grab>false</passive_grab>
3308- <internal/>
3309+ <_short>Key to expose the windows in the switcher</_short>
3310+ <_long>fixme</_long>
3311+ <default>&lt;Alt&gt;Down</default>
3312+ <passive_grab>false</passive_grab>
3313+ <internal/>
3314 </option>
3315- <option name="alt_tab_detail_stop" type="key">
3316- <_short>Key to collapse windows in the switcher</_short>
3317- <_long>fixme</_long>
3318- <default>&lt;Alt&gt;Up</default>
3319- <passive_grab>false</passive_grab>
3320- <internal/>
3321- </option>
3322+ <option name="alt_tab_detail_stop" type="key">
3323+ <_short>Key to collapse windows in the switcher</_short>
3324+ <_long>fixme</_long>
3325+ <default>&lt;Alt&gt;Up</default>
3326+ <passive_grab>false</passive_grab>
3327+ <internal/>
3328+ </option>
3329 <option name="alt_tab_next_window" type="key">
3330- <_short>Key to flip through windows in the switcher</_short>
3331- <_long>fixme</_long>
3332+ <_short>Key to flip through windows in the switcher</_short>
3333+ <_long>fixme</_long>
3334 <passive_grab>false</passive_grab>
3335 </option>
3336 <option name="alt_tab_prev_window" type="key">
3337@@ -170,11 +175,11 @@
3338 <_long>fixme</_long>
3339 <passive_grab>false</passive_grab>
3340 </option>
3341- <option name="show_minimized_windows" type="bool">
3342- <_short>Show minimized windows in switcher</_short>
3343- <_long>Hack to enable minimized windows in switcher. Disable and report bugs if problems are caused</_long>
3344- <default>true</default>
3345- </option>
3346+ <option name="show_minimized_windows" type="bool">
3347+ <_short>Show minimized windows in switcher</_short>
3348+ <_long>Hack to enable minimized windows in switcher. Disable and report bugs if problems are caused</_long>
3349+ <default>true</default>
3350+ </option>
3351 </group>
3352 <group>
3353 <_short>Experimental</_short>
3354@@ -333,7 +338,7 @@
3355 <max>100</max>
3356 <default>75</default>
3357 </option>
3358-
3359+
3360 <option name="devices_option" type="int">
3361 <_short>Show Devices</_short>
3362 <_long>Show devices in the launcher</_long>
3363
3364=== modified file 'standalone-clients/CMakeLists.txt'
3365--- standalone-clients/CMakeLists.txt 2012-01-17 11:30:30 +0000
3366+++ standalone-clients/CMakeLists.txt 2012-01-25 11:34:37 +0000
3367@@ -86,6 +86,10 @@
3368 ${UNITY_SRC}/PlacesSimpleTile.h
3369 ${UNITY_SRC}/PlacesVScrollBar.cpp
3370 ${UNITY_SRC}/PlacesVScrollBar.h
3371+ ${UNITY_SRC}/DashView.cpp
3372+ ${UNITY_SRC}/DashView.h
3373+ ${UNITY_SRC}/DashViewPrivate.cpp
3374+ ${UNITY_SRC}/DashViewPrivate.h
3375 ${UNITY_SRC}/HomeView.cpp
3376 ${UNITY_SRC}/HomeView.h
3377 ${UNITY_SRC}/DashStyle.cpp
3378@@ -460,6 +464,35 @@
3379 )
3380 add_dependencies (bg-hash unity-core-${UNITY_API_VERSION})
3381
3382+add_executable (hud
3383+ StandaloneHud.cpp
3384+ ${UNITY_SRC}/BackgroundEffectHelper.cpp
3385+ ${UNITY_SRC}/BackgroundEffectHelper.h
3386+ ${UNITY_SRC}/DashSettings.cpp
3387+ ${UNITY_SRC}/DashSettings.h
3388+ ${UNITY_SRC}/DashStyle.cpp
3389+ ${UNITY_SRC}/DashSearchBarSpinner.cpp
3390+ ${UNITY_SRC}/HudSearchBar.cpp
3391+ ${UNITY_SRC}/HudButton.cpp
3392+ ${UNITY_SRC}/HudIcon.cpp
3393+ ${UNITY_SRC}/HudIcon.h
3394+ ${UNITY_SRC}/HudView.cpp
3395+ ${UNITY_SRC}/IMTextEntry.cpp
3396+ ${UNITY_SRC}/Introspectable.cpp
3397+ ${UNITY_SRC}/IconTexture.cpp
3398+ ${UNITY_SRC}/IconLoader.cpp
3399+ ${UNITY_SRC}/JSONParser.cpp
3400+ ${UNITY_SRC}/OverlayRenderer.cpp
3401+ ${UNITY_SRC}/StaticCairoText.cpp
3402+ ${UNITY_SRC}/TextureCache.cpp
3403+ ${UNITY_SRC}/Timer.cpp
3404+ ${UNITY_SRC}/UBusWrapper.cpp
3405+ ${UNITY_SRC}/ubus-server.cpp
3406+ ${UNITY_SRC}/UScreen.cpp
3407+ ${UNITY_SRC}/UScreen.h
3408+ )
3409+add_dependencies (hud unity-core-${UNITY_API_VERSION})
3410+
3411 add_executable (test-shortcut
3412 TestShortcut.cpp
3413 ${UNITY_SRC}/AbstractSeparator.cpp
3414
3415=== added file 'standalone-clients/StandaloneHud.cpp'
3416--- standalone-clients/StandaloneHud.cpp 1970-01-01 00:00:00 +0000
3417+++ standalone-clients/StandaloneHud.cpp 2012-01-25 11:34:37 +0000
3418@@ -0,0 +1,170 @@
3419+/*
3420+ * Copyright 2010 Canonical Ltd.
3421+ *
3422+ * This program is free software: you can redistribute it and/or modify it
3423+ * under the terms of the GNU General Public License version 3, as published
3424+ * by the Free Software Foundation.
3425+ *
3426+ * This program is distributed in the hope that it will be useful, but
3427+ * WITHOUT ANY WARRANTY; without even the implied warranties of
3428+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
3429+ * PURPOSE. See the GNU General Public License for more details.
3430+ *
3431+ * You should have received a copy of the GNU General Public License
3432+ * version 3 along with this program. If not, see
3433+ * <http://www.gnu.org/licenses/>
3434+ *
3435+ * Authored by: Gordon Allott <gord.allott@canonical.com>
3436+ *
3437+ */
3438+
3439+#include <sstream>
3440+#include "Nux/Nux.h"
3441+#include "Nux/VLayout.h"
3442+#include "Nux/Button.h"
3443+#include "Nux/TextureArea.h"
3444+#include "Nux/WindowThread.h"
3445+#include "NuxGraphics/GraphicsEngine.h"
3446+#include <gtk/gtk.h>
3447+
3448+#include "HudView.h"
3449+#include "DashStyle.h"
3450+#include "DashSettings.h"
3451+#include <NuxCore/Logger.h>
3452+
3453+namespace
3454+{
3455+ nux::logging::Logger logger("unity.tests.Hud");
3456+}
3457+
3458+class TestRunner
3459+{
3460+public:
3461+ TestRunner ();
3462+ ~TestRunner ();
3463+
3464+ static void InitWindowThread (nux::NThread* thread, void* InitData);
3465+ void Init ();
3466+ nux::Layout *layout;
3467+ unity::hud::View* hud_view_;
3468+ unity::dash::Settings dash_settings_;
3469+
3470+private:
3471+ unity::hud::Hud hud_service_;
3472+};
3473+
3474+TestRunner::TestRunner ()
3475+ : hud_service_("com.canonical.hud", "/com/canonical/hud")
3476+{
3477+}
3478+
3479+TestRunner::~TestRunner ()
3480+{
3481+}
3482+
3483+void TestRunner::Init ()
3484+{
3485+ LOG_WARNING(logger) << "test init";
3486+ layout = new nux::VLayout();
3487+
3488+ hud_view_ = new unity::hud::View();
3489+
3490+ layout->AddView (hud_view_, 1, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_FULL);
3491+ nux::GetWindowCompositor().SetKeyFocusArea(hud_view_->default_focus());
3492+
3493+ nux::GetWindowThread()->SetLayout (layout);
3494+
3495+ // things the controller normally does
3496+ hud_service_.queries_updated.connect([&] (unity::hud::Hud::Queries queries) {
3497+ hud_view_->SetQueries(queries);
3498+ std::string icon_name = "";
3499+ for (auto query = queries.begin(); query != queries.end(); query++)
3500+ {
3501+ if (!(*query)->icon_name.empty())
3502+ {
3503+ icon_name = (*query)->icon_name;
3504+ break;
3505+ }
3506+ }
3507+
3508+ hud_view_->SetIcon(icon_name);
3509+
3510+ });
3511+
3512+ hud_view_->query_activated.connect([&] (unity::hud::Query::Ptr query) {
3513+ hud_service_.ExecuteQuery(query, 0);
3514+ });
3515+
3516+ hud_view_->query_selected.connect([&] (unity::hud::Query::Ptr query) {
3517+ hud_view_->SetIcon(query->icon_name);
3518+ });
3519+
3520+ hud_view_->search_changed.connect([&] (std::string search_string) {
3521+ hud_service_.RequestQuery(search_string);
3522+ });
3523+
3524+ hud_view_->search_activated.connect([&] (std::string search_string) {
3525+ hud_service_.ExecuteQueryBySearch(search_string, 0);
3526+ });
3527+
3528+ hud_service_.RequestQuery("");
3529+
3530+ hud_view_->SetWindowGeometry(layout->GetAbsoluteGeometry(), layout->GetGeometry());
3531+
3532+}
3533+
3534+void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData)
3535+{
3536+ TestRunner *self = (TestRunner *) InitData;
3537+ self->Init ();
3538+}
3539+
3540+void
3541+ControlThread (nux::NThread* thread,
3542+ void* data)
3543+{
3544+ // sleep for 3 seconds
3545+ nux::SleepForMilliseconds (3000);
3546+ printf ("ControlThread successfully started\n");
3547+}
3548+
3549+
3550+int main(int argc, char **argv)
3551+{
3552+ nux::SystemThread* st = NULL;
3553+ nux::WindowThread* wt = NULL;
3554+
3555+ // no real tests right now, just make sure we don't get any criticals and such
3556+ // waiting on nice perceptual diff support before we can build real tests
3557+ // for views
3558+
3559+ g_type_init ();
3560+ gtk_init (&argc, &argv);
3561+
3562+ nux::NuxInitialize(0);
3563+
3564+ // Slightly higher as we're more likely to test things we know will fail
3565+ nux::logging::configure_logging("unity.hud=debug");
3566+
3567+ nux::logging::configure_logging(::getenv("UNITY_LOG_SEVERITY"));
3568+ LOG_DEBUG(logger) << "starting the standalone hud";
3569+ // The instances for the pseudo-singletons.
3570+ unity::dash::Style dash_style;
3571+
3572+ TestRunner *test_runner = new TestRunner ();
3573+ wt = nux::CreateGUIThread(TEXT("Hud Prototype Test"),
3574+ 1024, 768,
3575+ 0,
3576+ &TestRunner::InitWindowThread,
3577+ test_runner);
3578+
3579+ st = nux::CreateSystemThread (NULL, ControlThread, wt);
3580+
3581+ if (st)
3582+ st->Start (NULL);
3583+
3584+ wt->Run (NULL);
3585+ delete st;
3586+ delete wt;
3587+ return 0;
3588+}
3589
3590=== modified file 'tests/CMakeLists.txt'
3591--- tests/CMakeLists.txt 2012-01-23 13:07:40 +0000
3592+++ tests/CMakeLists.txt 2012-01-25 11:34:37 +0000
3593@@ -99,6 +99,8 @@
3594
3595 # The service that provides DBus services to test against
3596 add_executable(test-gtest-service
3597+ test_service_hud.c
3598+ test_service_hud.h
3599 test_service_lens.c
3600 test_service_lens.h
3601 test_service_main.c
3602@@ -164,17 +166,18 @@
3603
3604 # tests that require dbus, must not require X
3605 add_executable(test-gtest-dbus
3606- test_categories.cpp
3607- test_filesystem_lenses.cpp
3608- test_filter.cpp
3609- test_indicator_entry.cpp
3610- test_lens.cpp
3611+# test_categories.cpp
3612+# test_filesystem_lenses.cpp
3613+# test_filter.cpp
3614+# test_indicator_entry.cpp
3615+# test_lens.cpp
3616 test_main_dbus.cpp
3617- test_model.cpp
3618- test_utils.h
3619- test_ratings_filter.cpp
3620- test_results.cpp
3621- )
3622+# test_model.cpp
3623+# test_utils.h
3624+# test_ratings_filter.cpp
3625+# test_results.cpp
3626+ test_hud.cpp
3627+ )
3628 target_link_libraries(test-gtest-dbus ${GTEST_BOTH_LIBRARIES})
3629 add_test(UnityGTestDBus test-gtest-dbus)
3630 add_dependencies(test-gtest-dbus unity-core-${UNITY_API_VERSION} test-gtest-service)
3631
3632=== added file 'tests/test_hud.cpp'
3633--- tests/test_hud.cpp 1970-01-01 00:00:00 +0000
3634+++ tests/test_hud.cpp 2012-01-25 11:34:37 +0000
3635@@ -0,0 +1,104 @@
3636+#include <gtest/gtest.h>
3637+#include <glib-object.h>
3638+#include <UnityCore/GLibWrapper.h>
3639+#include <UnityCore/Hud.h>
3640+
3641+using namespace std;
3642+
3643+namespace
3644+{
3645+
3646+GMainLoop* loop_ = NULL;
3647+unity::hud::Hud *hud;
3648+
3649+class TestHud : public ::testing::Test
3650+{
3651+public:
3652+ TestHud()
3653+ : query_return_result(false)
3654+ , connected_result(false)
3655+ {
3656+ }
3657+ unity::hud::Hud::Queries queries;
3658+ bool query_return_result;
3659+ bool connected_result;
3660+};
3661+
3662+TEST_F(TestHud, TestConstruction)
3663+{
3664+ loop_ = g_main_loop_new(NULL, FALSE);
3665+ hud = new unity::hud::Hud("com.canonical.Unity.Test", "/com/canonical/hud");
3666+
3667+ // performs a check on the hud, if the hud is connected, report a sucess
3668+ auto timeout_check = [] (gpointer data) -> gboolean
3669+ {
3670+ TestHud* self = static_cast<TestHud*>(data);
3671+ if (hud->connected)
3672+ {
3673+ self->connected_result = true;
3674+ g_main_loop_quit(loop_);
3675+ return FALSE;
3676+ }
3677+ else
3678+ {
3679+ self->connected_result = false;
3680+ return TRUE;
3681+ }
3682+ };
3683+
3684+
3685+ // if the hud is not connected when this lambda runs, fail.
3686+ auto timeout_bailout = [] (gpointer data) -> gboolean
3687+ {
3688+ TestHud* self = static_cast<TestHud*>(data);
3689+ // reached timeout, failed testing
3690+ self->connected_result = false;
3691+ g_main_loop_quit(loop_);
3692+ return FALSE;
3693+ };
3694+
3695+ g_timeout_add_seconds(1, timeout_check, this);
3696+ g_timeout_add_seconds(10, timeout_bailout, this);
3697+
3698+ g_main_loop_run(loop_);
3699+
3700+ EXPECT_EQ(connected_result, true);
3701+}
3702+
3703+TEST_F(TestHud, TestQueryReturn)
3704+{
3705+ query_return_result = false;
3706+
3707+ // make sure we receive the queries
3708+ auto query_connection = [this](unity::hud::Hud::Queries queries_)
3709+ {
3710+ query_return_result = true;
3711+ g_main_loop_quit(loop_);
3712+ queries = queries_;
3713+ };
3714+
3715+ auto timeout_bailout = [] (gpointer data) -> gboolean
3716+ {
3717+ TestHud* self = static_cast<TestHud*>(data);
3718+ self->query_return_result = false;
3719+ g_main_loop_quit(loop_);
3720+ return FALSE;
3721+ };
3722+
3723+ hud->queries_updated.connect(query_connection);
3724+
3725+ guint source_id = g_timeout_add_seconds(10, timeout_bailout, this);
3726+
3727+ // next check we get 30 entries from this specific known callback
3728+ hud->RequestQuery("Request30Queries");
3729+ g_main_loop_run(loop_);
3730+ EXPECT_EQ(query_return_result, true);
3731+ EXPECT_NE(queries.size(), 0);
3732+ g_source_remove(source_id);
3733+
3734+ // finally close the connection - Nothing to check for here
3735+ hud->CloseQuery();
3736+}
3737+
3738+
3739+}
3740
3741=== added file 'tests/test_service_hud.c'
3742--- tests/test_service_hud.c 1970-01-01 00:00:00 +0000
3743+++ tests/test_service_hud.c 2012-01-25 11:34:37 +0000
3744@@ -0,0 +1,268 @@
3745+#include "test_service_hud.h"
3746+#include <unity.h>
3747+#include <gio/gio.h>
3748+
3749+const char * hud_interface =
3750+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
3751+"<node name=\"/\">\n"
3752+" <interface name=\"com.canonical.hud\">\n"
3753+"<!-- Properties -->\n"
3754+" <!-- None -->\n"
3755+"\n"
3756+"<!-- Functions -->\n"
3757+" <method name=\"StartQuery\">\n"
3758+" <!-- in -->\n"
3759+" <arg type=\"s\" name=\"query\" direction=\"in\" />\n"
3760+" <arg type=\"i\" name=\"entries\" direction=\"in\" />\n"
3761+" <!-- out -->\n"
3762+" <arg type=\"s\" name=\"target\" direction=\"out\" />\n"
3763+" <arg type=\"a(sssssv)\" name=\"suggestions\" direction=\"out\" />\n"
3764+" <arg type=\"v\" name=\"querykey\" direction=\"out\" />\n"
3765+" </method>\n"
3766+"\n"
3767+" <method name=\"ExecuteQuery\">\n"
3768+" <arg type=\"v\" name=\"key\" direction=\"in\" />\n"
3769+" <arg type=\"u\" name=\"timestamp\" direction=\"in\" />\n"
3770+" </method>\n"
3771+"\n"
3772+" <method name=\"CloseQuery\">\n"
3773+" <arg type=\"v\" name=\"querykey\" direction=\"in\" />\n"
3774+" </method>\n"
3775+"\n"
3776+"<!-- Signals -->\n"
3777+" <signal name=\"UpdatedQuery\">\n"
3778+" <arg type=\"s\" name=\"target\" direction=\"out\" />\n"
3779+" <arg type=\"a(sssssv)\" name=\"suggestions\" direction=\"out\" />\n"
3780+" <arg type=\"v\" name=\"querykey\" direction=\"out\" />\n"
3781+" </signal>\n"
3782+"\n"
3783+"<!-- End of interesting stuff -->\n"
3784+"\n"
3785+" </interface>\n"
3786+"</node>\n"
3787+;
3788+static void bus_got_cb (GObject *object, GAsyncResult * res, gpointer user_data);
3789+static void bus_method (GDBusConnection *connection,
3790+ const gchar *sender,
3791+ const gchar *object_path,
3792+ const gchar *interface_name,
3793+ const gchar *method_name,
3794+ GVariant *parameters,
3795+ GDBusMethodInvocation *invocation,
3796+ gpointer user_data);
3797+
3798+G_DEFINE_TYPE(ServiceHud, service_hud, G_TYPE_OBJECT);
3799+static GDBusNodeInfo * node_info = NULL;
3800+static GDBusInterfaceInfo * iface_info = NULL;
3801+static GDBusInterfaceVTable bus_vtable = {
3802+ method_call: bus_method,
3803+ get_property: NULL,
3804+ set_property: NULL,
3805+};
3806+
3807+
3808+struct _ServiceHudPrivate
3809+{
3810+ GDBusConnection * bus;
3811+ GCancellable * bus_lookup;
3812+ guint bus_registration;
3813+};
3814+
3815+static void
3816+service_hud_dispose(GObject* object)
3817+{
3818+ ServiceHud* self = SERVICE_HUD(object);
3819+ if (self->priv->bus_lookup != NULL) {
3820+ g_cancellable_cancel(self->priv->bus_lookup);
3821+ g_object_unref(self->priv->bus_lookup);
3822+ self->priv->bus_lookup = NULL;
3823+ }
3824+
3825+ if (self->priv->bus_registration != 0) {
3826+ g_dbus_connection_unregister_object(self->priv->bus, self->priv->bus_registration);
3827+ self->priv->bus_registration = 0;
3828+ }
3829+
3830+ if (self->priv->bus != NULL) {
3831+ g_object_unref(self->priv->bus);
3832+ self->priv->bus = NULL;
3833+ }
3834+
3835+}
3836+
3837+static void
3838+service_hud_class_init(ServiceHudClass* klass)
3839+{
3840+ G_OBJECT_CLASS(klass)->dispose = service_hud_dispose;
3841+ g_type_class_add_private (klass, sizeof (ServiceHudPrivate));
3842+
3843+ if (node_info == NULL)
3844+ {
3845+ GError * error = NULL;
3846+
3847+ node_info = g_dbus_node_info_new_for_xml(hud_interface, &error);
3848+ if (error != NULL)
3849+ {
3850+ g_error("Unable to parse HUD interface: %s", error->message);
3851+ g_error_free(error);
3852+ }
3853+ }
3854+
3855+ if (node_info != NULL && iface_info == NULL)
3856+ {
3857+ iface_info = g_dbus_node_info_lookup_interface(node_info,"com.canonical.hud");
3858+ if (iface_info == NULL)
3859+ {
3860+ g_error("Unable to find interface 'com.canonical.hud'");
3861+ }
3862+ }
3863+
3864+}
3865+
3866+static void
3867+service_hud_init(ServiceHud* self)
3868+{
3869+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, SERVICE_TYPE_HUD, ServiceHudPrivate);
3870+ self->priv->bus = NULL;
3871+ self->priv->bus_lookup = NULL;
3872+ self->priv->bus_registration = 0;
3873+
3874+ self->priv->bus_lookup = g_cancellable_new();
3875+ g_bus_get(G_BUS_TYPE_SESSION, self->priv->bus_lookup, bus_got_cb, self);
3876+
3877+}
3878+
3879+ServiceHud*
3880+service_hud_new()
3881+{
3882+ return g_object_new(SERVICE_TYPE_HUD, NULL);
3883+}
3884+
3885+static void
3886+bus_got_cb (GObject *object, GAsyncResult * res, gpointer user_data)
3887+{
3888+ GError * error = NULL;
3889+ ServiceHud * self = SERVICE_HUD(user_data);
3890+ GDBusConnection * bus;
3891+
3892+ bus = g_bus_get_finish(res, &error);
3893+ if (error != NULL) {
3894+ g_critical("Unable to get bus: %s", error->message);
3895+ g_error_free(error);
3896+ return;
3897+ }
3898+
3899+ self->priv->bus = bus;
3900+
3901+ /* Register object */
3902+ self->priv->bus_registration = g_dbus_connection_register_object(bus,
3903+ /* path */ "/com/canonical/hud",
3904+ /* interface */ iface_info,
3905+ /* vtable */ &bus_vtable,
3906+ /* userdata */ self,
3907+ /* destroy */ NULL,
3908+ /* error */ &error);
3909+
3910+ if (error != NULL) {
3911+ g_critical ("Unable to create bus connection object, %s", error->message);
3912+ g_error_free(error);
3913+ return;
3914+ }
3915+
3916+ return;
3917+}
3918+
3919+static void
3920+bus_method (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data)
3921+{
3922+ if (g_strcmp0(method_name, "StartQuery") == 0)
3923+ {
3924+ GVariant * ret = NULL;
3925+ gchar * query = NULL;
3926+ int num_entries = 0;
3927+
3928+ g_variant_get(parameters, "(si)", &query, &num_entries);
3929+
3930+ /* Build into into a variant */
3931+ GVariantBuilder ret_builder;
3932+ g_variant_builder_init(&ret_builder, G_VARIANT_TYPE_TUPLE);
3933+ g_variant_builder_add_value(&ret_builder, g_variant_new_string("target"));
3934+ GVariantBuilder builder;
3935+
3936+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
3937+
3938+ int i = 0;
3939+ for (i = 0; i < num_entries; i++)
3940+ {
3941+ gchar* target = g_strdup_printf("test-%i", i);
3942+ gchar* icon = g_strdup_printf("icon-%i", i);
3943+ gchar* future_icon = g_strdup(icon);
3944+ gchar* completion_text = g_strdup_printf("completion-%i", i);
3945+ gchar* accelerator = g_strdup_printf("<alt>+whatever");
3946+
3947+ GVariantBuilder tuple;
3948+ g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE);
3949+ g_variant_builder_add_value(&tuple, g_variant_new_string(target));
3950+ g_variant_builder_add_value(&tuple, g_variant_new_string(icon));
3951+ g_variant_builder_add_value(&tuple, g_variant_new_string(future_icon));
3952+ g_variant_builder_add_value(&tuple, g_variant_new_string(completion_text));
3953+ g_variant_builder_add_value(&tuple, g_variant_new_string(accelerator));
3954+ // build a fake key
3955+ GVariant* key;
3956+ {
3957+ GVariantBuilder keybuilder;
3958+ g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE);
3959+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
3960+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
3961+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
3962+ g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986));
3963+
3964+ key = g_variant_new_variant(g_variant_builder_end(&keybuilder));
3965+ }
3966+ g_variant_ref_sink(key);
3967+ g_variant_builder_add_value(&tuple, key);
3968+ g_variant_builder_add_value(&builder, g_variant_builder_end(&tuple));
3969+ g_free(target);
3970+ g_free(icon);
3971+ g_free(future_icon);
3972+ g_free(completion_text);
3973+ }
3974+ g_variant_builder_add_value(&ret_builder, g_variant_builder_end(&builder));
3975+
3976+ GVariant* query_key;
3977+ {
3978+ GVariantBuilder keybuilder;
3979+ g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE);
3980+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
3981+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
3982+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
3983+ g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986));
3984+
3985+ query_key = g_variant_new_variant(g_variant_builder_end(&keybuilder));
3986+ }
3987+ g_variant_ref_sink(query_key);
3988+ g_variant_builder_add_value(&ret_builder, query_key);
3989+
3990+ ret = g_variant_builder_end(&ret_builder);
3991+
3992+ g_dbus_method_invocation_return_value(invocation, ret);
3993+ g_free(query);
3994+ }
3995+ else if (g_strcmp0(method_name, "ExecuteQuery") == 0)
3996+ {
3997+ GVariant * key = NULL;
3998+ key = g_variant_get_child_value(parameters, 0);
3999+ g_dbus_method_invocation_return_value(invocation, NULL);
4000+ g_variant_unref(key);
4001+ }
4002+ else if (g_strcmp0(method_name, "CloseQuery") == 0)
4003+ {
4004+ GVariant * key = NULL;
4005+ key = g_variant_get_child_value(parameters, 0);
4006+ g_dbus_method_invocation_return_value(invocation, NULL);
4007+ g_variant_unref(key);
4008+ }
4009+
4010+ return;
4011+}
4012+
4013
4014=== added file 'tests/test_service_hud.h'
4015--- tests/test_service_hud.h 1970-01-01 00:00:00 +0000
4016+++ tests/test_service_hud.h 2012-01-25 11:34:37 +0000
4017@@ -0,0 +1,46 @@
4018+#ifndef _SERVICE_HUD_H_
4019+#define _SERVICE_HUD_H_
4020+
4021+#include <glib-object.h>
4022+G_BEGIN_DECLS
4023+
4024+#define SERVICE_TYPE_HUD (service_hud_get_type ())
4025+
4026+#define SERVICE_HUD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
4027+ SERVICE_TYPE_HUD, ServiceHud))
4028+
4029+#define SERVICE_HUD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
4030+ SERVICE_TYPE_HUD, ServiceHudClass))
4031+
4032+#define SERVICE_IS_HUD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
4033+ SERVICE_TYPE_HUD))
4034+
4035+#define SERVICE_IS_HUD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
4036+ SERVICE_TYPE_HUD))
4037+
4038+#define ServiceHud_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
4039+ SERVICE_TYPE_HUD, ServiceHudClass))
4040+
4041+typedef struct _ServiceHud ServiceHud;
4042+typedef struct _ServiceHudClass ServiceHudClass;
4043+typedef struct _ServiceHudPrivate ServiceHudPrivate;
4044+
4045+struct _ServiceHud
4046+{
4047+ GObject parent;
4048+
4049+ ServiceHudPrivate *priv;
4050+};
4051+
4052+struct _ServiceHudClass
4053+{
4054+ GObjectClass parent_class;
4055+};
4056+
4057+GType service_hud_get_type(void) G_GNUC_CONST;
4058+
4059+ServiceHud* service_hud_new(void);
4060+
4061+G_END_DECLS
4062+
4063+#endif /* _SERVICE_HUD_H_ */
4064
4065=== modified file 'tests/test_service_main.c'
4066--- tests/test_service_main.c 2011-07-26 09:08:42 +0000
4067+++ tests/test_service_main.c 2012-01-25 11:34:37 +0000
4068@@ -2,6 +2,7 @@
4069
4070 #include "test_service_lens.h"
4071 #include "test_service_model.h"
4072+#include "test_service_hud.h"
4073
4074 static void on_bus_aquired(GDBusConnection* conn, const gchar* name, gpointer null);
4075 static void handle_method_call(GDBusConnection *connection,
4076@@ -32,8 +33,9 @@
4077 };
4078
4079 static GMainLoop* loop_ = NULL;
4080-static ServiceLens* lens_ = NULL;
4081-static ServiceModel* model_ = NULL;
4082+//static ServiceLens* lens_ = NULL;
4083+//static ServiceModel* model_ = NULL;
4084+static ServiceHud* hud_ = NULL;
4085
4086 gint
4087 main(gint argc, gchar** argv)
4088@@ -42,8 +44,9 @@
4089
4090 loop_ = g_main_loop_new(NULL, FALSE);
4091
4092- lens_ = service_lens_new();
4093- model_ = service_model_new();
4094+ //lens_ = service_lens_new();
4095+ //model_ = service_model_new();
4096+ hud_ = service_hud_new();
4097
4098 g_bus_own_name(G_BUS_TYPE_SESSION,
4099 "com.canonical.Unity.Test",
4100@@ -57,8 +60,9 @@
4101 g_main_loop_run(loop_);
4102 g_main_loop_unref(loop_);
4103
4104- g_object_unref(lens_);
4105- g_object_unref(model_);
4106+ //g_object_unref(lens_);
4107+ //g_object_unref(model_);
4108+ g_object_unref(hud_);
4109 g_dbus_node_info_unref(introspection_data);
4110
4111 return 0;