Merge lp:~fboucault/unity-2d/blur_without_compositor into lp:unity-2d/3.0

Proposed by Florian Boucault
Status: Rejected
Rejected by: Florian Boucault
Proposed branch: lp:~fboucault/unity-2d/blur_without_compositor
Merge into: lp:unity-2d/3.0
Diff against target: 7541 lines (+2379/-2507)
176 files modified
CMakeLists.txt (+6/-3)
data/unity-2d.convert (+0/-2)
debian/20_ubuntu-2d-gconf-default (+0/-8)
debian/20_ubuntu-2d-gconf-mandatory (+0/-1)
debian/changelog (+78/-17)
debian/control (+13/-10)
debian/gconf/ubuntu-2d.default.path (+2/-2)
debian/gconf/ubuntu-2d.mandatory.path (+2/-2)
debian/unity-2d-panel.install (+0/-2)
debian/unity-2d.gconf-defaults (+4/-0)
debian/unity-2d.install (+2/-4)
debian/unity-2d.postinst (+12/-15)
debian/unity-2d.postrm (+11/-14)
debian/unity-2d.preinst (+16/-0)
launcher/Launcher.qml (+11/-0)
launcher/LauncherItem.qml (+2/-0)
launcher/LauncherList.qml (+11/-0)
launcher/app/launcher.cpp (+2/-0)
libunity-2d-private/CMakeLists.txt (+1/-1)
libunity-2d-private/Unity2d/GnomeBackground.qml (+12/-22)
libunity-2d-private/Unity2d/plugin.cpp (+0/-4)
libunity-2d-private/src/CMakeLists.txt (+6/-0)
libunity-2d-private/src/debug.cpp (+23/-0)
libunity-2d-private/src/debug_p.h (+6/-0)
libunity-2d-private/src/gimageutils.cpp (+102/-0)
libunity-2d-private/src/gimageutils.h (+46/-0)
libunity-2d-private/src/iconimageprovider.cpp (+4/-56)
libunity-2d-private/src/launcherapplication.cpp (+4/-6)
libunity-2d-private/src/launcherapplicationslist.cpp (+20/-2)
libunity-2d-private/src/launcherapplicationslist.h (+2/-1)
libunity-2d-private/src/launcherdevice.cpp (+73/-21)
libunity-2d-private/src/launcherdevice.h (+4/-0)
libunity-2d-private/src/launchermenu.cpp (+1/-0)
libunity-2d-private/src/screeninfo.cpp (+1/-3)
libunity-2d-private/src/unity-2d-private.pc.cmake (+1/-1)
libunity-2d-private/src/unity2dapplication.cpp (+83/-1)
libunity-2d-private/src/unity2dapplication.h (+3/-0)
libunity-2d-private/src/windowinfo.cpp (+1/-3)
libunity-2d-private/src/workspacesinfo.cpp (+1/-3)
panel/CMakeLists.txt (+3/-5)
panel/app/CMakeLists.txt (+3/-1)
panel/app/main.cpp (+5/-2)
panel/app/panelmanager.cpp (+34/-46)
panel/app/panelmanager.h (+2/-0)
panel/app/unity2dstyle.cpp (+0/-98)
panel/app/unity2dstyle.h (+0/-44)
panel/applets/CMakeLists.txt (+15/-26)
panel/applets/appname/appnameapplet.cpp (+29/-75)
panel/applets/appname/appnameapplet.h (+3/-1)
panel/applets/appname/com.canonical.AppMenu.Registrar.xml (+0/-82)
panel/applets/appname/croppedlabel.cpp (+140/-0)
panel/applets/appname/croppedlabel.h (+45/-0)
panel/applets/appname/menubarwidget.cpp (+78/-279)
panel/applets/appname/menubarwidget.h (+25/-66)
panel/applets/appname/registrar.cpp (+0/-138)
panel/applets/appname/registrar.h (+0/-85)
panel/applets/common/cairoutils.cpp (+42/-0)
panel/applets/common/cairoutils.h (+47/-0)
panel/applets/common/indicatorentrywidget.cpp (+374/-0)
panel/applets/common/indicatorentrywidget.h (+90/-0)
panel/applets/common/indicatorsmanager.cpp (+206/-0)
panel/applets/common/indicatorsmanager.h (+72/-0)
panel/applets/common/indicatorwidget.cpp (+53/-0)
panel/applets/common/indicatorwidget.h (+52/-0)
panel/applets/common/panelstyle.cpp (+201/-0)
panel/applets/common/panelstyle.h (+72/-0)
panel/applets/homebutton/homebutton.cpp (+4/-2)
panel/applets/indicator-config.h.in (+0/-7)
panel/applets/indicator/abstractindicator.cpp (+0/-43)
panel/applets/indicator/abstractindicator.h (+0/-53)
panel/applets/indicator/datetimeindicator.cpp (+0/-94)
panel/applets/indicator/datetimeindicator.h (+0/-53)
panel/applets/indicator/indicator.c (+0/-525)
panel/applets/indicator/indicator.h (+0/-45)
panel/applets/indicator/indicatorapplet.cpp (+0/-114)
panel/applets/indicator/indicatorapplet.h (+0/-60)
panel/applets/indicator/indicatorservicemanager.cpp (+0/-120)
panel/applets/indicator/indicatorservicemanager.h (+0/-54)
places/AbstractButton.qml (+2/-0)
places/GroupHeader.qml (+2/-0)
places/Home.qml (+2/-0)
places/HomeButton.qml (+2/-0)
places/HomeShortcuts.qml (+4/-4)
places/SearchEntry.qml (+8/-0)
places/SearchRefine.qml (+2/-0)
places/SearchRefineOptionType.qml (+2/-0)
places/TickBox.qml (+3/-0)
places/UnityDefaultRenderer.qml (+2/-0)
places/UnityEmptySearchRenderer.qml (+2/-0)
places/UnityFileInfoRenderer.qml (+2/-0)
places/app/places.cpp (+2/-0)
places/artwork/desktop_dash_background_no_transparency.sci (+0/-7)
places/dash.qml (+11/-3)
po/af.po (+2/-2)
po/am.po (+2/-2)
po/an.po (+2/-2)
po/ar.po (+2/-2)
po/ast.po (+2/-2)
po/az.po (+2/-2)
po/be.po (+2/-2)
po/bem.po (+2/-2)
po/bg.po (+2/-2)
po/bn.po (+2/-2)
po/bs.po (+3/-3)
po/ca.po (+2/-2)
po/ca@valencia.po (+3/-3)
po/crh.po (+2/-2)
po/cs.po (+2/-2)
po/cy.po (+2/-2)
po/da.po (+2/-2)
po/de.po (+2/-2)
po/el.po (+2/-2)
po/en_AU.po (+4/-4)
po/en_GB.po (+4/-4)
po/eo.po (+2/-2)
po/es.po (+2/-2)
po/et.po (+3/-3)
po/eu.po (+2/-2)
po/fa.po (+2/-2)
po/fi.po (+2/-2)
po/fil.po (+2/-2)
po/fr.po (+2/-2)
po/fy.po (+2/-2)
po/gd.po (+2/-2)
po/gl.po (+2/-2)
po/gv.po (+2/-2)
po/he.po (+2/-2)
po/hi.po (+2/-2)
po/hr.po (+2/-2)
po/hu.po (+2/-2)
po/hy.po (+2/-2)
po/id.po (+2/-2)
po/is.po (+2/-2)
po/it.po (+2/-2)
po/ja.po (+2/-2)
po/ka.po (+2/-2)
po/kk.po (+2/-2)
po/ko.po (+2/-2)
po/ku.po (+2/-2)
po/ky.po (+2/-2)
po/lb.po (+2/-2)
po/lt.po (+2/-2)
po/lv.po (+2/-2)
po/mg.po (+2/-2)
po/ml.po (+2/-2)
po/ms.po (+2/-2)
po/nb.po (+2/-2)
po/nl.po (+2/-2)
po/nn.po (+2/-2)
po/oc.po (+2/-2)
po/pa.po (+2/-2)
po/pl.po (+2/-2)
po/pt.po (+2/-2)
po/pt_BR.po (+2/-2)
po/ro.po (+2/-2)
po/ru.po (+2/-2)
po/si.po (+2/-2)
po/sk.po (+2/-2)
po/sl.po (+2/-2)
po/sq.po (+2/-2)
po/sr.po (+2/-2)
po/sv.po (+2/-2)
po/ta.po (+2/-2)
po/te.po (+2/-2)
po/th.po (+2/-2)
po/tr.po (+2/-2)
po/tt.po (+2/-2)
po/ug.po (+2/-2)
po/uk.po (+2/-2)
po/unity-2d.pot (+2/-2)
po/ur.po (+2/-2)
po/vi.po (+2/-2)
po/zh_CN.po (+2/-2)
po/zh_HK.po (+2/-2)
po/zh_TW.po (+2/-2)
spread/app/spread.cpp (+1/-0)
To merge this branch: bzr merge lp:~fboucault/unity-2d/blur_without_compositor
Reviewer Review Type Date Requested Status
Gerry Boland Pending
Review via email: mp+70934@code.launchpad.net

Description of the change

[dash] Use a blurred background even when no compositor is available.

To post a comment you must log in.

Unmerged revisions

641. By Florian Boucault

[dash] Use a blurred background even when no compositor is available.

640. By Florian Boucault

Merged from lp:unity-2d

639. By Didier Roche-Tolomelli

Enable storing subdir (like kde4/) in the gsettings schema.
For instance /usr/share/applications/kde4/konversation.desktop should be stored
as kde4-konversation.desktop.

This is valid for all .desktop file in XDG_DATA_DIR/applications.
Note that full path and relative path are still supported

638. By Felix H. Dahlke

[launcher] Added a "safely remove" option for USB sticks.

637. By Aurélien Gâteau

[panel] Use the window button pixmaps from the active window manager instead of using the hardcoded Ambiance theme.

It also provides a fallback in case the theme is not Ambiance or Radiance.

636. By Aurélien Gâteau

[panel] Add support for GIcon-based icons in indicators, using code from IconImageProvider

Brings back icons for power indicator.

635. By Felix H. Dahlke

[launcher] Changed quicklist item "Keep In Launcher" to "Keep in launcher" as well as "Remove From Launcher" to "Remove from launcher" per design

634. By Aurélien Gâteau

[panel] Fix build with Unity trunk -r1325

Indicators::on_menu_pointer_moved() signal has been removed. The code now
implements mouse polling to implement mouse scrubbing. This is more efficient
than waiting for unity-panel-service to ask for menus to show.

633. By Didier Roche-Tolomelli

releasing version 3.8.14.1-0ubuntu1

632. By Didier Roche-Tolomelli

* Few upstream fixes:
  - unity-2d-places crashed with SIGSEGV in
    QDeclarativePropertyPrivate::initProperty() (LP: #817896)
  - update resets unity launcher favorites (LP: #817954)

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-07-27 09:42:32 +0000
3+++ CMakeLists.txt 2011-08-09 17:30:25 +0000
4@@ -25,10 +25,13 @@
5 find_package(X11 REQUIRED)
6 find_package(Gettext REQUIRED)
7 pkg_check_modules(GLIB REQUIRED glib-2.0)
8-pkg_check_modules(GDK REQUIRED gdk-2.0)
9-pkg_check_modules(GTK REQUIRED gtk+-2.0)
10+pkg_check_modules(GDK REQUIRED gdk-3.0)
11+pkg_check_modules(GTK REQUIRED gtk+-3.0)
12 pkg_check_modules(GIO REQUIRED gio-2.0)
13-pkg_check_modules(WNCK REQUIRED libwnck-1.0)
14+pkg_check_modules(WNCK REQUIRED libwnck-3.0)
15+pkg_check_modules(QTGCONF REQUIRED libqtgconf)
16+pkg_check_modules(NUXCORE REQUIRED nux-core-1.0)
17+pkg_check_modules(PANGO REQUIRED pango)
18
19
20 # GSettings schemas
21
22=== modified file 'data/unity-2d.convert'
23--- data/unity-2d.convert 2011-07-25 11:56:59 +0000
24+++ data/unity-2d.convert 2011-08-09 17:30:25 +0000
25@@ -3,5 +3,3 @@
26 hide-mode = /desktop/unity-2d/launcher/hide_mode
27 use-strut = /desktop/unity-2d/launcher/use_strut
28
29-[com.canonical.Unity.Launcher]
30-favorites = /desktop/unity-2d/launcher/favorites
31
32=== renamed file 'debian/20_unity-2d-gconf-default' => 'debian/20_ubuntu-2d-gconf-default'
33--- debian/20_unity-2d-gconf-default 2011-07-25 11:56:59 +0000
34+++ debian/20_ubuntu-2d-gconf-default 2011-08-09 17:30:25 +0000
35@@ -1,13 +1,5 @@
36-/apps/gnome-power-manager/lock/use_screensaver_settings true
37-/apps/gnome-power-manager/general/use_time_for_policy false
38-/desktop/gnome/applications/window_manager/default /usr/bin/metacity
39-/desktop/gnome/applications/window_manager/current /usr/bin/metacity
40 /apps/metacity/general/show_maximized_titlebars false
41 /apps/metacity/general/auto_maximize_windows true
42 /apps/metacity/general/capture_before_unmap true
43 /apps/metacity/general/compositing_manager true
44 /apps/metacity/general/compositor_effects false
45-/apps/metacity/general/theme Ambiance
46-/desktop/gnome/interface/gtk_theme Ambiance
47-/desktop/gnome/interface/icon_theme ubuntu-mono-dark
48-/desktop/gnome/peripherals/mouse/cursor_theme DMZ-White
49
50=== renamed file 'debian/20_unity-2d-gconf-mandatory' => 'debian/20_ubuntu-2d-gconf-mandatory'
51--- debian/20_unity-2d-gconf-mandatory 2011-06-15 13:05:38 +0000
52+++ debian/20_ubuntu-2d-gconf-mandatory 2011-08-09 17:30:25 +0000
53@@ -1,3 +1,2 @@
54-/apps/nautilus/preferences/exit_with_last_window false
55 /apps/metacity/global_keybindings/panel_main_menu disabled
56 /apps/metacity/global_keybindings/panel_run_dialog disabled
57
58=== modified file 'debian/changelog'
59--- debian/changelog 2011-07-29 14:05:54 +0000
60+++ debian/changelog 2011-08-09 17:30:25 +0000
61@@ -1,20 +1,33 @@
62-unity-2d (3.8.14-0ubuntu1) UNRELEASED; urgency=low
63-
64- *
65-
66- -- Florian Boucault <florian.boucault@canonical.com> Fri, 29 Jul 2011 16:05:25 +0200
67-
68-unity-2d (3.8.12-0ubuntu2) natty; urgency=low
69+unity-2d (3.8.14.1-0ubuntu1) oneiric; urgency=low
70+
71+ * Few upstream fixes:
72+ - unity-2d-places crashed with SIGSEGV in
73+ QDeclarativePropertyPrivate::initProperty() (LP: #817896)
74+ - update resets unity launcher favorites (LP: #817954)
75+
76+ -- Didier Roche <didrocks@ubuntu.com> Tue, 02 Aug 2011 16:08:27 +0200
77+
78+unity-2d (3.8.14-0ubuntu1) oneiric; urgency=low
79+
80+ * New upstream release:
81+ - [launcher] Need to press Alt+F1 twice to show launcher (LP: #812787)
82+ * debian/control:
83+ - build on latest libunity-core-4.0-dev and latest libnux-1.0-dev
84+
85+ -- Didier Roche <didrocks@ubuntu.com> Mon, 01 Aug 2011 19:53:40 +0200
86+
87+unity-2d (3.8.12-0ubuntu2) oneiric; urgency=low
88
89 * debian/control:
90 - enforcing latest libunity-private0 to be installed for each local
91 consumer
92+ - don't recommends indicator-me, it's deprecated
93 * debian/libunity-2d-private0.lintian-overrides:
94 - remove a qml-related exported symbol warning wrongly detected
95
96- -- Didier Roche <didrocks@ubuntu.com> Fri, 29 Jul 2011 08:01:51 +0200
97+ -- Didier Roche <didrocks@ubuntu.com> Fri, 29 Jul 2011 15:19:11 +0200
98
99-unity-2d (3.8.12-0ubuntu1) natty; urgency=low
100+unity-2d (3.8.12-0ubuntu1) oneiric; urgency=low
101
102 [ Florian Boucault ]
103 * Upstreamed patch 01_build_with_new_indicator.patch
104@@ -32,6 +45,7 @@
105 - remove default value for /desktop/unity-2d/launcher/favorites
106 * debian/control:
107 - add dependency on libdconf-qt-dev
108+ - add dependency on libnux-1.0-dev
109
110 [ Didier Roche ]
111 * New upstream release:
112@@ -73,13 +87,27 @@
113 * Fix typo in trigger (debian/unity-2d.triggers): (LP: #807358)
114 * Install the apport hook in the right directory so that it's not launched
115 unconditionally (LP: #712343)
116+ * debian/control:
117+ - dep on latest libqtdee-dev
118+ - dep now on gtk3 indicator version
119+ - dep on versionned libnux-1.0-dev
120+ - dep on versionned libunity-core-4.0-dev
121 * debian/control, debian/rules, debian/libunity-2d-private-dev:
122 - add new -dev project (LP: #814709)
123 - add an upstream pc file
124
125- -- Florian Boucault <florian.boucault@canonical.com> Thu, 28 Jul 2011 12:05:05 +0200
126-
127-unity-2d (3.8.10-0ubuntu1) natty; urgency=low
128+ -- Didier Roche <didrocks@ubuntu.com> Thu, 28 Jul 2011 12:05:38 +0200
129+
130+unity-2d (3.8.10-0ubuntu2) oneiric; urgency=low
131+
132+ * debian/control:
133+ - rebuild with new indicator 0.4
134+ * 01_build_with_new_indicator.patch:
135+ - patch to build with the new indicator 0.4 stack
136+
137+ -- Didier Roche <didrocks@ubuntu.com> Sun, 10 Jul 2011 23:48:01 +0200
138+
139+unity-2d (3.8.10-0ubuntu1) oneiric; urgency=low
140
141 [ Florian Boucault ]
142 * debian/unity-2d-launcher.install:
143@@ -102,10 +130,17 @@
144 - Missing a GConf schema file for the /desktop/unity-2d/… keys
145 (LP: #750303)
146 - [dash] home screen search hint should be 'Search' (LP: #797825)
147-
148- -- Florian Boucault <florian.boucault@canonical.com> Wed, 13 Jul 2011 11:59:29 +0200
149-
150-unity-2d (3.8.8-0ubuntu1) natty; urgency=low
151+ * debian/unity-2d.gconf-defaults,
152+ debian/20_ubuntu-2d-gconf-default:
153+ - transition some gconf keys from session-wide to system-wide
154+ (LP: #797672, #797676)
155+ * debian/control:
156+ - ensure we are still using gtk2 indicator for alpha2 (LP: #804938)
157+ - bump standards-version
158+
159+ -- Didier Roche <didrocks@ubuntu.com> Mon, 04 Jul 2011 11:05:54 +0200
160+
161+unity-2d (3.8.8-0ubuntu1) oneiric; urgency=low
162
163 [ Didier Roche ]
164 * new upstream release:
165@@ -152,7 +187,21 @@
166
167 -- Didier Roche <didrocks@ubuntu.com> Tue, 14 Jun 2011 16:14:18 +0200
168
169-unity-2d (3.8.6-0ubuntu1) natty; urgency=low
170+unity-2d (3.8.6-0ubuntu3~ppa1) oneiric; urgency=low
171+
172+ * Rebuild with new gcc
173+
174+ -- Didier Roche <didrocks@ubuntu.com> Tue, 07 Jun 2011 15:00:32 +0200
175+
176+unity-2d (3.8.6-0ubuntu2) oneiric; urgency=low
177+
178+ * debian/unity-2d.postinst, debian/unity-2d.postrm:
179+ - remove the magic to set unity-2d in oneiric as the default session in gdm
180+ as it's now installed on the ubuntu CD.
181+
182+ -- Didier Roche <didrocks@ubuntu.com> Wed, 01 Jun 2011 09:42:21 +0200
183+
184+unity-2d (3.8.6-0ubuntu1) oneiric; urgency=low
185
186 * New upstream release:
187 - [launcher] Support static shortcuts in the quicklists. (LP: #669923)
188@@ -196,6 +245,18 @@
189 * debian/libunity-2d-private0.post*
190 - removed: ldconfig is generated directly by dh_makeshlibs as we don't pass
191 -n anymore
192+ * don't install unity-2d session as it's in gnome-session now
193+ * debian/unity-2d.install
194+ debian/20_ubuntu-2d-gconf-default
195+ debian/20_ubuntu-2d-gconf-mandatory
196+ debian/gconf/ubuntu-2d.default.path
197+ debian/gconf/ubuntu-2d.mandatory.path:
198+ - remove uneeded defaults and mandatory
199+ - remove some deprecated keys
200+ - the session is now called ubuntu-2d and not unity-2d anymore
201+ * debian/unity-2d.preinst, debian/unity-2d.postinst
202+ debian/unity-2d.postrm:
203+ - take into account the natty -> oneiric migration with session name change
204
205 -- Didier Roche <didrocks@ubuntu.com> Wed, 25 May 2011 12:19:25 +0200
206
207
208=== modified file 'debian/control'
209--- debian/control 2011-07-29 11:55:03 +0000
210+++ debian/control 2011-08-09 17:30:25 +0000
211@@ -10,19 +10,22 @@
212 libqt4-dev,
213 libqt4-opengl-dev,
214 libglib2.0-dev,
215- libwnck-dev,
216+ libwnck-3-dev,
217+ libpango1.0-dev,
218 libqtgconf-dev,
219 libdconf-qt-dev,
220 libqtbamf-dev,
221- libqtdee-dev,
222+ libqtdee-dev (>= 0.2.3),
223 libdbusmenu-qt-dev,
224 libx11-dev,
225- libindicator-dev,
226- libgtk2.0-dev,
227+ libindicator3-dev,
228+ libgtk-3-dev,
229 libutouch-geis-dev,
230- libstartup-notification0-dev
231-Standards-Version: 3.9.1
232-Vcs-Bzr: http://bazaar.launchpad.net/~unity-2d-team/unity-2d/trunk
233+ libstartup-notification0-dev,
234+ libunity-core-4.0-dev (>= 4.6.0),
235+ libnux-1.0-dev (>= 1.0.8),
236+Standards-Version: 3.9.2
237+Vcs-Bzr: http://bazaar.launchpad.net/~unity-2d-team/unity-2d/oneiric
238
239 Package: unity-2d
240 Architecture: all
241@@ -56,9 +59,10 @@
242 Depends: ${shlibs:Depends},
243 ${misc:Depends},
244 libunity-2d-private0 (= ${binary:Version}),
245- libgtk2.0-dev,
246- libwnck-dev,
247+ libgtk-3-dev,
248+ libwnck-3-dev,
249 libglib2.0-dev,
250+ libpango1.0-dev,
251 Description: Unity 2D shared library - development files
252 This library is used to host common code used by several Unity 2D components
253 It is only used internally, there is no use case for it outside of the unity-2d
254@@ -90,7 +94,6 @@
255 Recommends: indicator-application,
256 indicator-appmenu,
257 indicator-datetime,
258- indicator-me,
259 indicator-messages,
260 indicator-session,
261 indicator-sound,
262
263=== renamed file 'debian/gconf/unity-2d.default.path' => 'debian/gconf/ubuntu-2d.default.path'
264--- debian/gconf/unity-2d.default.path 2011-06-15 13:05:38 +0000
265+++ debian/gconf/ubuntu-2d.default.path 2011-08-09 17:30:25 +0000
266@@ -1,3 +1,3 @@
267-# Additional mandatory path for unity-2d experience
268-xml:readonly:/var/lib/gconf/unity-2d.default
269+# Additional mandatory path for ubuntu-2d experience
270+xml:readonly:/var/lib/gconf/ubuntu-2d.default
271
272
273=== renamed file 'debian/gconf/unity-2d.mandatory.path' => 'debian/gconf/ubuntu-2d.mandatory.path'
274--- debian/gconf/unity-2d.mandatory.path 2011-06-15 13:05:38 +0000
275+++ debian/gconf/ubuntu-2d.mandatory.path 2011-08-09 17:30:25 +0000
276@@ -1,3 +1,3 @@
277-# Additional mandatory path for unity-2d experience
278-xml:readonly:/var/lib/gconf/unity-2d.mandatory
279+# Additional mandatory path for ubuntu-2d experience
280+xml:readonly:/var/lib/gconf/ubuntu-2d.mandatory
281
282
283=== modified file 'debian/unity-2d-panel.install'
284--- debian/unity-2d-panel.install 2011-01-14 21:41:39 +0000
285+++ debian/unity-2d-panel.install 2011-08-09 17:30:25 +0000
286@@ -1,4 +1,2 @@
287 usr/bin/unity-2d-panel
288 usr/share/applications/unity-2d-panel.desktop
289-usr/share/unity-2d/panel/artwork/background.png
290-usr/share/unity-2d/panel/artwork/divider.png
291
292=== added file 'debian/unity-2d.gconf-defaults'
293--- debian/unity-2d.gconf-defaults 1970-01-01 00:00:00 +0000
294+++ debian/unity-2d.gconf-defaults 2011-08-09 17:30:25 +0000
295@@ -0,0 +1,4 @@
296+/desktop/unity-2d/launcher/favorites [ubiquity-gtkui.desktop,nautilus-home.desktop,firefox.desktop,libreoffice-writer.desktop,libreoffice-calc.desktop,libreoffice-impress.desktop,ubuntu-software-center.desktop,ubuntuone-control-panel-gtk.desktop]
297+/desktop/unity-2d/launcher/hide_mode 2
298+/desktop/unity-2d/launcher/use_strut false
299+/desktop/unity-2d/launcher/super_key_enable true
300
301=== modified file 'debian/unity-2d.install'
302--- debian/unity-2d.install 2011-07-22 14:44:57 +0000
303+++ debian/unity-2d.install 2011-08-09 17:30:25 +0000
304@@ -1,9 +1,7 @@
305 debian/unity-2d.py /usr/share/apport/package-hooks
306 debian/gconf/* /usr/share/gconf
307-session/unity-2d.desktop /usr/share/xsessions
308-session/2d-ubuntu.session /usr/share/gnome-session/sessions
309-debian/20_unity-2d-gconf-mandatory /usr/share/gconf/unity-2d/mandatory
310-debian/20_unity-2d-gconf-default /usr/share/gconf/unity-2d/default
311+debian/20_ubuntu-2d-gconf-mandatory /usr/share/gconf/ubuntu-2d/mandatory
312+debian/20_ubuntu-2d-gconf-default /usr/share/gconf/ubuntu-2d/default
313 usr/share/locale/*/LC_MESSAGES/unity-2d.mo
314 usr/share/glib-2.0/schemas/com.canonical.Unity2d.gschema.xml
315 usr/share/GConf/gsettings
316
317=== modified file 'debian/unity-2d.postinst'
318--- debian/unity-2d.postinst 2011-06-15 13:05:38 +0000
319+++ debian/unity-2d.postinst 2011-08-09 17:30:25 +0000
320@@ -9,24 +9,21 @@
321
322 case "$1" in
323 configure|upgrade)
324- if [ -x /usr/lib/gdm/gdm-set-default-session ] ; then
325- /usr/lib/gdm/gdm-set-default-session --keep-old unity-2d || true
326- fi
327 if which update-gconf-defaults >/dev/null 2>&1 ; then
328- mkdir -p /var/lib/gconf/unity-2d.mandatory
329- mkdir -p /var/lib/gconf/unity-2d.default
330+ mkdir -p /var/lib/gconf/ubuntu-2d.mandatory
331+ mkdir -p /var/lib/gconf/ubuntu-2d.default
332 fi
333 ;;
334 triggered)
335 for trigger in $2; do
336 case $trigger in
337- /usr/share/gconf/unity-2d/mandatory)
338- update-gconf-defaults --source /usr/share/gconf/unity-2d/mandatory \
339- --destination /var/lib/gconf/unity-2d.mandatory --no-signal
340+ /usr/share/gconf/ubuntu-2d/mandatory)
341+ update-gconf-defaults --source /usr/share/gconf/ubuntu-2d/mandatory \
342+ --destination /var/lib/gconf/ubuntu-2d.mandatory --no-signal
343 ;;
344- /usr/share/gconf/unity-2d/default)
345- update-gconf-defaults --source /usr/share/gconf/unity-2d/default \
346- --destination /var/lib/gconf/unity-2d.default --no-signal
347+ /usr/share/gconf/ubuntu-2d/default)
348+ update-gconf-defaults --source /usr/share/gconf/ubuntu-2d/default \
349+ --destination /var/lib/gconf/ubuntu-2d.default --no-signal
350 ;;
351 esac
352 done
353@@ -39,9 +36,9 @@
354
355 # Upon installation/upgrade, regenerate all databases, because in this case
356 # there will be no trigger run
357-update-gconf-defaults --source /usr/share/gconf/unity-2d/mandatory \
358- --destination /var/lib/gconf/unity-2d.mandatory --no-signal
359-update-gconf-defaults --source /usr/share/gconf/unity-2d/default \
360- --destination /var/lib/gconf/unity-2d.default --no-signal
361+update-gconf-defaults --source /usr/share/gconf/ubuntu-2d/mandatory \
362+ --destination /var/lib/gconf/ubuntu-2d.mandatory --no-signal
363+update-gconf-defaults --source /usr/share/gconf/ubuntu-2d/default \
364+ --destination /var/lib/gconf/ubuntu-2d.default --no-signal
365 signal_daemons
366
367
368=== modified file 'debian/unity-2d.postrm'
369--- debian/unity-2d.postrm 2011-06-15 13:05:38 +0000
370+++ debian/unity-2d.postrm 2011-08-09 17:30:25 +0000
371@@ -3,20 +3,17 @@
372
373 case "$1" in
374 remove|purge)
375- if which update-gconf-defaults >/dev/null 2>&1 && [ -d /usr/share/gconf/mandatory/unity-2d ]; then
376- update-gconf-defaults --source /usr/share/gconf/unity-2d/mandatory \
377- --destination /var/lib/gconf/unity-2d.mandatory
378- update-gconf-defaults --source /usr/share/gconf/unity-2d/default \
379- --destination /var/lib/gconf/unity-2d.default
380- fi
381- if [ -d /var/lib/gconf/unity-2d.mandatory ]; then
382- rm -rf /var/lib/gconf/unity-2d.mandatory
383- fi
384- if [ -d /var/lib/gconf/unity-2d.default ]; then
385- rm -rf /var/lib/gconf/unity-2d.default
386- fi
387- if [ -x /usr/lib/gdm/gdm-set-default-session ] ; then
388- /usr/lib/gdm/gdm-set-default-session --remove unity-2d || true
389+ if which update-gconf-defaults >/dev/null 2>&1 && [ -d /usr/share/gconf/mandatory/ubuntu-2d ]; then
390+ update-gconf-defaults --source /usr/share/gconf/ubuntu-2d/mandatory \
391+ --destination /var/lib/gconf/ubuntu-2d.mandatory
392+ update-gconf-defaults --source /usr/share/gconf/ubuntu-2d/default \
393+ --destination /var/lib/gconf/ubuntu-2d.default
394+ fi
395+ if [ -d /var/lib/gconf/ubuntu-2d.mandatory ]; then
396+ rm -rf /var/lib/gconf/ubuntu-2d.mandatory
397+ fi
398+ if [ -d /var/lib/gconf/ubuntu-2d.default ]; then
399+ rm -rf /var/lib/gconf/ubuntu-2d.default
400 fi
401 ;;
402 esac
403
404=== added file 'debian/unity-2d.preinst'
405--- debian/unity-2d.preinst 1970-01-01 00:00:00 +0000
406+++ debian/unity-2d.preinst 2011-08-09 17:30:25 +0000
407@@ -0,0 +1,16 @@
408+#!/bin/sh
409+set -e
410+
411+case "$1" in
412+ install|upgrade)
413+ if dpkg --compare-versions "$2" le "3.8.6-0ubuntu1"; then
414+ if [ -d /var/lib/gconf/unity-2d.mandatory ]; then
415+ mv /var/lib/gconf/unity-2d.mandatory /var/lib/gconf/ubuntu-2d.mandatory || true
416+ mv /var/lib/gconf/unity-2d.default /var/lib/gconf/ubuntu-2d.default || true
417+ fi
418+ fi
419+ ;;
420+esac
421+
422+#DEBHELPER#
423+
424
425=== modified file 'launcher/Launcher.qml'
426--- launcher/Launcher.qml 2011-08-01 11:58:35 +0000
427+++ launcher/Launcher.qml 2011-08-09 17:30:25 +0000
428@@ -22,7 +22,10 @@
429 LauncherDropItem {
430 id: launcher
431
432+ Accessible.name: "root"
433+
434 GnomeBackground {
435+ Accessible.name: "background"
436 anchors.fill: parent
437 overlay_color: "black"
438 overlay_alpha: 0.66
439@@ -30,6 +33,7 @@
440 }
441
442 Rectangle {
443+ Accessible.name: "background"
444 anchors.fill: parent
445 color: "black"
446 opacity: 0.66
447@@ -37,6 +41,7 @@
448 }
449
450 Image {
451+ Accessible.name: "border"
452 id: border
453
454 width: 1
455@@ -50,12 +55,16 @@
456 onWebpageUrlDropped: applications.insertWebFavorite(url)
457
458 FocusScope {
459+ Accessible.name: "content"
460+
461 focus: true
462 anchors.fill: parent
463 z: 1 /* ensure the lists are always strictly on top of the background */
464
465 LauncherList {
466 id: main
467+ Accessible.name: "main"
468+
469 anchors.top: parent.top
470 anchors.bottom: shelf.top
471 anchors.bottomMargin: itemPadding
472@@ -75,6 +84,8 @@
473
474 LauncherList {
475 id: shelf
476+ Accessible.name: "shelf"
477+
478 anchors.bottom: parent.bottom
479 anchors.bottomMargin: main.anchors.bottomMargin
480 height: (tileSize + itemPadding) * count
481
482=== modified file 'launcher/LauncherItem.qml'
483--- launcher/LauncherItem.qml 2011-07-14 11:17:30 +0000
484+++ launcher/LauncherItem.qml 2011-08-09 17:30:25 +0000
485@@ -48,6 +48,8 @@
486 DropItem {
487 id: item
488
489+ Accessible.role: Accessible.PushButton
490+
491 anchors.horizontalCenter: parent.horizontalCenter
492
493 property int padding
494
495=== modified file 'launcher/LauncherList.qml'
496--- launcher/LauncherList.qml 2011-08-01 11:58:35 +0000
497+++ launcher/LauncherList.qml 2011-08-09 17:30:25 +0000
498@@ -77,6 +77,17 @@
499 delegate: LauncherItem {
500 id: launcherItem
501
502+ function accessibleDescription() {
503+ if (running) {
504+ var windows = u2d.tr("%1 window opened", "%1 windows opened", item.windowCount).arg(item.windowCount)
505+ return "%1 %2".arg(item.name).arg(windows)
506+ } else {
507+ return "%1 %2".arg(item.name).arg(u2d.tr("not running"))
508+ }
509+ }
510+
511+ Accessible.name: accessibleDescription()
512+
513 width: list.width
514 tileSize: list.tileSize
515 padding: list.itemPadding
516
517=== modified file 'launcher/app/launcher.cpp'
518--- launcher/app/launcher.cpp 2011-08-09 13:33:24 +0000
519+++ launcher/app/launcher.cpp 2011-08-09 17:30:25 +0000
520@@ -78,6 +78,7 @@
521 {
522 Unity2dApplication::earlySetup(argc, argv);
523 Unity2dApplication application(argc, argv);
524+ application.setApplicationName("Unity 2D Launcher");
525 QSet<QString> arguments = QSet<QString>::fromList(QCoreApplication::arguments());
526
527 GnomeSessionClient client(INSTALL_PREFIX "/share/applications/unity-2d-launcher.desktop");
528@@ -91,6 +92,7 @@
529 Unity2dPanel panel(true);
530 panel.setEdge(Unity2dPanel::LeftEdge);
531 panel.setFixedWidth(LauncherClient::MaximumWidth);
532+ panel.setAccessibleName("Launcher");
533
534 VisibilityController* visibilityController = new VisibilityController(&panel);
535
536
537=== modified file 'libunity-2d-private/CMakeLists.txt'
538--- libunity-2d-private/CMakeLists.txt 2011-07-29 13:49:34 +0000
539+++ libunity-2d-private/CMakeLists.txt 2011-08-09 17:30:25 +0000
540@@ -6,7 +6,7 @@
541 pkg_check_modules(QTDEE REQUIRED libqtdee)
542 pkg_check_modules(DBUSMENUQT REQUIRED dbusmenu-qt)
543 pkg_check_modules(STARTUPNOTIFICATION REQUIRED libstartup-notification-1.0)
544-pkg_check_modules(INDICATOR REQUIRED indicator)
545+pkg_check_modules(INDICATOR REQUIRED indicator3-0.4)
546 pkg_check_modules(DCONFQT REQUIRED dconf-qt)
547
548 set(libunity-2d-private_SOVERSION 0)
549
550=== modified file 'libunity-2d-private/Unity2d/GnomeBackground.qml'
551--- libunity-2d-private/Unity2d/GnomeBackground.qml 2011-08-09 13:33:24 +0000
552+++ libunity-2d-private/Unity2d/GnomeBackground.qml 2011-08-09 17:30:25 +0000
553@@ -17,7 +17,7 @@
554 */
555
556 import QtQuick 1.0
557-import gconf 1.0
558+import QConf 1.0
559 /* Necessary to access the blended image provider and CacheEffect */
560 import Unity2d 1.0
561
562@@ -32,19 +32,9 @@
563 property bool cached: true
564 effect: (cached) ? cacheEffect : null
565
566- GConfItem {
567- id: primary_color
568- key: "/desktop/gnome/background/primary_color"
569- }
570-
571- GConfItem {
572- id: picture_filename
573- key: "/desktop/gnome/background/picture_filename"
574- }
575-
576- GConfItem {
577- id: picture_options
578- key: "/desktop/gnome/background/picture_options"
579+ QConf {
580+ id: desktopBackground
581+ schema: "org.gnome.desktop.background"
582 }
583
584 Rectangle {
585@@ -55,13 +45,13 @@
586 }
587
588 anchors.fill: parent
589- color: primary_color.value
590+ color: desktopBackground.primaryColor
591 }
592
593 Image {
594 id: picture
595
596- visible: picture_filename.value
597+ visible: desktopBackground.pictureUri
598 source: {
599 if (!visible) return ""
600
601@@ -74,8 +64,8 @@
602 https://bugs.launchpad.net/ubuntu/+source/ubuntu-wallpapers/+bug/296538
603 http://bugreports.qt.nokia.com/browse/QTBUG-7276
604 */
605- var filename = picture_filename.value
606- if(filename == "/usr/share/backgrounds/warty-final-ubuntu.png")
607+ var filename = desktopBackground.pictureUri
608+ if(filename == "file:///usr/share/backgrounds/warty-final-ubuntu.png")
609 filename = "/usr/share/unity-2d/warty-final-ubuntu.jpg"
610
611 if(overlay_alpha > 0.0)
612@@ -99,13 +89,13 @@
613 - "spanned" (NOT IMPLEMENTED)
614 */
615 fillMode: {
616- if(picture_options.value == "wallpaper")
617+ if(desktopBackground.pictureOptions== "wallpaper")
618 return Image.Tile
619- else if(picture_options.value == "scaled")
620+ else if(desktopBackground.pictureOptions == "scaled")
621 return Image.PreserveAspectFit
622- else if(picture_options.value == "stretched")
623+ else if(desktopBackground.pictureOptions == "stretched")
624 return Image.Stretch
625- else if(picture_options.value == "zoom")
626+ else if(desktopBackground.pictureOptions == "zoom")
627 return Image.PreserveAspectCrop
628 else return Image.PreserveAspectFit
629 }
630
631=== modified file 'libunity-2d-private/Unity2d/plugin.cpp'
632--- libunity-2d-private/Unity2d/plugin.cpp 2011-07-26 16:05:51 +0000
633+++ libunity-2d-private/Unity2d/plugin.cpp 2011-08-09 17:30:25 +0000
634@@ -20,10 +20,6 @@
635 /* Required otherwise using wnck_set_client_type breaks linking with error:
636 undefined reference to `wnck_set_client_type(WnckClientType)'
637 */
638-extern "C" {
639-#include <libwnck/util.h>
640-}
641-
642 #include "plugin.h"
643
644 #include "launcherapplication.h"
645
646=== modified file 'libunity-2d-private/src/CMakeLists.txt'
647--- libunity-2d-private/src/CMakeLists.txt 2011-07-29 13:49:34 +0000
648+++ libunity-2d-private/src/CMakeLists.txt 2011-08-09 17:30:25 +0000
649@@ -2,7 +2,9 @@
650
651 # Sources
652 set(lib${LIB_NAME}_SRCS
653+ debug.cpp
654 gconnector.cpp
655+ gimageutils.cpp
656 gnomesessionclient.cpp
657 keyboardmodifiersmonitor.cpp
658 hotkeymonitor.cpp
659@@ -64,6 +66,8 @@
660 ${CMAKE_CURRENT_BINARY_DIR}
661 ${CMAKE_CURRENT_SOURCE_DIR}
662 ${GLIB_INCLUDE_DIRS}
663+ ${GTK_INCLUDE_DIRS}
664+ ${PANGO_INCLUDE_DIRS}
665 ${WNCK_INCLUDE_DIRS}
666 ${QTBAMF_INCLUDE_DIRS}
667 ${QTGCONF_INCLUDE_DIRS}
668@@ -93,6 +97,8 @@
669 ${QT_QTNETWORK_LIBRARIES}
670 ${X11_LIBRARIES}
671 ${GLIB_LDFLAGS}
672+ ${GTK_LDFLAGS}
673+ ${PANGO_LDFLAGS}
674 ${WNCK_LDFLAGS}
675 ${GDK_LDFLAGS}
676 ${GIO_LDFLAGS}
677
678=== added file 'libunity-2d-private/src/debug.cpp'
679--- libunity-2d-private/src/debug.cpp 1970-01-01 00:00:00 +0000
680+++ libunity-2d-private/src/debug.cpp 2011-08-09 17:30:25 +0000
681@@ -0,0 +1,23 @@
682+/* This file is part of unity-2d
683+ Copyright 2011 Canonical
684+ Author: Aurelien Gateau <aurelien.gateau@canonical.com>
685+
686+ This program is free software; you can redistribute it and/or modify
687+ it under the terms of the GNU General Public License as published
688+ by the Free Software Foundation; version 3.
689+
690+ This program is distributed in the hope that it will be useful,
691+ but WITHOUT ANY WARRANTY; without even the implied warranty of
692+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
693+ GNU General Public License for more details.
694+
695+ You should have received a copy of the GNU General Public License
696+ along with this program. If not, see <http://www.gnu.org/licenses/>.
697+ */
698+// Self
699+#include <debug_p.h>
700+
701+QDebug operator<<(QDebug& dbg, const std::string& str)
702+{
703+ return dbg << QString::fromUtf8(str.c_str());
704+}
705
706=== modified file 'libunity-2d-private/src/debug_p.h'
707--- libunity-2d-private/src/debug_p.h 2011-03-28 14:06:14 +0000
708+++ libunity-2d-private/src/debug_p.h 2011-08-09 17:30:25 +0000
709@@ -17,8 +17,12 @@
710 #ifndef DEBUG_P_H
711 #define DEBUG_P_H
712
713+// Qt
714 #include <QDebug>
715
716+// STL
717+#include <string>
718+
719 #define _UQ_TRACE(level) (level().nospace() << __PRETTY_FUNCTION__ << ":").space()
720
721 // Simple macros to get KDebug like support
722@@ -62,5 +66,7 @@
723
724 #define UQ_DEBUG_BLOCK Unity2dDebugBlock __unity2dDebugBlock__(__PRETTY_FUNCTION__)
725
726+// Support for outputing std::string with qDebug
727+QDebug operator<<(QDebug& dbg, const std::string& str);
728
729 #endif /* DEBUG_P_H */
730
731=== added file 'libunity-2d-private/src/gimageutils.cpp'
732--- libunity-2d-private/src/gimageutils.cpp 1970-01-01 00:00:00 +0000
733+++ libunity-2d-private/src/gimageutils.cpp 2011-08-09 17:30:25 +0000
734@@ -0,0 +1,102 @@
735+/*
736+ * This file is part of unity-2d
737+ *
738+ * Copyright 2011 Canonical Ltd.
739+ *
740+ * Authors:
741+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
742+ *
743+ * This program is free software; you can redistribute it and/or modify
744+ * it under the terms of the GNU General Public License as published by
745+ * the Free Software Foundation; version 3.
746+ *
747+ * This program is distributed in the hope that it will be useful,
748+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
749+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
750+ * GNU General Public License for more details.
751+ *
752+ * You should have received a copy of the GNU General Public License
753+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
754+ */
755+// Self
756+#include <gimageutils.h>
757+
758+// Local
759+#include <debug_p.h>
760+#include <gscopedpointer.h>
761+
762+// Qt
763+#include <QByteArray>
764+#include <QImage>
765+
766+// GTK
767+#include <gtk/gtk.h>
768+
769+namespace GImageUtils
770+{
771+
772+QImage imageForIconString(const QString& name, int size, GtkIconTheme* theme)
773+{
774+ if (!theme) {
775+ theme = gtk_icon_theme_get_default();
776+ }
777+ QByteArray utf8Name = name.toUtf8();
778+
779+ /* Load the icon by creating a GIcon from the string icon_name.
780+ icon_name can contain more than a simple icon name but possibly
781+ a string as returned by g_icon_to_string().
782+ */
783+ GObjectScopedPointer<GIcon> icon(g_icon_new_for_string(utf8Name.data(), NULL));
784+ GScopedPointer<GtkIconInfo, gtk_icon_info_free> iconInfo;
785+ iconInfo.reset(gtk_icon_theme_lookup_by_gicon(
786+ theme,
787+ icon.data(),
788+ size,
789+ (GtkIconLookupFlags)0)
790+ );
791+
792+ if (!iconInfo) {
793+ UQ_WARNING << "Failed to find icon:" << name;
794+ return QImage();
795+ }
796+
797+ GObjectScopedPointer<GdkPixbuf> pixbuf(gtk_icon_info_load_icon(iconInfo.data(), NULL));
798+ if (!pixbuf) {
799+ UQ_WARNING << "Failed to load icon:" << name;
800+ return QImage();
801+ }
802+
803+ return imageForPixbuf(pixbuf.data());
804+}
805+
806+QImage imageForPixbuf(const GdkPixbuf* pixbuf)
807+{
808+ QImage image(gdk_pixbuf_get_pixels(pixbuf),
809+ gdk_pixbuf_get_width(pixbuf),
810+ gdk_pixbuf_get_height(pixbuf),
811+ gdk_pixbuf_get_rowstride(pixbuf),
812+ QImage::Format_ARGB32);
813+
814+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
815+ /* ABGR → ARGB */
816+ QImage swappedImage = image.rgbSwapped();
817+#else
818+ /* ABGR → BGRA */
819+ /* Reference: https://bugs.launchpad.net/unity-2d/+bug/758782 */
820+ QImage swappedImage(image.size(), image.format());
821+ for (int i = 0; i < swappedImage.height(); ++i) {
822+ QRgb* p = (QRgb*) image.constScanLine(i);
823+ QRgb* q = (QRgb*) swappedImage.scanLine(i);
824+ QRgb* end = p + image.width();
825+ while (p < end) {
826+ *q = qRgba(qAlpha(*p), qRed(*p), qGreen(*p), qBlue(*p));
827+ p++;
828+ q++;
829+ }
830+ }
831+#endif
832+
833+ return swappedImage;
834+}
835+
836+} // namespace
837
838=== added file 'libunity-2d-private/src/gimageutils.h'
839--- libunity-2d-private/src/gimageutils.h 1970-01-01 00:00:00 +0000
840+++ libunity-2d-private/src/gimageutils.h 2011-08-09 17:30:25 +0000
841@@ -0,0 +1,46 @@
842+/*
843+ * This file is part of unity-2d
844+ *
845+ * Copyright 2011 Canonical Ltd.
846+ *
847+ * Authors:
848+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
849+ *
850+ * This program is free software; you can redistribute it and/or modify
851+ * it under the terms of the GNU General Public License as published by
852+ * the Free Software Foundation; version 3.
853+ *
854+ * This program is distributed in the hope that it will be useful,
855+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
856+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
857+ * GNU General Public License for more details.
858+ *
859+ * You should have received a copy of the GNU General Public License
860+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
861+ */
862+#ifndef GIMAGEUTILS_H
863+#define GIMAGEUTILS_H
864+
865+// Local
866+
867+// Qt
868+
869+class QImage;
870+class QString;
871+
872+struct _GdkPixbuf;
873+struct _GtkIconTheme;
874+
875+/**
876+ * Helper methods to deal with GTK images
877+ */
878+namespace GImageUtils
879+{
880+
881+QImage imageForIconString(const QString& name, int size, struct _GtkIconTheme* theme = 0);
882+
883+QImage imageForPixbuf(const struct _GdkPixbuf* pixbuf);
884+
885+} // namespace
886+
887+#endif /* GIMAGEUTILS_H */
888
889=== modified file 'libunity-2d-private/src/iconimageprovider.cpp'
890--- libunity-2d-private/src/iconimageprovider.cpp 2011-07-29 13:49:34 +0000
891+++ libunity-2d-private/src/iconimageprovider.cpp 2011-08-09 17:30:25 +0000
892@@ -23,6 +23,7 @@
893 #include <QFile>
894
895 #include <debug_p.h>
896+#include <gimageutils.h>
897
898 static const char* UNITY_RES_PATH = "/usr/share/unity/";
899
900@@ -114,62 +115,9 @@
901 icon_name.chop(4);
902 }
903
904- /* Load the icon by creating a GIcon from the string icon_name.
905- icon_name can contain more than a simple icon name but possibly
906- a string as returned by g_icon_to_string().
907- */
908- QByteArray byte_array = icon_name.toUtf8();
909- gchar *g_icon_name = byte_array.data();
910-
911- GIcon *g_icon = g_icon_new_for_string(g_icon_name, NULL);
912- GtkIconInfo *icon_info = gtk_icon_theme_lookup_by_gicon(theme, g_icon,
913- requestedSize.width(),
914- (GtkIconLookupFlags)0);
915- g_object_unref(g_icon);
916-
917- if (icon_info == NULL) {
918- UQ_WARNING << "Failed to find icon:" << icon_name;
919- return QImage();
920- }
921-
922- GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon_info, NULL);
923- gtk_icon_info_free(icon_info);
924-
925- if (pixbuf == NULL) {
926- UQ_WARNING << "Failed to load icon:" << icon_name;
927- return QImage();
928- }
929-
930- QImage image(gdk_pixbuf_get_pixels(pixbuf),
931- gdk_pixbuf_get_width(pixbuf),
932- gdk_pixbuf_get_height(pixbuf),
933- gdk_pixbuf_get_rowstride(pixbuf),
934- QImage::Format_ARGB32);
935-
936-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
937- /* ABGR → ARGB */
938- QImage swappedImage = image.rgbSwapped();
939-#else
940- /* ABGR → BGRA */
941- /* Reference: https://bugs.launchpad.net/unity-2d/+bug/758782 */
942- QImage swappedImage(image.size(), image.format());
943- for (int i = 0; i < swappedImage.height(); ++i) {
944- QRgb* p = (QRgb*) image.constScanLine(i);
945- QRgb* q = (QRgb*) swappedImage.scanLine(i);
946- QRgb* end = p + image.width();
947- while (p < end) {
948- *q = qRgba(qAlpha(*p), qRed(*p), qGreen(*p), qBlue(*p));
949- p++;
950- q++;
951- }
952- }
953-#endif
954-
955- g_object_unref(pixbuf);
956-
957+ QImage image = GImageUtils::imageForIconString(icon_name, requestedSize.width(), theme);
958 if (size) {
959- *size = swappedImage.size();
960+ *size = image.size();
961 }
962-
963- return swappedImage;
964+ return image;
965 }
966
967=== modified file 'libunity-2d-private/src/launcherapplication.cpp'
968--- libunity-2d-private/src/launcherapplication.cpp 2011-07-29 13:49:34 +0000
969+++ libunity-2d-private/src/launcherapplication.cpp 2011-08-09 17:30:25 +0000
970@@ -14,10 +14,6 @@
971 * along with this program. If not, see <http://www.gnu.org/licenses/>.
972 */
973
974-/* Those have to be included before any QObject-style header to avoid
975- compilation errors. */
976-#include <gdk/gdk.h>
977-
978 /* Note regarding the use of wnck: it is critically important that the client
979 type be set to pager because wnck will pass that type over to the window
980 manager through XEvents.
981@@ -59,6 +55,7 @@
982 #include <QX11Info>
983
984 extern "C" {
985+#include <gdk/gdk.h>
986 #include <libsn/sn.h>
987 }
988
989@@ -649,7 +646,8 @@
990 GTimeVal timeval;
991
992 g_get_current_time (&timeval);
993- GObjectScopedPointer<GdkAppLaunchContext> context(gdk_app_launch_context_new());
994+ GdkDisplay* display = gdk_display_get_default();
995+ GObjectScopedPointer<GdkAppLaunchContext> context(gdk_display_get_app_launch_context(display));
996 /* Using GDK_CURRENT_TIME doesn’t seem to work, launched windows
997 sometimes don’t get focus (see https://launchpad.net/bugs/643616). */
998 gdk_app_launch_context_set_timestamp(context.data(), timeval.tv_sec);
999@@ -880,7 +878,7 @@
1000 QAction* keep = new QAction(m_menu);
1001 keep->setCheckable(is_running);
1002 keep->setChecked(sticky());
1003- keep->setText(is_running ? u2dTr("Keep In Launcher") : u2dTr("Remove From Launcher"));
1004+ keep->setText(is_running ? u2dTr("Keep in launcher") : u2dTr("Remove from launcher"));
1005 actions.append(keep);
1006 QObject::connect(keep, SIGNAL(triggered()), this, SLOT(onKeepTriggered()));
1007 }
1008
1009=== modified file 'libunity-2d-private/src/launcherapplicationslist.cpp'
1010--- libunity-2d-private/src/launcherapplicationslist.cpp 2011-07-29 13:49:34 +0000
1011+++ libunity-2d-private/src/launcherapplicationslist.cpp 2011-08-09 17:30:25 +0000
1012@@ -101,6 +101,16 @@
1013 application->installX11EventFilter(this);
1014 }
1015
1016+ /* Get the system applications data dirs and be flexible if / is not at the
1017+ end of each path. */
1018+ QString xdgDataDir = QFile::decodeName(getenv("XDG_DATA_DIRS"));
1019+ if (xdgDataDir.isEmpty()) {
1020+ xdgDataDir = "/usr/local/share/:/usr/share/";
1021+ }
1022+ Q_FOREACH(const QString& dirName, xdgDataDir.split(':')) {
1023+ m_xdgApplicationDirs << QDir::cleanPath(dirName + "/applications") + "/";
1024+ }
1025+
1026 load();
1027 }
1028
1029@@ -178,9 +188,17 @@
1030 }
1031
1032 QString
1033-LauncherApplicationsList::favoriteFromDesktopFilePath(QString desktop_file)
1034+LauncherApplicationsList::favoriteFromDesktopFilePath(const QString& _desktopFile) const
1035 {
1036- return QDir(desktop_file).dirName();
1037+ QString desktopFile(_desktopFile);
1038+ Q_FOREACH(const QString& applicationDir, m_xdgApplicationDirs) {
1039+ if (_desktopFile.startsWith(applicationDir)) {
1040+ desktopFile.remove(applicationDir);
1041+ desktopFile.replace("/", "-");
1042+ break;
1043+ }
1044+ }
1045+ return desktopFile;
1046 }
1047
1048 void
1049
1050=== modified file 'libunity-2d-private/src/launcherapplicationslist.h'
1051--- libunity-2d-private/src/launcherapplicationslist.h 2011-08-06 10:42:04 +0000
1052+++ libunity-2d-private/src/launcherapplicationslist.h 2011-08-09 17:30:25 +0000
1053@@ -70,7 +70,7 @@
1054 void insertApplication(LauncherApplication* application);
1055 void removeApplication(LauncherApplication* application);
1056
1057- static QString favoriteFromDesktopFilePath(QString desktop_file);
1058+ QString favoriteFromDesktopFilePath(const QString& desktop_file) const;
1059
1060 void writeFavoritesToGConf();
1061
1062@@ -89,6 +89,7 @@
1063 */
1064 QHash<QString, LauncherApplication*> m_applicationForExecutable;
1065 QConf* m_dconf_launcher;
1066+ QStringList m_xdgApplicationDirs;
1067
1068 /* Startup notification support */
1069 SnDisplay *m_snDisplay;
1070
1071=== modified file 'libunity-2d-private/src/launcherdevice.cpp'
1072--- libunity-2d-private/src/launcherdevice.cpp 2011-07-29 13:49:34 +0000
1073+++ libunity-2d-private/src/launcherdevice.cpp 2011-08-09 17:30:25 +0000
1074@@ -186,35 +186,65 @@
1075 }
1076
1077 void
1078+LauncherDevice::unmount(GMountOperation* mountOperation)
1079+{
1080+ if (m_volume == NULL) {
1081+ return;
1082+ }
1083+
1084+ GObjectScopedPointer<GMount> mount(g_volume_get_mount(m_volume));
1085+
1086+ if (mount.isNull()) {
1087+ return;
1088+ }
1089+
1090+ if (g_mount_can_unmount(mount.data())) {
1091+ g_mount_unmount_with_operation(mount.data(), G_MOUNT_UNMOUNT_NONE, mountOperation, NULL,
1092+ (GAsyncReadyCallback) LauncherDevice::onMountUnmounted,
1093+ NULL);
1094+ }
1095+}
1096+
1097+void
1098 LauncherDevice::eject()
1099 {
1100 if (m_volume == NULL) {
1101 return;
1102 }
1103
1104- GMountOperation *mountOperation;
1105- mountOperation = gtk_mount_operation_new(NULL);
1106+ GObjectScopedPointer<GMountOperation> mountOperation(gtk_mount_operation_new(NULL));
1107
1108 if (g_volume_can_eject(m_volume)) {
1109- g_volume_eject_with_operation(m_volume, G_MOUNT_UNMOUNT_NONE, mountOperation,
1110- NULL, (GAsyncReadyCallback) LauncherDevice::onVolumeEjected, NULL);
1111- } else {
1112- GMount* mount = g_volume_get_mount(m_volume);
1113-
1114- if (mount == NULL) {
1115- return;
1116- }
1117-
1118- if (g_mount_can_unmount(mount)) {
1119- g_mount_unmount_with_operation(mount, G_MOUNT_UNMOUNT_NONE, mountOperation,
1120- NULL, (GAsyncReadyCallback) LauncherDevice::onMountUnmounted,
1121- NULL);
1122- } else {
1123- g_object_unref(mount);
1124- }
1125- }
1126-
1127- g_object_unref(mountOperation);
1128+ g_volume_eject_with_operation(m_volume, G_MOUNT_UNMOUNT_NONE, mountOperation.data(),
1129+ NULL,
1130+ (GAsyncReadyCallback) LauncherDevice::onVolumeEjected,
1131+ NULL);
1132+ } else {
1133+ unmount(mountOperation.data());
1134+ }
1135+}
1136+
1137+void
1138+LauncherDevice::stop()
1139+{
1140+ if (m_volume == NULL) {
1141+ return;
1142+ }
1143+
1144+ GObjectScopedPointer<GDrive> drive(g_volume_get_drive(m_volume));
1145+
1146+ if (drive.isNull()) {
1147+ return;
1148+ }
1149+
1150+ GObjectScopedPointer<GMountOperation> mountOperation(gtk_mount_operation_new(NULL));
1151+
1152+ if (g_drive_can_stop(drive.data())) {
1153+ g_drive_stop(drive.data(), G_MOUNT_UNMOUNT_NONE, mountOperation.data(), NULL,
1154+ (GAsyncReadyCallback) LauncherDevice::onDriveStopped, NULL);
1155+ } else {
1156+ unmount(mountOperation.data());
1157+ }
1158 }
1159
1160 void
1161@@ -224,6 +254,12 @@
1162 }
1163
1164 void
1165+LauncherDevice::onDriveStopped(GDrive* drive, GAsyncResult* res)
1166+{
1167+ g_drive_stop_finish(drive, res, NULL);
1168+}
1169+
1170+void
1171 LauncherDevice::onMountUnmounted(GMount* mount, GAsyncResult* res)
1172 {
1173 g_mount_unmount_with_operation_finish(mount, res, NULL);
1174@@ -237,6 +273,15 @@
1175 eject->setText(u2dTr("Eject"));
1176 m_menu->addAction(eject);
1177 QObject::connect(eject, SIGNAL(triggered()), this, SLOT(onEjectTriggered()));
1178+
1179+ GObjectScopedPointer<GDrive> drive(g_volume_get_drive(m_volume));
1180+
1181+ if (!drive.isNull() && g_drive_can_stop(drive.data())) {
1182+ QAction* stop = new QAction(m_menu);
1183+ stop->setText(u2dTr("Safely remove"));
1184+ m_menu->addAction(stop);
1185+ QObject::connect(stop, SIGNAL(triggered()), this, SLOT(onStopTriggered()));
1186+ }
1187 }
1188
1189 void
1190@@ -246,4 +291,11 @@
1191 eject();
1192 }
1193
1194+void
1195+LauncherDevice::onStopTriggered()
1196+{
1197+ m_menu->hide();
1198+ stop();
1199+}
1200+
1201 #include "launcherdevice.moc"
1202
1203=== modified file 'libunity-2d-private/src/launcherdevice.h'
1204--- libunity-2d-private/src/launcherdevice.h 2011-07-29 13:49:34 +0000
1205+++ libunity-2d-private/src/launcherdevice.h 2011-08-09 17:30:25 +0000
1206@@ -51,18 +51,22 @@
1207 Q_INVOKABLE GVolume* getVolume();
1208 Q_INVOKABLE void setVolume(GVolume* volume);
1209 Q_INVOKABLE void open();
1210+ Q_INVOKABLE void unmount(GMountOperation* mountOperation);
1211 Q_INVOKABLE void eject();
1212+ Q_INVOKABLE void stop();
1213
1214 Q_INVOKABLE virtual void createMenuActions();
1215
1216 private Q_SLOTS:
1217 void onEjectTriggered();
1218+ void onStopTriggered();
1219
1220 private:
1221 GVolume* m_volume;
1222
1223 static void onVolumeMounted(GVolume* volume, GAsyncResult* res);
1224 static void onVolumeEjected(GVolume* volume, GAsyncResult* res);
1225+ static void onDriveStopped(GDrive* drive, GAsyncResult* res);
1226 static void onMountUnmounted(GMount* mount, GAsyncResult* res);
1227 };
1228
1229
1230=== modified file 'libunity-2d-private/src/launchermenu.cpp'
1231--- libunity-2d-private/src/launchermenu.cpp 2011-07-29 13:49:34 +0000
1232+++ libunity-2d-private/src/launchermenu.cpp 2011-08-09 17:30:25 +0000
1233@@ -96,6 +96,7 @@
1234 void
1235 LauncherContextualMenu::setTitle(const QString& title)
1236 {
1237+ setAccessibleName(title);
1238 m_title = title;
1239 /* Escaping ampersands so that they are not considered as keyboard
1240 accelerators. */
1241
1242=== modified file 'libunity-2d-private/src/screeninfo.cpp'
1243--- libunity-2d-private/src/screeninfo.cpp 2011-07-29 13:49:34 +0000
1244+++ libunity-2d-private/src/screeninfo.cpp 2011-08-09 17:30:25 +0000
1245@@ -1,7 +1,5 @@
1246 extern "C" {
1247-#include <libwnck/screen.h>
1248-#include <libwnck/window.h>
1249-#include <libwnck/workspace.h>
1250+#include <libwnck/libwnck.h>
1251 }
1252
1253 #include "bamf-matcher.h"
1254
1255=== modified file 'libunity-2d-private/src/unity-2d-private.pc.cmake'
1256--- libunity-2d-private/src/unity-2d-private.pc.cmake 2011-08-05 10:52:31 +0000
1257+++ libunity-2d-private/src/unity-2d-private.pc.cmake 2011-08-09 17:30:25 +0000
1258@@ -9,4 +9,4 @@
1259 Version: @VERSION@
1260 Libs: -L@LIBDIR@ -lunity-2d-private
1261 Cflags: -I@INCLUDEDIR@/unity-2d-private
1262-Requires: glib-2.0, gtk+-2.0, libwnck-1.0
1263+Requires: glib-2.0, gtk+-3.0, libwnck-3.0, pango
1264
1265=== modified file 'libunity-2d-private/src/unity2dapplication.cpp'
1266--- libunity-2d-private/src/unity2dapplication.cpp 2011-07-27 11:42:46 +0000
1267+++ libunity-2d-private/src/unity2dapplication.cpp 2011-08-09 17:30:25 +0000
1268@@ -25,14 +25,62 @@
1269
1270 // libunity-2d
1271 #include <debug_p.h>
1272+#include <gconnector.h>
1273+#include <gscopedpointer.h>
1274 #include <unity2ddebug.h>
1275
1276 // Qt
1277+#include <QFont>
1278 #include <QWindowsStyle>
1279+#include <QAccessible>
1280+#include <QAccessibleWidget>
1281+#include <QWidget>
1282
1283 // GTK
1284 #include <gtk/gtk.h>
1285-
1286+#include <pango/pango.h>
1287+
1288+///////////////////////////////
1289+class PlatformFontTracker
1290+{
1291+public:
1292+ PlatformFontTracker()
1293+ {
1294+ m_gConnector.connect(gtk_settings_get_default(), "notify::gtk-font-name",
1295+ G_CALLBACK(PlatformFontTracker::onFontChanged), this);
1296+
1297+ updateFont();
1298+ }
1299+
1300+private:
1301+ void updateFont()
1302+ {
1303+ gchar* fontName = 0;
1304+ g_object_get(gtk_settings_get_default(), "gtk-font-name", &fontName, NULL);
1305+ GScopedPointer<PangoFontDescription, pango_font_description_free> fontDescription(
1306+ pango_font_description_from_string(fontName)
1307+ );
1308+ g_free(fontName);
1309+
1310+ int size = pango_font_description_get_size(fontDescription.data());
1311+
1312+ QFont font = QFont(
1313+ pango_font_description_get_family(fontDescription.data()),
1314+ size / PANGO_SCALE
1315+ );
1316+
1317+ QApplication::setFont(font);
1318+ }
1319+
1320+ static void onFontChanged(GObject*, GParamSpec*, PlatformFontTracker* obj)
1321+ {
1322+ obj->updateFont();
1323+ }
1324+
1325+ GConnector m_gConnector;
1326+};
1327+
1328+///////////////////////////////
1329 AbstractX11EventFilter::~AbstractX11EventFilter()
1330 {
1331 Unity2dApplication* application = Unity2dApplication::instance();
1332@@ -41,6 +89,28 @@
1333 }
1334 }
1335
1336+///////////////////////////////
1337+static bool arrayContains(char** begin, char** end, const char* string)
1338+{
1339+ for (char** ptr = begin; ptr != end; ++ptr) {
1340+ if (strcmp(*ptr, string) == 0) {
1341+ return true;
1342+ }
1343+ }
1344+ return false;
1345+}
1346+
1347+QAccessibleInterface *panelFactory(const QString &classname, QObject *object)
1348+{
1349+ QAccessibleInterface *interface = 0;
1350+
1351+ if (classname == "Unity2dPanel" && object && object->isWidgetType()) {
1352+ interface = new QAccessibleWidget(static_cast<QWidget *>(object), QAccessible::ToolBar);
1353+ }
1354+
1355+ return interface;
1356+}
1357+
1358 void Unity2dApplication::earlySetup(int& argc, char** argv)
1359 {
1360 // Parts of unity-2d uses GTK so it needs to be initialized
1361@@ -61,10 +131,19 @@
1362 if(getenv("QT_GRAPHICSSYSTEM") == 0) {
1363 QApplication::setGraphicsSystem("raster");
1364 }
1365+
1366+ /* Unless style has been specified in args, set default Qt style to
1367+ * QWindowStyle to avoid loading QGtkStyle. We don't want to load QGtkStyle
1368+ * because it uses libgtk2, which causes conflicts with our gtk3 code.
1369+ */
1370+ if (!arrayContains(argv, argv + argc, "-style")) {
1371+ QApplication::setStyle(new QWindowsStyle);
1372+ }
1373 }
1374
1375 Unity2dApplication::Unity2dApplication(int& argc, char** argv)
1376 : QApplication(argc, argv)
1377+, m_platformFontTracker(new PlatformFontTracker)
1378 {
1379 /* Allow developers to run Unity 2D uninstalled by telling dconf-qt
1380 where to look for Unity 2D's schemas.
1381@@ -73,11 +152,14 @@
1382 if (!isRunningInstalled()) {
1383 qputenv("GSETTINGS_SCHEMA_DIR", unity2dDirectory().toLocal8Bit() + "/data");
1384 }
1385+
1386+ QAccessible::installFactory(panelFactory);
1387 }
1388
1389 Unity2dApplication::~Unity2dApplication()
1390 {
1391 qDeleteAll(m_x11EventFilters);
1392+ delete m_platformFontTracker;
1393 }
1394
1395 Unity2dApplication* Unity2dApplication::instance()
1396
1397=== modified file 'libunity-2d-private/src/unity2dapplication.h'
1398--- libunity-2d-private/src/unity2dapplication.h 2011-07-18 13:47:29 +0000
1399+++ libunity-2d-private/src/unity2dapplication.h 2011-08-09 17:30:25 +0000
1400@@ -27,6 +27,8 @@
1401
1402 class Unity2dApplication;
1403
1404+class PlatformFontTracker;
1405+
1406 class AbstractX11EventFilter
1407 {
1408 public:
1409@@ -65,6 +67,7 @@
1410
1411 private:
1412 QList<AbstractX11EventFilter*> m_x11EventFilters;
1413+ PlatformFontTracker* m_platformFontTracker;
1414 };
1415
1416 #endif // UNITY2DAPPLICATION_H
1417
1418=== modified file 'libunity-2d-private/src/windowinfo.cpp'
1419--- libunity-2d-private/src/windowinfo.cpp 2011-07-29 13:49:34 +0000
1420+++ libunity-2d-private/src/windowinfo.cpp 2011-08-09 17:30:25 +0000
1421@@ -14,9 +14,7 @@
1422 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1423 */
1424
1425-#include <libwnck/screen.h>
1426-#include <libwnck/window.h>
1427-#include <libwnck/workspace.h>
1428+#include <libwnck/libwnck.h>
1429
1430 #include <glib-2.0/glib.h>
1431
1432
1433=== modified file 'libunity-2d-private/src/workspacesinfo.cpp'
1434--- libunity-2d-private/src/workspacesinfo.cpp 2011-07-29 13:49:34 +0000
1435+++ libunity-2d-private/src/workspacesinfo.cpp 2011-08-09 17:30:25 +0000
1436@@ -4,9 +4,7 @@
1437 #include <debug_p.h>
1438
1439 extern "C" {
1440-#include <libwnck/screen.h>
1441-#include <libwnck/window.h>
1442-#include <libwnck/workspace.h>
1443+#include <libwnck/libwnck.h>
1444 }
1445
1446 #include <QAbstractEventDispatcher>
1447
1448=== modified file 'panel/CMakeLists.txt'
1449--- panel/CMakeLists.txt 2011-06-27 13:40:51 +0000
1450+++ panel/CMakeLists.txt 2011-08-09 17:30:25 +0000
1451@@ -1,5 +1,8 @@
1452 project(unity-2d-panel)
1453
1454+# Dependencies
1455+pkg_check_modules(UNITYCORE REQUIRED unity-core-4.0)
1456+
1457 # Source
1458 include_directories(
1459 ${libunity-2d-private_SOURCE_DIR}/src
1460@@ -8,8 +11,3 @@
1461 add_subdirectory(applets)
1462 add_subdirectory(app)
1463 add_subdirectory(tests)
1464-
1465-# Install
1466-install(DIRECTORY artwork
1467- DESTINATION ${UNITY_2D_DIR}/panel
1468- )
1469
1470=== modified file 'panel/app/CMakeLists.txt'
1471--- panel/app/CMakeLists.txt 2011-04-04 16:41:15 +0000
1472+++ panel/app/CMakeLists.txt 2011-08-09 17:30:25 +0000
1473@@ -1,7 +1,6 @@
1474 set(panel_SRCS
1475 main.cpp
1476 panelmanager.cpp
1477- unity2dstyle.cpp
1478 )
1479
1480 qt4_automoc(${panel_SRCS})
1481@@ -10,14 +9,17 @@
1482 include_directories(
1483 ${CMAKE_CURRENT_BINARY_DIR}
1484 ${CMAKE_CURRENT_SOURCE_DIR}
1485+ ${GTK_INCLUDE_DIRS}
1486 ${uqapplets_SOURCE_DIR}
1487 ${uqapplets_SOURCE_DIR}/common
1488+ ${UNITYCORE_INCLUDE_DIRS}
1489 ${libunity-2d-private_SOURCE_DIR}/src
1490 )
1491
1492 target_link_libraries(unity-2d-panel
1493 ${QT_QTGUI_LIBRARIES}
1494 ${QT_QTCORE_LIBRARIES}
1495+ ${GTK_LDFLAGS}
1496 uqapplets
1497 unity-2d-private
1498 )
1499
1500=== modified file 'panel/app/main.cpp'
1501--- panel/app/main.cpp 2011-07-18 13:47:29 +0000
1502+++ panel/app/main.cpp 2011-08-09 17:30:25 +0000
1503@@ -22,12 +22,12 @@
1504 // Local
1505 #include <config.h>
1506 #include <panelmanager.h>
1507+#include <panelstyle.h>
1508
1509 // Unity
1510 #include <gnomesessionclient.h>
1511 #include <unity2ddebug.h>
1512 #include <unity2dapplication.h>
1513-#include <unity2dstyle.h>
1514 #include <unity2dtr.h>
1515
1516 // Qt
1517@@ -54,7 +54,10 @@
1518 ThemeEngineHandler handler;
1519 Unity2dApplication::earlySetup(argc, argv);
1520 Unity2dApplication app(argc, argv);
1521- QApplication::setStyle(new Unity2dStyle);
1522+ app.setApplicationName("Unity 2D Panel");
1523+
1524+ // Instantiate a PanelStyle so that it configures QApplication
1525+ PanelStyle::instance();
1526
1527 GnomeSessionClient client(INSTALL_PREFIX "/share/applications/unity-2d-panel.desktop");
1528 client.connectToSessionManager();
1529
1530=== modified file 'panel/app/panelmanager.cpp'
1531--- panel/app/panelmanager.cpp 2011-06-12 23:01:35 +0000
1532+++ panel/app/panelmanager.cpp 2011-08-09 17:30:25 +0000
1533@@ -24,6 +24,8 @@
1534
1535 // Local
1536 #include <config.h>
1537+#include <panelstyle.h>
1538+#include <indicatorsmanager.h>
1539
1540 // Applets
1541 #include <appindicator/appindicatorapplet.h>
1542@@ -42,70 +44,56 @@
1543
1544 using namespace Unity2d;
1545
1546-static QPalette getPalette()
1547-{
1548- QPalette palette;
1549-
1550- /* Should use the panel's background provided by Unity but it turns
1551- out not to be good. It would look like:
1552-
1553- QBrush bg(QPixmap("theme:/panel_background.png"));
1554- */
1555- QBrush bg(QPixmap(unity2dDirectory() + "/panel/artwork/background.png"));
1556- palette.setBrush(QPalette::Window, bg);
1557- palette.setBrush(QPalette::Button, bg);
1558- return palette;
1559-}
1560-
1561-static QLabel* createSeparator()
1562-{
1563- QLabel* label = new QLabel;
1564- QPixmap pix(unity2dDirectory() + "/panel/artwork/divider.png");
1565- label->setPixmap(pix);
1566- label->setFixedSize(pix.size());
1567- return label;
1568-}
1569-
1570-static Unity2dPanel* instantiatePanel(int screen)
1571+static QWidget* createSeparator()
1572+{
1573+ // Just a quick-hack: homebutton is going away anyway
1574+ QWidget* widget = new QWidget;
1575+ widget->setFixedWidth(6);
1576+ return widget;
1577+}
1578+
1579+PanelManager::PanelManager(QObject* parent)
1580+: QObject(parent)
1581+{
1582+ QDesktopWidget* desktop = QApplication::desktop();
1583+ for(int i = 0; i < desktop->screenCount(); ++i) {
1584+ Unity2dPanel* panel = instantiatePanel(i);
1585+ m_panels.append(panel);
1586+ panel->show();
1587+ panel->move(desktop->screenGeometry(i).topLeft());
1588+ }
1589+ connect(desktop, SIGNAL(screenCountChanged(int)), SLOT(onScreenCountChanged(int)));
1590+}
1591+
1592+PanelManager::~PanelManager()
1593+{
1594+ qDeleteAll(m_panels);
1595+}
1596+
1597+Unity2dPanel* PanelManager::instantiatePanel(int screen)
1598 {
1599 Unity2dPanel* panel = new Unity2dPanel;
1600+ panel->setAccessibleName("Top Panel");
1601 panel->setEdge(Unity2dPanel::TopEdge);
1602- panel->setPalette(getPalette());
1603 panel->setFixedHeight(24);
1604
1605+ IndicatorsManager* indicatorsManager = new IndicatorsManager(panel);
1606+
1607 int leftmost = QApplication::desktop()->screenNumber(QPoint());
1608 if (screen == leftmost) {
1609 panel->addWidget(new HomeButtonApplet);
1610 panel->addWidget(createSeparator());
1611 }
1612- panel->addWidget(new AppNameApplet);
1613+ panel->addWidget(new AppNameApplet(indicatorsManager));
1614 if (screen == leftmost) {
1615 /* It doesn’t make sense to have more than one instance of the systray,
1616 XEmbed’ed windows can be displayed only once anyway. */
1617 panel->addWidget(new LegacyTrayApplet);
1618 }
1619- panel->addWidget(new IndicatorApplet);
1620+ panel->addWidget(new IndicatorApplet(indicatorsManager));
1621 return panel;
1622 }
1623
1624-PanelManager::PanelManager(QObject* parent)
1625- : QObject(parent)
1626-{
1627- QDesktopWidget* desktop = QApplication::desktop();
1628- for(int i = 0; i < desktop->screenCount(); ++i) {
1629- Unity2dPanel* panel = instantiatePanel(i);
1630- m_panels.append(panel);
1631- panel->show();
1632- panel->move(desktop->screenGeometry(i).topLeft());
1633- }
1634- connect(desktop, SIGNAL(screenCountChanged(int)), SLOT(onScreenCountChanged(int)));
1635-}
1636-
1637-PanelManager::~PanelManager()
1638-{
1639- qDeleteAll(m_panels);
1640-}
1641-
1642 void
1643 PanelManager::onScreenCountChanged(int newCount)
1644 {
1645
1646=== modified file 'panel/app/panelmanager.h'
1647--- panel/app/panelmanager.h 2011-04-04 16:41:15 +0000
1648+++ panel/app/panelmanager.h 2011-08-09 17:30:25 +0000
1649@@ -40,6 +40,8 @@
1650 Q_DISABLE_COPY(PanelManager)
1651 QList<Unity2dPanel*> m_panels;
1652
1653+ Unity2dPanel* instantiatePanel(int screen);
1654+
1655 private Q_SLOTS:
1656 void onScreenCountChanged(int newCount);
1657 };
1658
1659=== removed file 'panel/app/unity2dstyle.cpp'
1660--- panel/app/unity2dstyle.cpp 2011-03-28 12:16:02 +0000
1661+++ panel/app/unity2dstyle.cpp 1970-01-01 00:00:00 +0000
1662@@ -1,98 +0,0 @@
1663-/*
1664- * Plasma applet to display DBus global menu
1665- *
1666- * Copyright 2009 Canonical Ltd.
1667- *
1668- * Authors:
1669- * - Aurélien Gâteau <aurelien.gateau@canonical.com>
1670- *
1671- * This program is free software; you can redistribute it and/or modify
1672- * it under the terms of the GNU General Public License as published by
1673- * the Free Software Foundation; version 3.
1674- *
1675- * This program is distributed in the hope that it will be useful,
1676- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1677- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1678- * GNU General Public License for more details.
1679- *
1680- * You should have received a copy of the GNU General Public License
1681- * along with this program. If not, see <http://www.gnu.org/licenses/>
1682- */
1683-
1684-// Self
1685-#include "unity2dstyle.h"
1686-
1687-// Local
1688-
1689-// libunity-2d-private
1690-#include <debug_p.h>
1691-#include <keyboardmodifiersmonitor.h>
1692-
1693-// Qt
1694-#include <QGtkStyle>
1695-#include <QMenu>
1696-#include <QPainter>
1697-#include <QStyleOptionFrame>
1698-#include <QWidget>
1699-
1700-Unity2dStyle::Unity2dStyle()
1701-: QProxyStyle(new QGtkStyle)
1702-{
1703-}
1704-
1705-void Unity2dStyle::drawControl(QStyle::ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const
1706-{
1707- if (element == QStyle::CE_MenuBarItem && widget) {
1708- QStyleOptionMenuItem opt = *qstyleoption_cast<const QStyleOptionMenuItem*>(option);
1709- if (!(opt.state & QStyle::State_Enabled) && (opt.state & QStyle::State_Sunken)) {
1710- // Reset State_Sunken flag to avoid drawing a frame on a disabled menu item
1711- // See https://bugs.launchpad.net/unity-2d/+bug/717744
1712- opt.state ^= QStyle::State_Sunken;
1713- }
1714- // Skip "widget" parameter to avoid solid gray background behind the menubar items
1715- QProxyStyle::drawControl(element, &opt, painter, 0);
1716- } else if (element == QStyle::CE_MenuBarEmptyArea) {
1717- // Avoid gray borders around the menubar items
1718- } else {
1719- QProxyStyle::drawControl(element, option, painter, widget);
1720- }
1721-}
1722-
1723-int Unity2dStyle::pixelMetric(QStyle::PixelMetric metric, const QStyleOption* option, const QWidget* widget) const
1724-{
1725- if (metric == QStyle::PM_MenuBarVMargin) {
1726- // Avoid one-pixel gap above menuitem
1727- return 0;
1728- } else {
1729- return QProxyStyle::pixelMetric(metric, option, widget);
1730- }
1731-}
1732-
1733-QSize Unity2dStyle::sizeFromContents(QStyle::ContentsType type, const QStyleOption* option, const QSize& contentsSize, const QWidget* widget) const
1734-{
1735- QSize size = QProxyStyle::sizeFromContents(type, option, contentsSize, widget);
1736- if (type == QStyle::CT_MenuBarItem && widget) {
1737- // Avoid three-pixel gap below menuitem
1738- size.setHeight(widget->height());
1739- }
1740- return size;
1741-}
1742-
1743-int Unity2dStyle::styleHint(StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData) const
1744-{
1745- if (hint == QStyle::SH_UnderlineShortcut) {
1746- // The shortcut of an opened menu can be triggered without holding Alt
1747- // down, so we always show the underline. For all other widgets we only
1748- // show the underlines if alt is down.
1749- // Note that this is a bit hackish: it only works reliably if the
1750- // widget repaints itself when alt is pressed or released. For now only
1751- // the MenuBarWidget from the AppNameApplets does this.
1752- if (qobject_cast<const QMenu*>(widget)) {
1753- return true;
1754- } else {
1755- return KeyboardModifiersMonitor::instance()->keyboardModifiers() == Qt::AltModifier;
1756- }
1757- } else {
1758- return QProxyStyle::styleHint(hint, option, widget, returnData);
1759- }
1760-}
1761
1762=== removed file 'panel/app/unity2dstyle.h'
1763--- panel/app/unity2dstyle.h 2011-01-26 15:50:26 +0000
1764+++ panel/app/unity2dstyle.h 1970-01-01 00:00:00 +0000
1765@@ -1,44 +0,0 @@
1766-/*
1767- * This file is part of unity-2d
1768- *
1769- * Copyright 2010 Canonical Ltd.
1770- *
1771- * Authors:
1772- * - Aurélien Gâteau <aurelien.gateau@canonical.com>
1773- *
1774- * This program is free software; you can redistribute it and/or modify
1775- * it under the terms of the GNU General Public License as published by
1776- * the Free Software Foundation; version 3.
1777- *
1778- * This program is distributed in the hope that it will be useful,
1779- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1780- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1781- * GNU General Public License for more details.
1782- *
1783- * You should have received a copy of the GNU General Public License
1784- * along with this program. If not, see <http://www.gnu.org/licenses/>
1785- */
1786-
1787-#ifndef UNITY2DSTYLE_H
1788-#define UNITY2DSTYLE_H
1789-
1790-// Local
1791-
1792-// Qt
1793-#include <QProxyStyle>
1794-
1795-class Unity2dStyle : public QProxyStyle
1796-{
1797-public:
1798- Unity2dStyle();
1799-
1800- virtual void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget = 0) const;
1801-
1802- virtual int pixelMetric(PixelMetric metric, const QStyleOption* option = 0, const QWidget* widget = 0) const;
1803-
1804- virtual QSize sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& contentsSize, const QWidget* widget = 0) const;
1805-
1806- virtual int styleHint(StyleHint hint, const QStyleOption* option = 0, const QWidget* widget = 0, QStyleHintReturn* returnData = 0) const;
1807-};
1808-
1809-#endif /* UNITY2DSTYLE_H */
1810
1811=== modified file 'panel/applets/CMakeLists.txt'
1812--- panel/applets/CMakeLists.txt 2011-07-18 10:33:35 +0000
1813+++ panel/applets/CMakeLists.txt 2011-08-09 17:30:25 +0000
1814@@ -1,42 +1,28 @@
1815 project(uqapplets)
1816
1817-macro(read_pkg_variable cmake_var pkg pkg_var)
1818- execute_process(
1819- COMMAND pkg-config --variable=${pkg_var} ${pkg}
1820- OUTPUT_VARIABLE tmp
1821- )
1822- # Remove trailing newline from ${tmp}
1823- string(STRIP "${tmp}" ${cmake_var})
1824-endmacro(read_pkg_variable)
1825-
1826 # Dependencies
1827 include(FindPkgConfig)
1828
1829 pkg_check_modules(QTBAMF REQUIRED libqtbamf)
1830 pkg_check_modules(DBUSMENUQT REQUIRED dbusmenu-qt)
1831-pkg_check_modules(INDICATOR REQUIRED indicator)
1832-
1833-# Get indicator dirs from pkgconfig
1834-read_pkg_variable(INDICATOR_DIR indicator indicatordir)
1835-read_pkg_variable(INDICATOR_ICONS_DIR indicator iconsdir)
1836-configure_file(indicator-config.h.in indicator-config.h)
1837
1838 # Sources
1839 set(uqapplets_SRCS
1840 appindicator/appindicatorapplet.cpp
1841 appindicator/sniitem.cpp
1842 appname/appnameapplet.cpp
1843+ appname/croppedlabel.cpp
1844 appname/menubarwidget.cpp
1845- appname/registrar.cpp
1846 appname/windowhelper.cpp
1847 common/applet.cpp
1848+ common/indicatorentrywidget.cpp
1849+ common/indicatorsmanager.cpp
1850+ common/indicatorwidget.cpp
1851+ common/cairoutils.cpp
1852+ common/panelstyle.cpp
1853 homebutton/homebuttonapplet.cpp
1854 homebutton/homebutton.cpp
1855- indicator/abstractindicator.cpp
1856- indicator/datetimeindicator.cpp
1857 indicator/indicatorapplet.cpp
1858- indicator/indicatorservicemanager.cpp
1859- indicator/indicator.c
1860 legacytray/legacytrayapplet.cpp
1861 legacytray/fdoselectionmanager.cpp
1862 legacytray/fdotask.cpp
1863@@ -45,10 +31,6 @@
1864 legacytray/x11embedpainter.cpp
1865 )
1866
1867-qt4_add_dbus_adaptor(uqapplets_SRCS appname/com.canonical.AppMenu.Registrar.xml
1868- registrar.h Registrar
1869- )
1870-
1871 qt4_automoc(${uqapplets_SRCS})
1872
1873 # Build
1874@@ -58,13 +40,17 @@
1875 ${CMAKE_CURRENT_SOURCE_DIR}/common
1876 ${CMAKE_CURRENT_SOURCE_DIR}/homebutton
1877 ${CMAKE_CURRENT_SOURCE_DIR}/indicator
1878+ ${CMAKE_CURRENT_SOURCE_DIR}/unitycore
1879 ${QTBAMF_INCLUDE_DIRS}
1880+ ${QTGCONF_INCLUDE_DIRS}
1881 ${DBUSMENUQT_INCLUDE_DIRS}
1882 ${GTK_INCLUDE_DIRS}
1883- ${INDICATOR_INCLUDE_DIRS}
1884 ${WNCK_INCLUDE_DIRS}
1885 ${CMAKE_CURRENT_BINARY_DIR}
1886 ${X11_INCLUDE_DIR}
1887+ ${UNITYCORE_INCLUDE_DIRS}
1888+ ${NUXCORE_INCLUDE_DIRS}
1889+ ${PANGO_INCLUDE_DIRS}
1890 ${libunity-2d-private_SOURCE_DIR}/src
1891 )
1892
1893@@ -75,13 +61,16 @@
1894 ${QT_QTCORE_LIBRARIES}
1895 ${DBUSMENUQT_LDFLAGS}
1896 ${QTBAMF_LDFLAGS}
1897+ ${QTGCONF_LDFLAGS}
1898 ${GTK_LDFLAGS}
1899- ${INDICATOR_LDFLAGS}
1900 ${WNCK_LDFLAGS}
1901 ${X11_LIBRARIES}
1902 ${X11_Xrender_LIB}
1903 ${X11_Xcomposite_LIB}
1904 ${X11_Xdamage_LIB}
1905 ${X11_Xfixes_LIB}
1906+ ${UNITYCORE_LDFLAGS}
1907+ ${NUXCORE_LDFLAGS}
1908+ ${PANGO_LDFLAGS}
1909 unity-2d-private
1910 )
1911
1912=== modified file 'panel/applets/appname/appnameapplet.cpp'
1913--- panel/applets/appname/appnameapplet.cpp 2011-07-26 09:36:41 +0000
1914+++ panel/applets/appname/appnameapplet.cpp 2011-08-09 17:30:25 +0000
1915@@ -23,7 +23,9 @@
1916 #include "appnameapplet.h"
1917
1918 // Local
1919+#include "croppedlabel.h"
1920 #include "menubarwidget.h"
1921+#include "panelstyle.h"
1922 #include "windowhelper.h"
1923
1924 // Unity-2d
1925@@ -45,13 +47,9 @@
1926 #include <QApplication>
1927 #include <QDesktopWidget>
1928
1929-static const char* METACITY_DIR = "/usr/share/themes/Ambiance/metacity-1";
1930-
1931 static const int WINDOW_BUTTONS_RIGHT_MARGIN = 4;
1932
1933-static const int APPNAME_LABEL_LEFT_MARGIN = 12;
1934-
1935-static const int FADEOUT_WIDTH = 16;
1936+static const int APPNAME_LABEL_LEFT_MARGIN = 6;
1937
1938 namespace Unity2d
1939 {
1940@@ -59,13 +57,11 @@
1941 class WindowButton : public QAbstractButton
1942 {
1943 public:
1944- WindowButton(const QString& prefix, QWidget* parent = 0)
1945+ WindowButton(const PanelStyle::WindowButtonType& buttonType, QWidget* parent = 0)
1946 : QAbstractButton(parent)
1947- , m_prefix(prefix)
1948- , m_normalPix(loadPix("normal"))
1949- , m_hoverPix(loadPix("prelight"))
1950- , m_downPix(loadPix("pressed"))
1951+ , m_buttonType(buttonType)
1952 {
1953+ loadPixmaps();
1954 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
1955 setAttribute(Qt::WA_Hover);
1956 }
1957@@ -76,6 +72,14 @@
1958 }
1959
1960 protected:
1961+ bool event(QEvent* ev)
1962+ {
1963+ if (ev->type() == QEvent::PaletteChange) {
1964+ loadPixmaps();
1965+ }
1966+ return QAbstractButton::event(ev);
1967+ }
1968+
1969 void paintEvent(QPaintEvent*)
1970 {
1971 QPainter painter(this);
1972@@ -91,62 +95,17 @@
1973 }
1974
1975 private:
1976- QString m_prefix;
1977+ PanelStyle::WindowButtonType m_buttonType;
1978 QPixmap m_normalPix;
1979 QPixmap m_hoverPix;
1980 QPixmap m_downPix;
1981
1982- QPixmap loadPix(const QString& name)
1983- {
1984- QString path = QString("%1/%2_focused_%3.png")
1985- .arg(METACITY_DIR)
1986- .arg(m_prefix)
1987- .arg(name);
1988- return QPixmap(path);
1989- }
1990-};
1991-
1992-/**
1993- * This label makes sure minimumSizeHint() is not set. This ensures the applet
1994- * does not get wider if a window title is very long
1995- */
1996-class CroppedLabel : public QLabel
1997-{
1998-public:
1999- CroppedLabel(QWidget* parent = 0)
2000- : QLabel(parent)
2001- {}
2002-
2003- QSize minimumSizeHint() const
2004- {
2005- return QWidget::minimumSizeHint();
2006- }
2007-
2008-protected:
2009- void paintEvent(QPaintEvent* event)
2010- {
2011- QImage image(width(), height(), QImage::Format_ARGB32_Premultiplied);
2012- {
2013- QPainter painter(&image);
2014- painter.initFrom(this);
2015- painter.setCompositionMode(QPainter::CompositionMode_Source);
2016- painter.fillRect(rect(), Qt::transparent);
2017-
2018- painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
2019- painter.drawText(contentsRect(), Qt::AlignLeft | Qt::AlignVCenter, text());
2020-
2021- if (QLabel::minimumSizeHint().width() > contentsRect().width()) {
2022- // Text does not fit, fade the end
2023- painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
2024- QRect gradientRect(width() - FADEOUT_WIDTH, 0, FADEOUT_WIDTH, height());
2025- QLinearGradient gradient(gradientRect.topLeft(), gradientRect.topRight());
2026- gradient.setColorAt(0, Qt::white);
2027- gradient.setColorAt(1, Qt::transparent);
2028- painter.fillRect(gradientRect, gradient);
2029- }
2030- }
2031- QPainter painter(this);
2032- painter.drawImage(0, 0, image);
2033+ void loadPixmaps()
2034+ {
2035+ PanelStyle* style = PanelStyle::instance();
2036+ m_normalPix = style->windowButtonPixmap(m_buttonType, PanelStyle::NormalState);
2037+ m_hoverPix = style->windowButtonPixmap(m_buttonType, PanelStyle::PrelightState);
2038+ m_downPix = style->windowButtonPixmap(m_buttonType, PanelStyle::PressedState);
2039 }
2040 };
2041
2042@@ -180,9 +139,9 @@
2043 QHBoxLayout* layout = new QHBoxLayout(m_windowButtonWidget);
2044 layout->setContentsMargins(0, 0, WINDOW_BUTTONS_RIGHT_MARGIN, 0);
2045 layout->setSpacing(0);
2046- m_closeButton = new WindowButton("close");
2047- m_minimizeButton = new WindowButton("minimize");
2048- m_maximizeButton = new WindowButton("unmaximize");
2049+ m_closeButton = new WindowButton(PanelStyle::CloseWindowButton);
2050+ m_minimizeButton = new WindowButton(PanelStyle::MinimizeWindowButton);
2051+ m_maximizeButton = new WindowButton(PanelStyle::UnmaximizeWindowButton);
2052 layout->addWidget(m_closeButton);
2053 layout->addWidget(m_minimizeButton);
2054 layout->addWidget(m_maximizeButton);
2055@@ -200,10 +159,10 @@
2056 q, SLOT(updateWidgets()));
2057 }
2058
2059- void setupMenuBarWidget()
2060+ void setupMenuBarWidget(IndicatorsManager* manager)
2061 {
2062- m_menuBarWidget = new MenuBarWidget(0 /* Window menu */);
2063- QObject::connect(m_menuBarWidget, SIGNAL(menuBarClosed()),
2064+ m_menuBarWidget = new MenuBarWidget(manager);
2065+ QObject::connect(m_menuBarWidget, SIGNAL(isOpenedChanged()),
2066 q, SLOT(updateWidgets()));
2067 QObject::connect(m_menuBarWidget, SIGNAL(isEmptyChanged()),
2068 q, SLOT(updateWidgets()));
2069@@ -216,21 +175,16 @@
2070 }
2071 };
2072
2073-AppNameApplet::AppNameApplet()
2074+AppNameApplet::AppNameApplet(IndicatorsManager* indicatorsManager)
2075 : d(new AppNameAppletPrivate)
2076 {
2077 d->q = this;
2078 setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Minimum);
2079
2080- QPalette palette;
2081- palette.setColor(QPalette::WindowText, Qt::white);
2082- palette.setColor(QPalette::ButtonText, Qt::white);
2083- setPalette(palette);
2084-
2085 d->setupWindowHelper();
2086 d->setupLabel();
2087 d->setupWindowButtonWidget();
2088- d->setupMenuBarWidget();
2089+ d->setupMenuBarWidget(indicatorsManager);
2090 d->setupKeyboardModifiersMonitor();
2091
2092 QHBoxLayout* layout = new QHBoxLayout(this);
2093
2094=== modified file 'panel/applets/appname/appnameapplet.h'
2095--- panel/applets/appname/appnameapplet.h 2011-06-06 09:06:55 +0000
2096+++ panel/applets/appname/appnameapplet.h 2011-08-09 17:30:25 +0000
2097@@ -29,6 +29,8 @@
2098
2099 class QEvent;
2100
2101+class IndicatorsManager;
2102+
2103 namespace Unity2d
2104 {
2105
2106@@ -37,7 +39,7 @@
2107 {
2108 Q_OBJECT
2109 public:
2110- AppNameApplet();
2111+ AppNameApplet(IndicatorsManager*);
2112 ~AppNameApplet();
2113
2114 protected:
2115
2116=== removed file 'panel/applets/appname/com.canonical.AppMenu.Registrar.xml'
2117--- panel/applets/appname/com.canonical.AppMenu.Registrar.xml 2011-02-10 01:10:19 +0000
2118+++ panel/applets/appname/com.canonical.AppMenu.Registrar.xml 1970-01-01 00:00:00 +0000
2119@@ -1,82 +0,0 @@
2120-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
2121-<node xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
2122- <dox:d><![CDATA[
2123- @mainpage
2124-  
2125- An interface to register menus that are associated with a window in an application.  The
2126- main interface is docuemented here: @ref com::canonical::AppMenu::Registrar.
2127-     
2128- The actual menus are transported using the dbusmenu protocol which is available
2129- here: @ref com::canonical::dbusmenu.
2130- ]]></dox:d>
2131- <interface name="com.canonical.AppMenu.Registrar" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
2132- <dox:d>
2133- An interface to register a menu from an application's window to be displayed in another
2134- window.  This manages that association between XWindow Window IDs and the dbus
2135- address and object that provides the menu using the dbusmenu dbus interface.
2136- </dox:d>
2137- <method name="RegisterWindow">
2138- <dox:d><![CDATA[
2139- Associates a dbusmenu with a window
2140-      
2141- /note this method assumes that the connection from the caller is the DBus connection
2142- to use for the object.  Applications that use multiple DBus connections will need to
2143- ensure this method is called with the same connection that implmenets the object.
2144- ]]></dox:d>
2145- <arg name="windowId" type="u" direction="in">
2146- <dox:d>The XWindow ID of the window</dox:d>
2147- </arg>
2148- <arg name="menuObjectPath" type="o" direction="in">
2149- <dox:d>The object on the dbus interface implementing the dbusmenu interface</dox:d>
2150- </arg>
2151- </method>
2152- <method name="UnregisterWindow">
2153- <dox:d>
2154- A method to allow removing a window from the database. Windows will also be removed
2155- when the client drops off DBus so this is not required. It is polite though. And
2156- important for testing.
2157- </dox:d>
2158- <arg name="windowId" type="u" direction="in">
2159- <dox:d>The XWindow ID of the window</dox:d>
2160- </arg>
2161- </method>
2162- <method name="GetMenuForWindow">
2163- <dox:d>Gets the registered menu for a given window ID.</dox:d>
2164- <arg name="windowId" type="u" direction="in">
2165- <dox:d>The XWindow ID of the window to get</dox:d>
2166- </arg>
2167- <arg name="service" type="s" direction="out">
2168- <dox:d>The address of the connection on DBus (e.g. :1.23 or org.example.service)</dox:d>
2169- </arg>
2170- <arg name="menuObjectPath" type="o" direction="out">
2171- <dox:d>The path to the object which implements the com.canonical.dbusmenu interface.</dox:d>
2172- </arg>
2173- </method>
2174- <method name="GetMenus">
2175- <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MenuInfoList"/>
2176- <dox:d>Gets the information on all menus that the registrar knows about. This
2177- is useful for debugging or bringing up a new renderer.</dox:d>
2178- <arg name="menus" type="a(uso)" direction="out">
2179- <dox:d>An array of structures containing the same parameters as @GetMenuForWindow. Window ID, Service and ObjectPath.</dox:d>
2180- </arg>
2181- </method>
2182- <signal name="WindowRegistered">
2183- <dox:d>Signals when the registrar gets a new menu registered</dox:d>
2184- <arg name="windowId" type="u" direction="out">
2185- <dox:d>The XWindow ID of the window</dox:d>
2186- </arg>
2187- <arg name="service" type="s" direction="out">
2188- <dox:d>The address of the connection on DBus (e.g. :1.23 or org.example.service)</dox:d>
2189- </arg>
2190- <arg name="menuObjectPath" type="o" direction="out">
2191- <dox:d>The path to the object which implements the com.canonical.dbusmenu interface.</dox:d>
2192- </arg>
2193- </signal>
2194- <signal name="WindowUnregistered">
2195- <dox:d>Signals when the registrar removes a menu registration</dox:d>
2196- <arg name="windowId" type="u" direction="out">
2197- <dox:d>The XWindow ID of the window</dox:d>
2198- </arg>
2199- </signal>
2200- </interface>
2201-</node>
2202
2203=== added file 'panel/applets/appname/croppedlabel.cpp'
2204--- panel/applets/appname/croppedlabel.cpp 1970-01-01 00:00:00 +0000
2205+++ panel/applets/appname/croppedlabel.cpp 2011-08-09 17:30:25 +0000
2206@@ -0,0 +1,140 @@
2207+/*
2208+ * This file is part of unity-2d
2209+ *
2210+ * Copyright 2011 Canonical Ltd.
2211+ *
2212+ * Authors:
2213+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
2214+ *
2215+ * This program is free software; you can redistribute it and/or modify
2216+ * it under the terms of the GNU General Public License as published by
2217+ * the Free Software Foundation; version 3.
2218+ *
2219+ * This program is distributed in the hope that it will be useful,
2220+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2221+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2222+ * GNU General Public License for more details.
2223+ *
2224+ * You should have received a copy of the GNU General Public License
2225+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2226+ */
2227+// Self
2228+#include "croppedlabel.h"
2229+
2230+// Local
2231+#include <cairoutils.h>
2232+#include <panelstyle.h>
2233+
2234+// unity-2d
2235+#include <debug_p.h>
2236+
2237+// libqtgconf
2238+#include <gconfitem-qml-wrapper.h>
2239+
2240+// Qt
2241+#include <QImage>
2242+#include <QPainter>
2243+
2244+// GTK
2245+#include <gtk/gtk.h>
2246+
2247+static const int FADEOUT_WIDTH = 30;
2248+
2249+static const char* WINDOW_TITLE_FONT_KEY = "/apps/metacity/general/titlebar_font";
2250+
2251+CroppedLabel::CroppedLabel(QWidget* parent)
2252+: QLabel(parent)
2253+{
2254+}
2255+
2256+QSize CroppedLabel::minimumSizeHint() const
2257+{
2258+ return QWidget::minimumSizeHint();
2259+}
2260+
2261+static void paintFadeoutGradient(QImage* image)
2262+{
2263+ QPainter painter(image);
2264+ painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
2265+ QRect gradientRect(image->width() - FADEOUT_WIDTH, 0, FADEOUT_WIDTH, image->height());
2266+ QLinearGradient gradient(gradientRect.topLeft(), gradientRect.topRight());
2267+ gradient.setColorAt(0, Qt::white);
2268+ gradient.setColorAt(1, Qt::transparent);
2269+ painter.fillRect(gradientRect, gradient);
2270+}
2271+
2272+static QString getWindowTitleFontName()
2273+{
2274+ GConfItemQmlWrapper client;
2275+ client.setKey(WINDOW_TITLE_FONT_KEY);
2276+ return client.getValue().toString();
2277+}
2278+
2279+void CroppedLabel::paintEvent(QPaintEvent* event)
2280+{
2281+ // Create an image filled with background brush (to avoid subpixel hinting
2282+ // artefacts around text)
2283+ QImage image(width(), height(), QImage::Format_ARGB32_Premultiplied);
2284+ {
2285+ QPainter painter(&image);
2286+ painter.initFrom(this);
2287+ painter.eraseRect(rect());
2288+ }
2289+
2290+ // Create a pango layout
2291+ GObjectScopedPointer<PangoContext> pangoContext(gdk_pango_context_get());
2292+ GObjectScopedPointer<PangoLayout> layout(pango_layout_new(pangoContext.data()));
2293+
2294+ // Set font
2295+ QByteArray fontName = getWindowTitleFontName().toUtf8();
2296+ PangoFontDescription* desc = pango_font_description_from_string(fontName.data());
2297+ pango_layout_set_font_description(layout.data(), desc);
2298+ pango_font_description_free(desc);
2299+
2300+ // Set text
2301+ QByteArray utf8Text = text().toUtf8();
2302+ pango_layout_set_text (layout.data(), utf8Text.data(), -1);
2303+
2304+ // Get text size
2305+ int textWidth = 0;
2306+ int textHeight = 0;
2307+ pango_layout_get_pixel_size(layout.data(), &textWidth, &textHeight);
2308+
2309+ // Draw text
2310+ CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(&image));
2311+ CairoUtils::Pointer cr(cairo_create(surface.data()));
2312+
2313+ PanelStyle* style = PanelStyle::instance();
2314+ GtkStyleContext* style_context = style->styleContext();
2315+
2316+ gtk_style_context_save(style_context);
2317+
2318+ GtkWidgetPath* widget_path = gtk_widget_path_new();
2319+ gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
2320+ gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
2321+ gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget");
2322+
2323+ gtk_style_context_set_path(style_context, widget_path);
2324+ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
2325+ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
2326+
2327+ gtk_render_layout(style_context, cr.data(),
2328+ contentsRect().left(),
2329+ contentsRect().top() + (height() - textHeight) / 2,
2330+ layout.data());
2331+
2332+ gtk_widget_path_free(widget_path);
2333+
2334+ gtk_style_context_restore(style_context);
2335+
2336+ // Fade if necessary
2337+ if (textWidth > contentsRect().width()) {
2338+ paintFadeoutGradient(&image);
2339+ }
2340+
2341+ // Paint on our widget
2342+ QPainter painter(this);
2343+ painter.drawImage(0, 0, image);
2344+}
2345+
2346+#include "croppedlabel.moc"
2347
2348=== added file 'panel/applets/appname/croppedlabel.h'
2349--- panel/applets/appname/croppedlabel.h 1970-01-01 00:00:00 +0000
2350+++ panel/applets/appname/croppedlabel.h 2011-08-09 17:30:25 +0000
2351@@ -0,0 +1,45 @@
2352+/*
2353+ * This file is part of unity-2d
2354+ *
2355+ * Copyright 2011 Canonical Ltd.
2356+ *
2357+ * Authors:
2358+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
2359+ *
2360+ * This program is free software; you can redistribute it and/or modify
2361+ * it under the terms of the GNU General Public License as published by
2362+ * the Free Software Foundation; version 3.
2363+ *
2364+ * This program is distributed in the hope that it will be useful,
2365+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2366+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2367+ * GNU General Public License for more details.
2368+ *
2369+ * You should have received a copy of the GNU General Public License
2370+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2371+ */
2372+#ifndef CROPPEDLABEL_H
2373+#define CROPPEDLABEL_H
2374+
2375+// Local
2376+
2377+// Qt
2378+#include <QLabel>
2379+
2380+/**
2381+ * This label makes sure minimumSizeHint() is not set. This ensures the applet
2382+ * does not get wider if a window title is very long
2383+ */
2384+class CroppedLabel : public QLabel
2385+{
2386+ Q_OBJECT
2387+public:
2388+ CroppedLabel(QWidget* parent = 0);
2389+
2390+ QSize minimumSizeHint() const;
2391+
2392+protected:
2393+ void paintEvent(QPaintEvent*);
2394+};
2395+
2396+#endif /* CROPPEDLABEL_H */
2397
2398=== modified file 'panel/applets/appname/menubarwidget.cpp'
2399--- panel/applets/appname/menubarwidget.cpp 2011-07-26 09:36:41 +0000
2400+++ panel/applets/appname/menubarwidget.cpp 2011-08-09 17:30:25 +0000
2401@@ -20,299 +20,98 @@
2402 */
2403
2404 // Self
2405-#include "menubarwidget.h"
2406+#include <menubarwidget.h>
2407
2408 // Local
2409-#include "config.h"
2410-#include "debug_p.h"
2411-#include "keyboardmodifiersmonitor.h"
2412-#include "registrar.h"
2413-
2414-// dbusmenu-qt
2415-#include <dbusmenuimporter.h>
2416-
2417-// bamf
2418-#include <bamf-matcher.h>
2419-#include <bamf-window.h>
2420+#include <debug_p.h>
2421+#include <indicatorentrywidget.h>
2422+#include <indicatorsmanager.h>
2423
2424 // Qt
2425-#include <QActionEvent>
2426 #include <QHBoxLayout>
2427-#include <QLabel>
2428-#include <QMenuBar>
2429-#include <QTimer>
2430-
2431-class MyDBusMenuImporter : public DBusMenuImporter
2432-{
2433-public:
2434- MyDBusMenuImporter(const QString &service, const QString &path, QObject *parent)
2435- : DBusMenuImporter(service, path, parent)
2436- , m_service(service)
2437- , m_path(path)
2438- {}
2439-
2440- QString service() const { return m_service; }
2441- QString path() const { return m_path; }
2442-
2443-private:
2444- QString m_service;
2445- QString m_path;
2446-};
2447-
2448-MenuBarWidget::MenuBarWidget(QMenu* windowMenu, QWidget* parent)
2449+
2450+static const int MENU_ITEM_PADDING = 6;
2451+
2452+MenuBarWidget::MenuBarWidget(IndicatorsManager* indicatorsManager, QWidget* parent)
2453 : QWidget(parent)
2454-, m_windowMenu(windowMenu)
2455-{
2456- m_activeWinId = 0;
2457- setupRegistrar();
2458- setupMenuBar();
2459-
2460- connect(&BamfMatcher::get_default(), SIGNAL(ActiveWindowChanged(BamfWindow*, BamfWindow*)),
2461- SLOT(slotActiveWindowChanged(BamfWindow*, BamfWindow*)));
2462- /* Work around a bug in BAMF: the ActiveWindowChanged signal is not emitted
2463- for some windows that open maximized. This is for example the case of the
2464- LibreOffice startcenter. */
2465- connect(&BamfMatcher::get_default(), SIGNAL(ViewOpened(BamfView*)),
2466- SLOT(slotViewOpened()));
2467- updateActiveWinId(BamfMatcher::get_default().active_window());
2468-}
2469-
2470-void MenuBarWidget::setupRegistrar()
2471-{
2472- m_registrar = Registrar::instance();
2473- if (!m_registrar->connectToBus()) {
2474- UQ_WARNING << "could not connect registrar to DBus";
2475- }
2476-
2477- connect(m_registrar, SIGNAL(WindowRegistered(WId, const QString&, const QDBusObjectPath&)),
2478- SLOT(slotWindowRegistered(WId, const QString&, const QDBusObjectPath&)));
2479- connect(m_registrar, SIGNAL(WindowUnregistered(WId)),
2480- SLOT(slotWindowUnregistered(WId)));
2481-}
2482-
2483-void MenuBarWidget::setupMenuBar()
2484-{
2485- m_menuBar = new QMenuBar;
2486- new MenuBarClosedHelper(this);
2487-
2488- QHBoxLayout* layout = new QHBoxLayout(this);
2489- layout->setMargin(0);
2490- layout->setSpacing(0);
2491- layout->addWidget(m_menuBar);
2492- m_menuBar->setNativeMenuBar(false);
2493-
2494- m_updateMenuBarTimer = new QTimer(this);
2495- m_updateMenuBarTimer->setSingleShot(true);
2496- m_updateMenuBarTimer->setInterval(0);
2497- connect(m_updateMenuBarTimer, SIGNAL(timeout()),
2498- SLOT(updateMenuBar()));
2499-
2500- // Repaint the menubar when modifiers change so that the shortcut underline
2501- // is drawn or not
2502- connect(KeyboardModifiersMonitor::instance(), SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers)),
2503- m_menuBar, SLOT(update()));
2504-}
2505-
2506-void MenuBarWidget::slotActiveWindowChanged(BamfWindow* /*former*/, BamfWindow* current)
2507-{
2508- if (current) {
2509- updateActiveWinId(current);
2510- }
2511-}
2512-
2513-void MenuBarWidget::slotViewOpened()
2514-{
2515- BamfWindow* active = BamfMatcher::get_default().active_window();
2516- if (active != NULL) {
2517- if (active->xid() != m_activeWinId) {
2518- /* This shouldn’t be needed as BAMF should have emitted the
2519- ActiveWindowChanged signal, but it sometimes doesn’t (e.g. when
2520- LibreOffice startcenter starts automatically maximized). */
2521- updateActiveWinId(active);
2522- }
2523- }
2524-}
2525-
2526-void MenuBarWidget::slotWindowRegistered(WId wid, const QString& service, const QDBusObjectPath& menuObjectPath)
2527-{
2528- MyDBusMenuImporter* importer = new MyDBusMenuImporter(service, menuObjectPath.path(), this);
2529- delete m_importers.take(wid);
2530- m_importers.insert(wid, importer);
2531- connect(importer, SIGNAL(menuUpdated()), SLOT(slotMenuUpdated()));
2532- connect(importer, SIGNAL(actionActivationRequested(QAction*)), SLOT(slotActionActivationRequested(QAction*)));
2533- QMetaObject::invokeMethod(importer, "updateMenu", Qt::QueuedConnection);
2534-}
2535-
2536-void MenuBarWidget::slotWindowUnregistered(WId wid)
2537-{
2538- MyDBusMenuImporter* importer = m_importers.take(wid);
2539- if (importer) {
2540- importer->deleteLater();
2541- }
2542- if (wid == m_activeWinId) {
2543- m_activeWinId = 0;
2544- updateMenuBar();
2545- }
2546-}
2547-
2548-void MenuBarWidget::slotMenuUpdated()
2549-{
2550- DBusMenuImporter* importer = static_cast<DBusMenuImporter*>(sender());
2551-
2552- if (m_importers.value(m_activeWinId) == importer) {
2553- updateMenuBar();
2554- }
2555-}
2556-
2557-void MenuBarWidget::slotActionActivationRequested(QAction* action)
2558-{
2559- DBusMenuImporter* importer = static_cast<DBusMenuImporter*>(sender());
2560-
2561- if (m_importers.value(m_activeWinId) == importer) {
2562- m_menuBar->setActiveAction(action);
2563- }
2564-}
2565-
2566-QMenu* MenuBarWidget::menuForWinId(WId wid) const
2567-{
2568- MyDBusMenuImporter* importer = m_importers.value(wid);
2569- return importer ? importer->menu() : 0;
2570-}
2571-
2572-void MenuBarWidget::updateActiveWinId(BamfWindow* bamfWindow)
2573-{
2574- WId id = bamfWindow ? bamfWindow->xid() : 0;
2575- if (id == m_activeWinId) {
2576- return;
2577- }
2578- if (id == window()->winId()) {
2579- // Do not update id if the active window is the one hosting this applet
2580- return;
2581- }
2582- m_activeWinId = id;
2583- updateMenuBar();
2584-}
2585-
2586-void MenuBarWidget::updateMenuBar()
2587-{
2588- WId winId = m_activeWinId;
2589- QMenu* menu = menuForWinId(winId);
2590-
2591- if (!menu) {
2592- if (winId) {
2593- menu = m_windowMenu;
2594- } else {
2595- // No active window, show a desktop menubar
2596- // FIXME: Empty menu
2597- /*
2598- menu = mEmptyMenu;
2599- */
2600- }
2601- }
2602-
2603- m_menuBar->clear();
2604- // FIXME: Empty menu
2605- if (!menu) {
2606- return;
2607- }
2608- menu->installEventFilter(this);
2609- Q_FOREACH(QAction* action, menu->actions()) {
2610- if (action->isSeparator()) {
2611- continue;
2612- }
2613- m_menuBar->addAction(action);
2614- }
2615-}
2616-
2617-bool MenuBarWidget::eventFilter(QObject* object, QEvent* event)
2618-{
2619- switch (event->type()) {
2620- case QEvent::ActionAdded:
2621- case QEvent::ActionRemoved:
2622- case QEvent::ActionChanged:
2623- m_updateMenuBarTimer->start();
2624- break;
2625- default:
2626- break;
2627- }
2628- return false;
2629+, m_indicatorsManager(indicatorsManager)
2630+, m_layout(new QHBoxLayout(this))
2631+, m_isEmpty(true)
2632+, m_isOpened(false)
2633+{
2634+ m_layout->setMargin(0);
2635+ m_layout->setSpacing(0);
2636+ indicatorsManager->indicators()->on_object_added.connect(
2637+ sigc::mem_fun(this, &MenuBarWidget::onObjectAdded)
2638+ );
2639+ indicatorsManager->indicators()->on_entry_activated.connect(
2640+ sigc::mem_fun(this, &MenuBarWidget::onEntryActivated)
2641+ );
2642+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
2643+ m_layout->addStretch();
2644 }
2645
2646 bool MenuBarWidget::isEmpty() const
2647 {
2648- return m_menuBar->actions().isEmpty();
2649+ return m_isEmpty;
2650 }
2651
2652 bool MenuBarWidget::isOpened() const
2653 {
2654- return m_menuBar->activeAction();
2655-}
2656-
2657-// MenuBarClosedHelper ----------------------------------------
2658-MenuBarClosedHelper::MenuBarClosedHelper(MenuBarWidget* widget)
2659-: QObject(widget)
2660-, m_widget(widget)
2661-{
2662- widget->m_menuBar->installEventFilter(this);
2663-}
2664-
2665-bool MenuBarClosedHelper::eventFilter(QObject* object, QEvent* event)
2666-{
2667- if (object == m_widget->m_menuBar) {
2668- switch (event->type()) {
2669- case QEvent::ActionAdded:
2670- case QEvent::ActionRemoved:
2671- case QEvent::ActionChanged:
2672- menuBarActionEvent(static_cast<QActionEvent*>(event));
2673- break;
2674- default:
2675- break;
2676- }
2677- } else {
2678- // Top-level menus
2679- if (event->type() == QEvent::Hide) {
2680- // menu hide themselves when the menubar is closed but also when
2681- // one goes from one menu to another. The way to know this is to
2682- // check the value of QMenuBar::activeAction(), but at this point
2683- // it has not been updated yet, so we check in a delayed method.
2684- QMetaObject::invokeMethod(this, "emitMenuBarClosed", Qt::QueuedConnection);
2685- }
2686- }
2687- return false;
2688-}
2689-
2690-void MenuBarClosedHelper::emitMenuBarClosed()
2691-{
2692- if (!m_widget->m_menuBar->activeAction()) {
2693- QMetaObject::invokeMethod(m_widget, "menuBarClosed");
2694- }
2695-}
2696-
2697-void MenuBarClosedHelper::menuBarActionEvent(QActionEvent* event)
2698-{
2699- QMenu* menu = event->action()->menu();
2700- if (menu) {
2701- // Install/remove event filters on top level menus so that know when
2702- // they hide themselves and can emit menuBarClosed()
2703- switch (event->type()) {
2704- case QEvent::ActionAdded:
2705- case QEvent::ActionChanged:
2706- menu->installEventFilter(this);
2707- break;
2708- case QEvent::ActionRemoved:
2709- menu->removeEventFilter(this);
2710- break;
2711- default:
2712- break;
2713- }
2714- }
2715-
2716- // Emit isEmptyChanged() if necessary
2717- QList<QAction*> actions = m_widget->m_menuBar->actions();
2718- if (event->type() == QEvent::ActionAdded && actions.count() == 1) {
2719- QMetaObject::invokeMethod(m_widget, "isEmptyChanged");
2720- } else if (event->type() == QEvent::ActionRemoved && actions.isEmpty()) {
2721- QMetaObject::invokeMethod(m_widget, "isEmptyChanged");
2722+ return m_isOpened;
2723+}
2724+
2725+void MenuBarWidget::onObjectAdded(const unity::indicator::Indicator::Ptr& indicator)
2726+{
2727+ QString name = QString::fromStdString(indicator->name());
2728+ if (name == "libappmenu.so") {
2729+ indicator->on_entry_added.connect(sigc::mem_fun(this, &MenuBarWidget::onEntryAdded));
2730+ }
2731+}
2732+
2733+void MenuBarWidget::onEntryAdded(const unity::indicator::Entry::Ptr& entry)
2734+{
2735+ IndicatorEntryWidget* widget = new IndicatorEntryWidget(entry);
2736+ widget->setPadding(MENU_ITEM_PADDING);
2737+ connect(widget, SIGNAL(isEmptyChanged()), SLOT(updateIsEmpty()));
2738+
2739+ m_widgetList.append(widget);
2740+ m_indicatorsManager->addIndicatorEntryWidget(widget);
2741+
2742+ // Insert *before* stretch
2743+ m_layout->insertWidget(m_layout->count() - 1, widget);
2744+}
2745+
2746+void MenuBarWidget::updateIsEmpty()
2747+{
2748+ bool empty = true;
2749+ Q_FOREACH(IndicatorEntryWidget* widget, m_widgetList) {
2750+ if (!widget->isEmpty()) {
2751+ empty = false;
2752+ break;
2753+ }
2754+ }
2755+ if (m_isEmpty != empty) {
2756+ m_isEmpty = empty;
2757+ isEmptyChanged();
2758+ }
2759+}
2760+
2761+void MenuBarWidget::onEntryActivated(const std::string& id)
2762+{
2763+ bool isOpened = false;
2764+ if (!id.empty()) {
2765+ // We only cares about menubar entries
2766+ Q_FOREACH(IndicatorEntryWidget* widget, m_widgetList) {
2767+ if (widget->entry()->id() == id) {
2768+ isOpened = true;
2769+ break;
2770+ }
2771+ }
2772+ }
2773+ if (m_isOpened != isOpened) {
2774+ m_isOpened = isOpened;
2775+ isOpenedChanged();
2776 }
2777 }
2778
2779
2780=== modified file 'panel/applets/appname/menubarwidget.h'
2781--- panel/applets/appname/menubarwidget.h 2011-07-26 09:36:41 +0000
2782+++ panel/applets/appname/menubarwidget.h 2011-08-09 17:30:25 +0000
2783@@ -23,86 +23,45 @@
2784 #define MENUBARWIDGET_H
2785
2786 // Qt
2787-#include <QHash>
2788 #include <QWidget>
2789
2790-class BamfWindow;
2791-
2792-class QActionEvent;
2793-class QDBusObjectPath;
2794-class QMenu;
2795-class QMenuBar;
2796-class QTimer;
2797-
2798-class MyDBusMenuImporter;
2799-class Registrar;
2800-
2801-typedef QHash<WId, MyDBusMenuImporter*> ImporterForWId;
2802-
2803-class MenuBarWidget;
2804-
2805-/**
2806- * An helper class which monitors the menubar and emits MenuBarWidget::menuBarClosed()
2807- * when necessary
2808- */
2809-class MenuBarClosedHelper : public QObject
2810-{
2811-Q_OBJECT
2812-public:
2813- MenuBarClosedHelper(MenuBarWidget*);
2814-
2815-protected:
2816- bool eventFilter(QObject*, QEvent*); //reimp
2817-
2818-private Q_SLOTS:
2819- void emitMenuBarClosed();
2820-
2821-private:
2822- MenuBarWidget* m_widget;
2823- void menuBarActionEvent(QActionEvent*);
2824-};
2825-
2826-class MenuBarWidget : public QWidget
2827-{
2828-Q_OBJECT
2829-public:
2830- MenuBarWidget(QMenu* windowMenu, QWidget* parent = 0);
2831+// libunity-core
2832+#include <UnityCore/Indicator.h>
2833+#include <UnityCore/IndicatorEntry.h>
2834+
2835+class QHBoxLayout;
2836+
2837+class IndicatorEntryWidget;
2838+class IndicatorsManager;
2839+
2840+class MenuBarWidget : public QWidget, public sigc::trackable
2841+{
2842+Q_OBJECT
2843+public:
2844+ MenuBarWidget(IndicatorsManager*, QWidget* parent = 0);
2845
2846 bool isEmpty() const;
2847 bool isOpened() const;
2848
2849 Q_SIGNALS:
2850- void menuBarClosed();
2851+ void isOpenedChanged();
2852 void isEmptyChanged();
2853
2854-protected:
2855- bool eventFilter(QObject*, QEvent*); // reimp
2856-
2857 private Q_SLOTS:
2858- void slotActiveWindowChanged(BamfWindow*, BamfWindow*);
2859- void slotViewOpened();
2860- void slotWindowRegistered(WId, const QString& service, const QDBusObjectPath& menuObjectPath);
2861- void slotWindowUnregistered(WId);
2862- void slotMenuUpdated();
2863- void slotActionActivationRequested(QAction* action);
2864- void updateMenuBar();
2865+ void updateIsEmpty();
2866
2867 private:
2868 Q_DISABLE_COPY(MenuBarWidget)
2869
2870- QMenuBar* m_menuBar;
2871- Registrar* m_registrar;
2872- ImporterForWId m_importers;
2873- WId m_activeWinId;
2874- QMenu* m_windowMenu;
2875- QTimer* m_updateMenuBarTimer;
2876-
2877- void setupRegistrar();
2878- void setupMenuBar();
2879- QMenu* menuForWinId(WId) const;
2880- void updateActiveWinId(BamfWindow*);
2881-
2882- friend class MenuBarClosedHelper;
2883+ IndicatorsManager* m_indicatorsManager;
2884+ QHBoxLayout* m_layout;
2885+ bool m_isEmpty;
2886+ bool m_isOpened;
2887+ QList<IndicatorEntryWidget*> m_widgetList;
2888+
2889+ void onObjectAdded(const unity::indicator::Indicator::Ptr&);
2890+ void onEntryAdded(const unity::indicator::Entry::Ptr&);
2891+ void onEntryActivated(const std::string&);
2892 };
2893
2894 #endif /* MENUBARWIDGET_H */
2895
2896=== removed file 'panel/applets/appname/registrar.cpp'
2897--- panel/applets/appname/registrar.cpp 2011-04-04 16:46:14 +0000
2898+++ panel/applets/appname/registrar.cpp 1970-01-01 00:00:00 +0000
2899@@ -1,138 +0,0 @@
2900-/*
2901- * Plasma applet to display application window menus
2902- *
2903- * Copyright 2010 Canonical Ltd.
2904- *
2905- * Authors:
2906- * - Aurélien Gâteau <aurelien.gateau@canonical.com>
2907- *
2908- * This program is free software; you can redistribute it and/or modify
2909- * it under the terms of the GNU General Public License as published by
2910- * the Free Software Foundation; version 3.
2911- *
2912- * This program is distributed in the hope that it will be useful,
2913- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2914- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2915- * GNU General Public License for more details.
2916- *
2917- * You should have received a copy of the GNU General Public License
2918- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2919- */
2920-
2921-// Self
2922-#include "registrar.h"
2923-
2924-// Qt
2925-#include <QApplication>
2926-#include <QDBusMessage>
2927-#include <QDBusObjectPath>
2928-#include <QDBusServiceWatcher>
2929-
2930-// Local
2931-#include "registraradaptor.h"
2932-
2933-static const char* DBUS_SERVICE = "com.canonical.AppMenu.Registrar";
2934-static const char* DBUS_OBJECT_PATH = "/com/canonical/AppMenu/Registrar";
2935-
2936-// Marshalling code for MenuInfo
2937-QDBusArgument& operator<<(QDBusArgument& argument, const MenuInfo& info)
2938-{
2939- argument.beginStructure();
2940- argument << info.winId << info.service << info.path;
2941- argument.endStructure();
2942- return argument;
2943-}
2944-
2945-const QDBusArgument& operator>>(const QDBusArgument& argument, MenuInfo& info)
2946-{
2947- argument.beginStructure();
2948- argument >> info.winId >> info.service >> info.path;
2949- argument.endStructure();
2950- return argument;
2951-}
2952-
2953-Registrar::Registrar()
2954-: QObject()
2955-, mServiceWatcher(new QDBusServiceWatcher(this))
2956-{
2957- qDBusRegisterMetaType<MenuInfo>();
2958- qDBusRegisterMetaType<MenuInfoList>();
2959- mServiceWatcher->setConnection(QDBusConnection::sessionBus());
2960- mServiceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
2961- connect(mServiceWatcher, SIGNAL(serviceUnregistered(const QString&)), SLOT(slotServiceUnregistered(const QString&)));
2962-}
2963-
2964-Registrar::~Registrar()
2965-{
2966- QDBusConnection::sessionBus().unregisterService(mService);
2967-}
2968-
2969-Registrar* Registrar::instance()
2970-{
2971- static Registrar singleton;
2972- return &singleton;
2973-}
2974-
2975-bool Registrar::connectToBus(const QString& _service, const QString& _path)
2976-{
2977- mService = _service.isEmpty() ? DBUS_SERVICE : _service;
2978- QString path = _path.isEmpty() ? DBUS_OBJECT_PATH : _path;
2979-
2980- bool ok = QDBusConnection::sessionBus().registerService(mService);
2981- if (!ok) {
2982- return false;
2983- }
2984- new RegistrarAdaptor(this);
2985- QDBusConnection::sessionBus().registerObject(path, this);
2986-
2987- return true;
2988-}
2989-
2990-void Registrar::RegisterWindow(WId wid, const QDBusObjectPath& menuObjectPath)
2991-{
2992- MenuInfo info;
2993- info.winId = wid;
2994- info.service = message().service();
2995- info.path = menuObjectPath;
2996- mDb.insert(wid, info);
2997- mServiceWatcher->addWatchedService(info.service);
2998- WindowRegistered(wid, info.service, info.path);
2999-}
3000-
3001-void Registrar::UnregisterWindow(WId wid)
3002-{
3003- mDb.remove(wid);
3004- WindowUnregistered(wid);
3005-}
3006-
3007-QString Registrar::GetMenuForWindow(WId winId, QDBusObjectPath& menuObjectPath)
3008-{
3009- MenuInfo info = mDb.value(winId);
3010- QString service = info.service;
3011- menuObjectPath = info.path;
3012- return service;
3013-}
3014-
3015-MenuInfoList Registrar::GetMenus()
3016-{
3017- return mDb.values();
3018-}
3019-
3020-void Registrar::slotServiceUnregistered(const QString& service)
3021-{
3022- MenuInfoDb::Iterator
3023- it = mDb.begin(),
3024- end = mDb.end();
3025- for (;it != end;) {
3026- if (it.value().service == service) {
3027- WId id = it.key();
3028- it = mDb.erase(it);
3029- WindowUnregistered(id);
3030- } else {
3031- ++it;
3032- }
3033- }
3034- mServiceWatcher->removeWatchedService(service);
3035-}
3036-
3037-#include "registrar.moc"
3038
3039=== removed file 'panel/applets/appname/registrar.h'
3040--- panel/applets/appname/registrar.h 2011-04-04 16:47:28 +0000
3041+++ panel/applets/appname/registrar.h 1970-01-01 00:00:00 +0000
3042@@ -1,85 +0,0 @@
3043-/*
3044- * Plasma applet to display application window menus
3045- *
3046- * Copyright 2010 Canonical Ltd.
3047- *
3048- * Authors:
3049- * - Aurélien Gâteau <aurelien.gateau@canonical.com>
3050- *
3051- * This program is free software; you can redistribute it and/or modify
3052- * it under the terms of the GNU General Public License as published by
3053- * the Free Software Foundation; version 3.
3054- *
3055- * This program is distributed in the hope that it will be useful,
3056- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3057- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3058- * GNU General Public License for more details.
3059- *
3060- * You should have received a copy of the GNU General Public License
3061- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3062- */
3063-
3064-#ifndef REGISTRAR_H
3065-#define REGISTRAR_H
3066-
3067-// Qt
3068-#include <QDBusContext>
3069-#include <QDBusObjectPath>
3070-#include <QObject>
3071-#include <QWidget> // For WId
3072-
3073-class QDBusObjectPath;
3074-class QDBusServiceWatcher;
3075-class QMenu;
3076-
3077-struct MenuInfo
3078-{
3079- MenuInfo()
3080- : winId(0)
3081- , path("/")
3082- {}
3083-
3084- uint winId;
3085- QString service;
3086- QDBusObjectPath path;
3087-};
3088-Q_DECLARE_METATYPE(MenuInfo)
3089-
3090-typedef QList<MenuInfo> MenuInfoList;
3091-Q_DECLARE_METATYPE(MenuInfoList)
3092-
3093-class Registrar : public QObject, protected QDBusContext
3094-{
3095- Q_OBJECT
3096-
3097-public:
3098- /* The registrar is a singleton shared between all instances of MenuBarWidget. */
3099- static Registrar* instance();
3100-
3101- bool connectToBus(const QString& service = QString(), const QString& objectPath = QString());
3102-
3103-Q_SIGNALS:
3104- void WindowRegistered(WId wid, const QString& service, const QDBusObjectPath&);
3105- void WindowUnregistered(WId wid);
3106-
3107-public Q_SLOTS:
3108- Q_NOREPLY void RegisterWindow(WId wid, const QDBusObjectPath& menuObjectPath);
3109- Q_NOREPLY void UnregisterWindow(WId wid);
3110- QString GetMenuForWindow(WId wid, QDBusObjectPath& menuObjectPath);
3111- MenuInfoList GetMenus();
3112-
3113-private Q_SLOTS:
3114- void slotServiceUnregistered(const QString& service);
3115-
3116-private:
3117- Registrar();
3118- Q_DISABLE_COPY(Registrar)
3119- ~Registrar();
3120-
3121- QDBusServiceWatcher* mServiceWatcher;
3122- typedef QHash<WId, MenuInfo> MenuInfoDb;
3123- MenuInfoDb mDb;
3124- QString mService;
3125-};
3126-
3127-#endif /* REGISTRAR_H */
3128
3129=== added file 'panel/applets/common/cairoutils.cpp'
3130--- panel/applets/common/cairoutils.cpp 1970-01-01 00:00:00 +0000
3131+++ panel/applets/common/cairoutils.cpp 2011-08-09 17:30:25 +0000
3132@@ -0,0 +1,42 @@
3133+/*
3134+ * This file is part of unity-2d
3135+ *
3136+ * Copyright 2011 Canonical Ltd.
3137+ *
3138+ * Authors:
3139+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
3140+ *
3141+ * This program is free software; you can redistribute it and/or modify
3142+ * it under the terms of the GNU General Public License as published by
3143+ * the Free Software Foundation; version 3.
3144+ *
3145+ * This program is distributed in the hope that it will be useful,
3146+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3147+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3148+ * GNU General Public License for more details.
3149+ *
3150+ * You should have received a copy of the GNU General Public License
3151+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3152+ */
3153+// Self
3154+#include "cairoutils.h"
3155+
3156+// Local
3157+
3158+// Qt
3159+#include <QImage>
3160+
3161+namespace CairoUtils {
3162+
3163+cairo_surface_t* createSurfaceForQImage(QImage* image)
3164+{
3165+ return cairo_image_surface_create_for_data(
3166+ image->bits(),
3167+ CAIRO_FORMAT_ARGB32,
3168+ image->width(),
3169+ image->height(),
3170+ image->bytesPerLine()
3171+ );
3172+}
3173+
3174+} // namespace
3175
3176=== added file 'panel/applets/common/cairoutils.h'
3177--- panel/applets/common/cairoutils.h 1970-01-01 00:00:00 +0000
3178+++ panel/applets/common/cairoutils.h 2011-08-09 17:30:25 +0000
3179@@ -0,0 +1,47 @@
3180+/*
3181+ * This file is part of unity-2d
3182+ *
3183+ * Copyright 2011 Canonical Ltd.
3184+ *
3185+ * Authors:
3186+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
3187+ *
3188+ * This program is free software; you can redistribute it and/or modify
3189+ * it under the terms of the GNU General Public License as published by
3190+ * the Free Software Foundation; version 3.
3191+ *
3192+ * This program is distributed in the hope that it will be useful,
3193+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3194+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3195+ * GNU General Public License for more details.
3196+ *
3197+ * You should have received a copy of the GNU General Public License
3198+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3199+ */
3200+#ifndef CAIROUTILS_H
3201+#define CAIROUTILS_H
3202+
3203+// Local
3204+#include <gscopedpointer.h>
3205+
3206+// Qt
3207+
3208+// Cairo
3209+#include <cairo.h>
3210+
3211+class QImage;
3212+
3213+namespace CairoUtils {
3214+
3215+typedef GScopedPointer<cairo_surface_t, cairo_surface_destroy> SurfacePointer;
3216+typedef GScopedPointer<cairo_t, cairo_destroy> Pointer;
3217+
3218+/**
3219+ * Creates a Cairo surface for a QImage.
3220+ * QImage format must be Format_ARGB32_Premultiplied.
3221+ */
3222+cairo_surface_t* createSurfaceForQImage(QImage*);
3223+
3224+} // namespace
3225+
3226+#endif /* CAIROUTILS_H */
3227
3228=== added file 'panel/applets/common/indicatorentrywidget.cpp'
3229--- panel/applets/common/indicatorentrywidget.cpp 1970-01-01 00:00:00 +0000
3230+++ panel/applets/common/indicatorentrywidget.cpp 2011-08-09 17:30:25 +0000
3231@@ -0,0 +1,374 @@
3232+/*
3233+ * This file is part of unity-2d
3234+ *
3235+ * Copyright 2011 Canonical Ltd.
3236+ *
3237+ * Authors:
3238+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
3239+ *
3240+ * This program is free software; you can redistribute it and/or modify
3241+ * it under the terms of the GNU General Public License as published by
3242+ * the Free Software Foundation; version 3.
3243+ *
3244+ * This program is distributed in the hope that it will be useful,
3245+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3246+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3247+ * GNU General Public License for more details.
3248+ *
3249+ * You should have received a copy of the GNU General Public License
3250+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3251+ */
3252+// Self
3253+#include "indicatorentrywidget.h"
3254+
3255+// Local
3256+#include <cairoutils.h>
3257+#include <debug_p.h>
3258+#include <gscopedpointer.h>
3259+#include <gimageutils.h>
3260+#include <panelstyle.h>
3261+
3262+// Qt
3263+#include <QIcon>
3264+#include <QPainter>
3265+#include <QWheelEvent>
3266+
3267+// GTK
3268+#include <gtk/gtk.h>
3269+
3270+// libc
3271+#include <time.h>
3272+
3273+static const int SPACING = 3;
3274+static const int PADDING = 3;
3275+static const int ICON_SIZE = 22;
3276+
3277+using namespace unity::indicator;
3278+
3279+IndicatorEntryWidget::IndicatorEntryWidget(const Entry::Ptr& entry)
3280+: m_entry(entry)
3281+, m_padding(PADDING)
3282+, m_hasIcon(false)
3283+, m_hasLabel(false)
3284+, m_gtkWidgetPath(gtk_widget_path_new())
3285+{
3286+ gtk_widget_path_append_type(m_gtkWidgetPath, GTK_TYPE_WINDOW);
3287+ gtk_widget_path_iter_set_name(m_gtkWidgetPath, -1 , "UnityPanelWidget");
3288+ gtk_widget_path_append_type(m_gtkWidgetPath, GTK_TYPE_MENU_BAR);
3289+ gtk_widget_path_append_type(m_gtkWidgetPath, GTK_TYPE_MENU_ITEM);
3290+
3291+ setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
3292+ m_entry->updated.connect(sigc::mem_fun(this, &IndicatorEntryWidget::updatePix));
3293+}
3294+
3295+IndicatorEntryWidget::~IndicatorEntryWidget()
3296+{
3297+ gtk_widget_path_free(m_gtkWidgetPath);
3298+}
3299+
3300+QSize IndicatorEntryWidget::minimumSizeHint() const
3301+{
3302+ return sizeHint();
3303+}
3304+
3305+QSize IndicatorEntryWidget::sizeHint() const
3306+{
3307+ return m_pix.size();
3308+}
3309+
3310+void IndicatorEntryWidget::resizeEvent(QResizeEvent* event)
3311+{
3312+ QWidget::resizeEvent(event);
3313+ updatePix();
3314+}
3315+
3316+void IndicatorEntryWidget::paintEvent(QPaintEvent*)
3317+{
3318+ if (!m_pix.isNull()) {
3319+ QPainter painter(this);
3320+ painter.drawPixmap(0, 0, m_pix);
3321+ }
3322+}
3323+
3324+
3325+void IndicatorEntryWidget::paintActiveBackground(QImage* image)
3326+{
3327+ // This code should be kept in sync with corresponding unityshell code from
3328+ // plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp
3329+
3330+ // Get a surface and a context
3331+ CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(image));
3332+ CairoUtils::Pointer cr(cairo_create(surface.data()));
3333+
3334+ // Init style
3335+ GtkStyleContext* styleContext = PanelStyle::instance()->styleContext();
3336+
3337+ gtk_style_context_save(styleContext);
3338+
3339+ gtk_style_context_set_path(styleContext, m_gtkWidgetPath);
3340+ gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUBAR);
3341+ gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUITEM);
3342+ gtk_style_context_set_state(styleContext, GTK_STATE_FLAG_PRELIGHT);
3343+
3344+ // Draw
3345+ // FIXME(Cimi) probably some padding is needed here.
3346+ gtk_render_background(styleContext, cr.data(), 0, 0, width(), height());
3347+ gtk_render_frame(styleContext, cr.data(), 0, 0, width(), height());
3348+
3349+ // Clean up
3350+ gtk_style_context_restore(styleContext);
3351+}
3352+
3353+void IndicatorEntryWidget::updatePix()
3354+{
3355+ bool oldIsEmpty = isEmpty();
3356+
3357+ int width = m_padding;
3358+ int iconX = m_padding;
3359+ int labelX = 0;
3360+
3361+ GObjectScopedPointer<PangoLayout> pangoLayout;
3362+
3363+ // Compute width, labelX and update m_has{Icon,Label}
3364+ QPixmap iconPix;
3365+ if (m_entry->image_visible()) {
3366+ iconPix = decodeIcon();
3367+ m_hasIcon = !iconPix.isNull();
3368+ } else {
3369+ m_hasIcon = false;
3370+ }
3371+ if (m_hasIcon) {
3372+ width += iconPix.width();
3373+ }
3374+
3375+ m_hasLabel = !m_entry->label().empty() && m_entry->label_visible();
3376+ if (m_hasLabel) {
3377+ if (m_hasIcon) {
3378+ width += SPACING;
3379+ }
3380+ labelX = width;
3381+ pangoLayout.reset(createPangoLayout());
3382+ int labelWidth;
3383+ int labelHeight;
3384+ pango_layout_get_pixel_size(pangoLayout.data(), &labelWidth, &labelHeight);
3385+
3386+ width += labelWidth;
3387+ }
3388+
3389+ width += m_padding;
3390+
3391+ // Paint
3392+ QPixmap oldPix = m_pix;
3393+ if (!m_hasIcon && !m_hasLabel) {
3394+ m_pix = QPixmap();
3395+ } else {
3396+ QImage img(width, height(), QImage::Format_ARGB32_Premultiplied);
3397+ QPainter painter(&img);
3398+ painter.initFrom(this);
3399+ painter.eraseRect(img.rect());
3400+ if (m_entry->active()) {
3401+ paintActiveBackground(&img);
3402+ }
3403+ if (m_hasIcon) {
3404+ bool disabled = !m_entry->image_sensitive();
3405+ if (disabled) {
3406+ painter.setOpacity(0.5);
3407+ }
3408+ painter.drawPixmap(iconX, (height() - iconPix.height()) / 2, iconPix);
3409+ if (disabled) {
3410+ painter.setOpacity(1);
3411+ }
3412+ }
3413+ if (m_hasLabel) {
3414+ paintLabel(&img, pangoLayout.data(), labelX);
3415+ }
3416+ m_pix = QPixmap::fromImage(img);
3417+ }
3418+
3419+ // Notify others we changed, but only trigger a layout update if necessary
3420+ if (m_pix.size() == oldPix.size()) {
3421+ update();
3422+ } else {
3423+ updateGeometry();
3424+ }
3425+ bool newIsEmpty = isEmpty();
3426+ if (newIsEmpty != oldIsEmpty) {
3427+ // If we emit isEmptyChanged() directly it won't reach any connected
3428+ // slot. I assume this is because this method is called as a response
3429+ // to a sigc++ signal.
3430+ QMetaObject::invokeMethod(this, "isEmptyChanged", Qt::QueuedConnection);
3431+ }
3432+}
3433+
3434+PangoLayout* IndicatorEntryWidget::createPangoLayout()
3435+{
3436+ // Parse
3437+ PangoAttrList* attrs = NULL;
3438+ if (m_entry->show_now()) {
3439+ if (!pango_parse_markup(m_entry->label().c_str(),
3440+ -1,
3441+ '_',
3442+ &attrs,
3443+ NULL,
3444+ NULL,
3445+ NULL))
3446+ {
3447+ UQ_WARNING << "pango_parse_markup failed";
3448+ }
3449+ }
3450+
3451+ // Create layout
3452+ GObjectScopedPointer<PangoContext> pangoContext(gdk_pango_context_get());
3453+ PangoLayout* layout = pango_layout_new(pangoContext.data());
3454+
3455+ if (attrs) {
3456+ pango_layout_set_attributes(layout, attrs);
3457+ pango_attr_list_unref(attrs);
3458+ }
3459+
3460+ // Set font
3461+ char* font_description = NULL;
3462+ GtkSettings *settings = gtk_settings_get_default();
3463+ g_object_get(settings,
3464+ "gtk-font-name", &font_description,
3465+ NULL);
3466+ PangoFontDescription* desc = pango_font_description_from_string(font_description);
3467+ pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL);
3468+ pango_layout_set_font_description(layout, desc);
3469+ pango_font_description_free(desc);
3470+ g_free(font_description);
3471+
3472+ // Set text
3473+ QString label = QString::fromUtf8(m_entry->label().c_str());
3474+ label.replace('_', QString());
3475+ QByteArray utf8Label = label.toUtf8();
3476+ pango_layout_set_text(layout, utf8Label.data(), -1);
3477+
3478+ return layout;
3479+}
3480+
3481+void IndicatorEntryWidget::paintLabel(QImage* image, PangoLayout* layout, int labelX)
3482+{
3483+ // This code should be kept in sync with corresponding unityshell code from
3484+ // plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp
3485+ int labelWidth, labelHeight;
3486+ pango_layout_get_pixel_size(layout, &labelWidth, &labelHeight);
3487+ CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(image));
3488+ CairoUtils::Pointer cr(cairo_create(surface.data()));
3489+ pango_cairo_update_layout(cr.data(), layout);
3490+
3491+ PanelStyle* style = PanelStyle::instance();
3492+ GtkStyleContext* styleContext = style->styleContext();
3493+
3494+ gtk_style_context_save(styleContext);
3495+
3496+ gtk_style_context_set_path(styleContext, m_gtkWidgetPath);
3497+ gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUBAR);
3498+ gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUITEM);
3499+
3500+ if (m_entry->active()) {
3501+ gtk_style_context_set_state(styleContext, GTK_STATE_FLAG_PRELIGHT);
3502+ }
3503+
3504+ gtk_render_layout(styleContext, cr.data(), labelX, (image->height() - labelHeight) / 2, layout);
3505+ gtk_style_context_restore(styleContext);
3506+}
3507+
3508+QPixmap IndicatorEntryWidget::decodeIcon()
3509+{
3510+ QPixmap pix;
3511+
3512+ int type = m_entry->image_type();
3513+
3514+ if (type == 0) {
3515+ // No icon
3516+ } else if (type == GTK_IMAGE_PIXBUF) {
3517+ QByteArray data = QByteArray::fromBase64(m_entry->image_data().c_str());
3518+ QImage image;
3519+ bool ok = image.loadFromData(data);
3520+ if (ok) {
3521+ pix = QPixmap::fromImage(image);
3522+ } else {
3523+ UQ_WARNING << "Failed to decode image";
3524+ }
3525+ } else if (type == GTK_IMAGE_ICON_NAME) {
3526+ QString name = QString::fromStdString(m_entry->image_data());
3527+ QIcon icon = QIcon::fromTheme(name);
3528+ pix = icon.pixmap(ICON_SIZE, ICON_SIZE);
3529+ } else if (type == GTK_IMAGE_GICON) {
3530+ QString name = QString::fromStdString(m_entry->image_data());
3531+ QImage image = GImageUtils::imageForIconString(name, ICON_SIZE);
3532+ if (image.isNull()) {
3533+ UQ_WARNING << "Failed to load icon from" << name;
3534+ return QPixmap();
3535+ }
3536+ return QPixmap::fromImage(image);
3537+ } else {
3538+ UQ_WARNING << "Unknown image type" << m_entry->image_type();
3539+ }
3540+ return pix;
3541+}
3542+
3543+void IndicatorEntryWidget::mousePressEvent(QMouseEvent*)
3544+{
3545+ UQ_RETURN_IF_FAIL(m_hasIcon || m_hasLabel);
3546+ showMenu(Qt::LeftButton);
3547+}
3548+
3549+void IndicatorEntryWidget::mouseReleaseEvent(QMouseEvent*)
3550+{
3551+ UQ_VAR(this);
3552+ update();
3553+}
3554+
3555+void IndicatorEntryWidget::wheelEvent(QWheelEvent* event)
3556+{
3557+ m_entry->Scroll(event->delta());
3558+}
3559+
3560+void IndicatorEntryWidget::showMenu(Qt::MouseButton qtButton)
3561+{
3562+ if (m_entry->active()) {
3563+ return;
3564+ }
3565+ int nuxButton = qtButton == Qt::NoButton ? 0 : 1;
3566+ QPoint pos = mapToGlobal(rect().bottomLeft());
3567+ m_entry->ShowMenu(pos.x(), pos.y(),
3568+ time(NULL),
3569+ nuxButton
3570+ );
3571+}
3572+
3573+void IndicatorEntryWidget::setPadding(int padding)
3574+{
3575+ if (m_padding != padding) {
3576+ m_padding = padding;
3577+ updatePix();
3578+ }
3579+}
3580+
3581+bool IndicatorEntryWidget::event(QEvent* ev)
3582+{
3583+ bool ret = QWidget::event(ev);
3584+ switch (ev->type()) {
3585+ case QEvent::FontChange:
3586+ case QEvent::PaletteChange:
3587+ updatePix();
3588+ break;
3589+ default:
3590+ break;
3591+ }
3592+ return ret;
3593+}
3594+
3595+bool IndicatorEntryWidget::isEmpty() const
3596+{
3597+ return !m_hasIcon && !m_hasLabel;
3598+}
3599+
3600+unity::indicator::Entry::Ptr IndicatorEntryWidget::entry() const
3601+{
3602+ return m_entry;
3603+}
3604+
3605+#include "indicatorentrywidget.moc"
3606
3607=== added file 'panel/applets/common/indicatorentrywidget.h'
3608--- panel/applets/common/indicatorentrywidget.h 1970-01-01 00:00:00 +0000
3609+++ panel/applets/common/indicatorentrywidget.h 2011-08-09 17:30:25 +0000
3610@@ -0,0 +1,90 @@
3611+/*
3612+ * This file is part of unity-2d
3613+ *
3614+ * Copyright 2011 Canonical Ltd.
3615+ *
3616+ * Authors:
3617+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
3618+ *
3619+ * This program is free software; you can redistribute it and/or modify
3620+ * it under the terms of the GNU General Public License as published by
3621+ * the Free Software Foundation; version 3.
3622+ *
3623+ * This program is distributed in the hope that it will be useful,
3624+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3625+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3626+ * GNU General Public License for more details.
3627+ *
3628+ * You should have received a copy of the GNU General Public License
3629+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3630+ */
3631+#ifndef INDICATORENTRYWIDGET_H
3632+#define INDICATORENTRYWIDGET_H
3633+
3634+// Local
3635+
3636+// libunity-core
3637+#include <UnityCore/IndicatorEntry.h>
3638+
3639+// Qt
3640+#include <QWidget>
3641+
3642+struct _GtkWidgetPath;
3643+struct _PangoLayout;
3644+
3645+class QPainter;
3646+
3647+class IndicatorEntryWidget : public QWidget, public sigc::trackable
3648+{
3649+Q_OBJECT
3650+public:
3651+ IndicatorEntryWidget(const unity::indicator::Entry::Ptr& entry);
3652+ ~IndicatorEntryWidget();
3653+
3654+ QSize minimumSizeHint() const;
3655+ QSize sizeHint() const;
3656+
3657+ void setPadding(int);
3658+
3659+ bool isEmpty() const;
3660+
3661+ unity::indicator::Entry::Ptr entry() const;
3662+
3663+ /**
3664+ * Shows the menu.
3665+ *
3666+ * When this method is called because of a click, button
3667+ * must be set to Qt::LeftButton.
3668+ *
3669+ * When it is called because user previously clicked an indicator and moved the
3670+ * mouse to another indicator, button must be set to Qt::NoButton.
3671+ */
3672+ void showMenu(Qt::MouseButton button);
3673+
3674+Q_SIGNALS:
3675+ void isEmptyChanged();
3676+
3677+protected:
3678+ void resizeEvent(QResizeEvent*);
3679+ void paintEvent(QPaintEvent*);
3680+ void mousePressEvent(QMouseEvent*);
3681+ void mouseReleaseEvent(QMouseEvent*);
3682+ void wheelEvent(QWheelEvent*);
3683+ bool event(QEvent*);
3684+
3685+private:
3686+ unity::indicator::Entry::Ptr m_entry;
3687+ QPixmap m_pix;
3688+ int m_padding;
3689+ bool m_hasIcon;
3690+ bool m_hasLabel;
3691+ struct _GtkWidgetPath* m_gtkWidgetPath;
3692+ void updatePix();
3693+ QPixmap decodeIcon();
3694+ void paintActiveBackground(QImage*);
3695+
3696+ struct _PangoLayout* createPangoLayout();
3697+ void paintLabel(QImage*, struct _PangoLayout*, int labelX);
3698+};
3699+
3700+#endif /* INDICATORENTRYWIDGET_H */
3701
3702=== added file 'panel/applets/common/indicatorsmanager.cpp'
3703--- panel/applets/common/indicatorsmanager.cpp 1970-01-01 00:00:00 +0000
3704+++ panel/applets/common/indicatorsmanager.cpp 2011-08-09 17:30:25 +0000
3705@@ -0,0 +1,206 @@
3706+/*
3707+ * This file is part of unity-2d
3708+ *
3709+ * Copyright 2011 Canonical Ltd.
3710+ *
3711+ * Authors:
3712+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
3713+ *
3714+ * This program is free software; you can redistribute it and/or modify
3715+ * it under the terms of the GNU General Public License as published by
3716+ * the Free Software Foundation; version 3.
3717+ *
3718+ * This program is distributed in the hope that it will be useful,
3719+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3720+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3721+ * GNU General Public License for more details.
3722+ *
3723+ * You should have received a copy of the GNU General Public License
3724+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3725+ */
3726+// Self
3727+#include "indicatorsmanager.h"
3728+
3729+// Local
3730+#include <debug_p.h>
3731+#include <indicatorentrywidget.h>
3732+
3733+// Qt
3734+#include <QApplication>
3735+#include <QTimer>
3736+#include <QX11Info>
3737+
3738+// X11
3739+#include <X11/Xlib.h>
3740+
3741+using namespace unity::indicator;
3742+
3743+IndicatorsManager::IndicatorsManager(QObject* parent)
3744+: QObject(parent)
3745+, m_indicators(new DBusIndicators)
3746+, m_geometrySyncTimer(new QTimer(this))
3747+, m_mouseTrackerTimer(new QTimer(this))
3748+{
3749+ m_geometrySyncTimer->setInterval(0);
3750+ m_geometrySyncTimer->setSingleShot(true);
3751+ connect(m_geometrySyncTimer, SIGNAL(timeout()), SLOT(syncGeometries()));
3752+
3753+ // m_mouseTrackerTimer is inspired from
3754+ // plugins/unityshell/src/PanelView.cpp in OnEntryActivated()
3755+ //
3756+ // Rationale copied from Unity source code:
3757+ // """
3758+ // Track menus being scrubbed at 60Hz (about every 16 millisec)
3759+ // It might sound ugly, but it's far nicer (and more responsive) than the
3760+ // code it replaces which used to capture motion events in another process
3761+ // (unity-panel-service) and send them to us over dbus.
3762+ // NOTE: The reason why we have to use a timer instead of tracking motion
3763+ // events is because the motion events will never be delivered to this
3764+ // process. All the motion events will go to unity-panel-service while
3765+ // scrubbing because the active panel menu has (needs) the pointer grab.
3766+ // """
3767+ m_mouseTrackerTimer->setInterval(16);
3768+ m_mouseTrackerTimer->setSingleShot(false);
3769+ connect(m_mouseTrackerTimer, SIGNAL(timeout()), SLOT(checkMousePosition()));
3770+
3771+ m_indicators->on_entry_show_menu.connect(
3772+ sigc::mem_fun(this, &IndicatorsManager::onEntryShowMenu)
3773+ );
3774+
3775+ m_indicators->on_entry_activate_request.connect(
3776+ sigc::mem_fun(this, &IndicatorsManager::onEntryActivateRequest)
3777+ );
3778+
3779+ m_indicators->on_entry_activated.connect(
3780+ sigc::mem_fun(this, &IndicatorsManager::onEntryActivated)
3781+ );
3782+
3783+ m_indicators->on_synced.connect(
3784+ sigc::mem_fun(this, &IndicatorsManager::onSynced)
3785+ );
3786+}
3787+
3788+unity::indicator::DBusIndicators::Ptr IndicatorsManager::indicators() const
3789+{
3790+ return m_indicators;
3791+}
3792+
3793+void IndicatorsManager::onEntryShowMenu(const std::string& /*entryId*/, int posX, int posY, int /*timestamp*/, int /*button*/)
3794+{
3795+ // Copied from plugins/unityshell/src/PanelView.cpp, in OnEntryShowMenu()
3796+ // Without this code, menus cannot be shown from mousePressEvent() (but can
3797+ // be shown from mouseReleaseEvent())
3798+ /*
3799+ Neil explanation:
3800+ On button down, X automatically gives Qt a passive grab on the mouse this
3801+ means that, if the panel service tries to grab the pointer to show the menu
3802+ (gtk does this automatically), it fails and the menu can't show.
3803+ We connect to the on_entry_show_menu signal, which is emitted before
3804+ DBusIndicators does anything else, and just break the grab.
3805+ */
3806+ Display* display = QX11Info::display();
3807+ XUngrabPointer(display, CurrentTime);
3808+ XFlush(display);
3809+
3810+ XButtonEvent event = {
3811+ ButtonRelease,
3812+ 0,
3813+ False,
3814+ display,
3815+ 0,
3816+ 0,
3817+ 0,
3818+ CurrentTime,
3819+ posX, posY,
3820+ posX, posY,
3821+ 0,
3822+ Button1,
3823+ True
3824+ };
3825+ qApp->x11ProcessEvent(reinterpret_cast<XEvent*>(&event));
3826+}
3827+
3828+void IndicatorsManager::checkMousePosition()
3829+{
3830+ // Called by m_mouseTrackerTimer to implement mouse scrubbing
3831+ // (Assuming item A menu is opened, move mouse over item B => item B menu opens)
3832+ QWidget* widget = QApplication::widgetAt(QCursor::pos());
3833+ IndicatorEntryWidget* entryWidget = qobject_cast<IndicatorEntryWidget*>(widget);
3834+ if (!entryWidget) {
3835+ return;
3836+ }
3837+ entryWidget->showMenu(Qt::NoButton);
3838+}
3839+
3840+void IndicatorsManager::onEntryActivateRequest(const std::string& entryId)
3841+{
3842+ if (entryId.empty()) {
3843+ return;
3844+ }
3845+ IndicatorEntryWidget* widget = 0;
3846+ Q_FOREACH(widget, m_widgetList) {
3847+ if (widget->entry()->id() == entryId) {
3848+ break;
3849+ }
3850+ }
3851+ if (!widget) {
3852+ UQ_WARNING << "Could not find a widget for IndicatorEntry with id" << QString::fromStdString(entryId);
3853+ return;
3854+ }
3855+ widget->showMenu(Qt::NoButton);
3856+}
3857+
3858+void IndicatorsManager::onEntryActivated(const std::string& entryId)
3859+{
3860+ if (entryId.empty()) {
3861+ m_mouseTrackerTimer->stop();
3862+ } else {
3863+ m_mouseTrackerTimer->start();
3864+ }
3865+}
3866+
3867+void IndicatorsManager::onSynced()
3868+{
3869+ QMetaObject::invokeMethod(m_geometrySyncTimer, "start", Qt::QueuedConnection);
3870+}
3871+
3872+void IndicatorsManager::addIndicatorEntryWidget(IndicatorEntryWidget* widget)
3873+{
3874+ m_widgetList.append(widget);
3875+ widget->installEventFilter(this);
3876+}
3877+
3878+bool IndicatorsManager::eventFilter(QObject*, QEvent* event)
3879+{
3880+ switch (event->type()) {
3881+ case QEvent::Show:
3882+ case QEvent::Hide:
3883+ case QEvent::Move:
3884+ case QEvent::Resize:
3885+ m_geometrySyncTimer->start();
3886+ break;
3887+ default:
3888+ break;
3889+ }
3890+ return false;
3891+}
3892+
3893+void IndicatorsManager::syncGeometries()
3894+{
3895+ EntryLocationMap locations;
3896+ Q_FOREACH(IndicatorEntryWidget* widget, m_widgetList) {
3897+ if (!widget->isVisible()) {
3898+ continue;
3899+ }
3900+ Entry::Ptr entry = widget->entry();
3901+ if (entry->IsUnused()) {
3902+ continue;
3903+ }
3904+ QPoint topLeft = widget->mapToGlobal(QPoint(0, 0));
3905+ nux::Rect rect(topLeft.x(), topLeft.y(), widget->width(), widget->height());
3906+ locations[widget->entry()->id()] = rect;
3907+ }
3908+ m_indicators->SyncGeometries("Panel", locations);
3909+}
3910+
3911+#include "indicatorsmanager.moc"
3912
3913=== added file 'panel/applets/common/indicatorsmanager.h'
3914--- panel/applets/common/indicatorsmanager.h 1970-01-01 00:00:00 +0000
3915+++ panel/applets/common/indicatorsmanager.h 2011-08-09 17:30:25 +0000
3916@@ -0,0 +1,72 @@
3917+/*
3918+ * This file is part of unity-2d
3919+ *
3920+ * Copyright 2011 Canonical Ltd.
3921+ *
3922+ * Authors:
3923+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
3924+ *
3925+ * This program is free software; you can redistribute it and/or modify
3926+ * it under the terms of the GNU General Public License as published by
3927+ * the Free Software Foundation; version 3.
3928+ *
3929+ * This program is distributed in the hope that it will be useful,
3930+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3931+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3932+ * GNU General Public License for more details.
3933+ *
3934+ * You should have received a copy of the GNU General Public License
3935+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3936+ */
3937+#ifndef INDICATORSMANAGER_H
3938+#define INDICATORSMANAGER_H
3939+
3940+// Local
3941+
3942+// Qt
3943+#include <QMap>
3944+#include <QObject>
3945+
3946+// libunity-core
3947+#include <UnityCore/DBusIndicators.h>
3948+
3949+class QTimer;
3950+
3951+class IndicatorEntryWidget;
3952+
3953+/**
3954+ * Instantiates DBusIndicators and implement common behavior
3955+ */
3956+class IndicatorsManager : public QObject, public sigc::trackable
3957+{
3958+ Q_OBJECT
3959+public:
3960+ IndicatorsManager(QObject* parent);
3961+
3962+ unity::indicator::DBusIndicators::Ptr indicators() const;
3963+
3964+ void addIndicatorEntryWidget(IndicatorEntryWidget* widget);
3965+
3966+protected:
3967+ bool eventFilter(QObject*, QEvent*);
3968+
3969+private Q_SLOTS:
3970+ void syncGeometries();
3971+ void checkMousePosition();
3972+
3973+private:
3974+ Q_DISABLE_COPY(IndicatorsManager)
3975+ unity::indicator::DBusIndicators::Ptr m_indicators;
3976+ QTimer* m_geometrySyncTimer;
3977+ QTimer* m_mouseTrackerTimer;
3978+
3979+ typedef QList<IndicatorEntryWidget*> IndicatorEntryWidgetList;
3980+ IndicatorEntryWidgetList m_widgetList;
3981+
3982+ void onSynced();
3983+ void onEntryShowMenu(const std::string&, int x, int y, int timestamp, int button);
3984+ void onEntryActivateRequest(const std::string& entryId);
3985+ void onEntryActivated(const std::string& entryId);
3986+};
3987+
3988+#endif /* INDICATORSMANAGER_H */
3989
3990=== added file 'panel/applets/common/indicatorwidget.cpp'
3991--- panel/applets/common/indicatorwidget.cpp 1970-01-01 00:00:00 +0000
3992+++ panel/applets/common/indicatorwidget.cpp 2011-08-09 17:30:25 +0000
3993@@ -0,0 +1,53 @@
3994+/*
3995+ * This file is part of unity-2d
3996+ *
3997+ * Copyright 2011 Canonical Ltd.
3998+ *
3999+ * Authors:
4000+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
4001+ *
4002+ * This program is free software; you can redistribute it and/or modify
4003+ * it under the terms of the GNU General Public License as published by
4004+ * the Free Software Foundation; version 3.
4005+ *
4006+ * This program is distributed in the hope that it will be useful,
4007+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4008+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4009+ * GNU General Public License for more details.
4010+ *
4011+ * You should have received a copy of the GNU General Public License
4012+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4013+ */
4014+// Self
4015+#include "indicatorwidget.h"
4016+
4017+// Local
4018+#include <debug_p.h>
4019+#include <indicatorentrywidget.h>
4020+#include <indicatorsmanager.h>
4021+
4022+// Qt
4023+#include <QHBoxLayout>
4024+
4025+using namespace unity::indicator;
4026+
4027+IndicatorWidget::IndicatorWidget(const Indicator::Ptr& indicator, IndicatorsManager* manager)
4028+: m_layout(new QHBoxLayout(this))
4029+, m_indicatorsManager(manager)
4030+, m_indicator(indicator)
4031+{
4032+ m_layout->setMargin(0);
4033+ m_layout->setSpacing(0);
4034+
4035+ m_indicator->on_entry_added.connect(sigc::mem_fun(this, &IndicatorWidget::onEntryAdded));
4036+}
4037+
4038+void IndicatorWidget::onEntryAdded(const Entry::Ptr& entry)
4039+{
4040+ IndicatorEntryWidget* widget = new IndicatorEntryWidget(entry);
4041+ m_indicatorsManager->addIndicatorEntryWidget(widget);
4042+ m_layout->addWidget(widget);
4043+}
4044+
4045+
4046+#include "indicatorwidget.moc"
4047
4048=== added file 'panel/applets/common/indicatorwidget.h'
4049--- panel/applets/common/indicatorwidget.h 1970-01-01 00:00:00 +0000
4050+++ panel/applets/common/indicatorwidget.h 2011-08-09 17:30:25 +0000
4051@@ -0,0 +1,52 @@
4052+/*
4053+ * This file is part of unity-2d
4054+ *
4055+ * Copyright 2011 Canonical Ltd.
4056+ *
4057+ * Authors:
4058+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
4059+ *
4060+ * This program is free software; you can redistribute it and/or modify
4061+ * it under the terms of the GNU General Public License as published by
4062+ * the Free Software Foundation; version 3.
4063+ *
4064+ * This program is distributed in the hope that it will be useful,
4065+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4066+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4067+ * GNU General Public License for more details.
4068+ *
4069+ * You should have received a copy of the GNU General Public License
4070+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4071+ */
4072+#ifndef INDICATORWIDGET_H
4073+#define INDICATORWIDGET_H
4074+
4075+// Local
4076+
4077+// libunity-core
4078+#include <UnityCore/Indicator.h>
4079+#include <UnityCore/IndicatorEntry.h>
4080+
4081+// Qt
4082+#include <QWidget>
4083+
4084+class QHBoxLayout;
4085+
4086+class IndicatorEntryWidget;
4087+class IndicatorsManager;
4088+
4089+class IndicatorWidget : public QWidget, public sigc::trackable
4090+{
4091+Q_OBJECT
4092+public:
4093+ IndicatorWidget(const unity::indicator::Indicator::Ptr& indicator, IndicatorsManager* manager);
4094+
4095+private:
4096+ QHBoxLayout* m_layout;
4097+ IndicatorsManager* m_indicatorsManager;
4098+ unity::indicator::Indicator::Ptr m_indicator;
4099+
4100+ void onEntryAdded(const unity::indicator::Entry::Ptr& entry);
4101+};
4102+
4103+#endif /* INDICATORWIDGET_H */
4104
4105=== added file 'panel/applets/common/panelstyle.cpp'
4106--- panel/applets/common/panelstyle.cpp 1970-01-01 00:00:00 +0000
4107+++ panel/applets/common/panelstyle.cpp 2011-08-09 17:30:25 +0000
4108@@ -0,0 +1,201 @@
4109+/*
4110+ * This file is part of unity-2d
4111+ *
4112+ * Copyright 2011 Canonical Ltd.
4113+ *
4114+ * Authors:
4115+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
4116+ *
4117+ * This program is free software; you can redistribute it and/or modify
4118+ * it under the terms of the GNU General Public License as published by
4119+ * the Free Software Foundation; version 3.
4120+ *
4121+ * This program is distributed in the hope that it will be useful,
4122+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4123+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4124+ * GNU General Public License for more details.
4125+ *
4126+ * You should have received a copy of the GNU General Public License
4127+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4128+ */
4129+// Self
4130+#include "panelstyle.h"
4131+
4132+// libunity-2d
4133+#include <cairoutils.h>
4134+#include <debug_p.h>
4135+#include <gconnector.h>
4136+#include <gscopedpointer.h>
4137+
4138+// Qt
4139+#include <QApplication>
4140+#include <QPalette>
4141+#include <QStyle>
4142+
4143+// GTK
4144+#include <gtk/gtk.h>
4145+
4146+static const char* METACITY_THEME_DIR = "/usr/share/themes/%1/metacity-1";
4147+
4148+class PanelStylePrivate
4149+{
4150+public:
4151+ PanelStyle* q;
4152+ GObjectScopedPointer<GtkStyleContext> m_styleContext;
4153+ GConnector m_gConnector;
4154+
4155+ QString m_themeName;
4156+
4157+ static void onThemeChanged(GObject*, GParamSpec*, gpointer data)
4158+ {
4159+ PanelStylePrivate* priv = reinterpret_cast<PanelStylePrivate*>(data);
4160+ priv->updatePalette();
4161+ }
4162+
4163+ void updatePalette()
4164+ {
4165+ gchar* themeName = 0;
4166+ g_object_get(gtk_settings_get_default(), "gtk-theme-name", &themeName, NULL);
4167+ m_themeName = QString::fromUtf8(themeName);
4168+ g_free(themeName);
4169+
4170+ GtkStyleContext* context = m_styleContext.data();
4171+ gtk_style_context_invalidate(context);
4172+
4173+ // Without this line, it seems the GtkStyleContext is not correctly
4174+ // initialized and we get some uninitialized pixels in the background
4175+ // brush.
4176+ gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, NULL);
4177+
4178+ QPalette pal;
4179+ pal.setBrush(QPalette::Window, generateBackgroundBrush());
4180+ QApplication::setPalette(pal);
4181+ }
4182+
4183+ QBrush generateBackgroundBrush()
4184+ {
4185+ QImage image(100, 24, QImage::Format_ARGB32_Premultiplied); // FIXME: Hardcoded
4186+ image.fill(Qt::transparent);
4187+ CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(&image));
4188+ CairoUtils::Pointer cr(cairo_create(surface.data()));
4189+ gtk_render_background(m_styleContext.data(), cr.data(), 0, 0, image.width(), image.height());
4190+ return QBrush(image);
4191+ }
4192+
4193+ QPixmap windowButtonPixmapFromWMTheme(PanelStyle::WindowButtonType type, PanelStyle::WindowButtonState state)
4194+ {
4195+ QString dir = QString(METACITY_THEME_DIR).arg(m_themeName);
4196+
4197+ QString typeString, stateString;
4198+ switch (type) {
4199+ case PanelStyle::CloseWindowButton:
4200+ typeString = "close";
4201+ break;
4202+ case PanelStyle::MinimizeWindowButton:
4203+ typeString = "minimize";
4204+ break;
4205+ case PanelStyle::UnmaximizeWindowButton:
4206+ typeString = "unmaximize";
4207+ break;
4208+ }
4209+
4210+ switch (state) {
4211+ case PanelStyle::NormalState:
4212+ stateString = "";
4213+ break;
4214+ case PanelStyle::PrelightState:
4215+ stateString = "_focused_prelight";
4216+ break;
4217+ case PanelStyle::PressedState:
4218+ stateString = "_focused_pressed";
4219+ break;
4220+ }
4221+
4222+ QString path = QString("%1/%2%3.png")
4223+ .arg(dir)
4224+ .arg(typeString)
4225+ .arg(stateString);
4226+ return QPixmap(path);
4227+ }
4228+
4229+ QPixmap genericWindowButtonPixmap(PanelStyle::WindowButtonType type, PanelStyle::WindowButtonState state)
4230+ {
4231+ QStyle::StandardPixmap standardIcon;
4232+ switch (type) {
4233+ case PanelStyle::CloseWindowButton:
4234+ standardIcon = QStyle::SP_TitleBarCloseButton;
4235+ break;
4236+ case PanelStyle::MinimizeWindowButton:
4237+ standardIcon = QStyle::SP_TitleBarMinButton;
4238+ break;
4239+ case PanelStyle::UnmaximizeWindowButton:
4240+ standardIcon = QStyle::SP_TitleBarNormalButton;
4241+ break;
4242+ }
4243+
4244+ QIcon icon = QApplication::style()->standardIcon(standardIcon);
4245+ const int extent = 22;
4246+ switch (state) {
4247+ case PanelStyle::NormalState:
4248+ return icon.pixmap(extent);
4249+ case PanelStyle::PrelightState:
4250+ return icon.pixmap(extent, QIcon::Active);
4251+ case PanelStyle::PressedState:
4252+ return icon.pixmap(extent, QIcon::Active, QIcon::On);
4253+ }
4254+ // Silence compiler
4255+ return QPixmap();
4256+ }
4257+};
4258+
4259+PanelStyle::PanelStyle(QObject* parent)
4260+: d(new PanelStylePrivate)
4261+{
4262+ d->q = this;
4263+ d->m_styleContext.reset(gtk_style_context_new());
4264+
4265+ GtkWidgetPath* widgetPath = gtk_widget_path_new ();
4266+ gtk_widget_path_append_type(widgetPath, GTK_TYPE_WINDOW);
4267+ gtk_widget_path_iter_set_name(widgetPath, -1 , "UnityPanelWidget");
4268+
4269+ gtk_style_context_set_path(d->m_styleContext.data(), widgetPath);
4270+ gtk_style_context_add_class(d->m_styleContext.data(), "gnome-panel-menu-bar");
4271+ gtk_style_context_add_class(d->m_styleContext.data(), "unity-panel");
4272+
4273+ gtk_widget_path_free (widgetPath);
4274+
4275+ d->m_gConnector.connect(gtk_settings_get_default(), "notify::gtk-theme-name",
4276+ G_CALLBACK(PanelStylePrivate::onThemeChanged), d);
4277+
4278+ d->updatePalette();
4279+}
4280+
4281+PanelStyle::~PanelStyle()
4282+{
4283+ delete d;
4284+}
4285+
4286+PanelStyle* PanelStyle::instance()
4287+{
4288+ static PanelStyle style;
4289+ return &style;
4290+}
4291+
4292+GtkStyleContext* PanelStyle::styleContext() const
4293+{
4294+ return d->m_styleContext.data();
4295+}
4296+
4297+QPixmap PanelStyle::windowButtonPixmap(PanelStyle::WindowButtonType type, PanelStyle::WindowButtonState state)
4298+{
4299+ // According to Unity PanelStyle code, the buttons of some WM themes do not
4300+ // match well with the panel background. So except for themes we provide,
4301+ // fallback to generic button pixmaps.
4302+ if (d->m_themeName == "Ambiance" || d->m_themeName == "Radiance") {
4303+ return d->windowButtonPixmapFromWMTheme(type, state);
4304+ } else {
4305+ return d->genericWindowButtonPixmap(type, state);
4306+ }
4307+}
4308+
4309+#include "panelstyle.moc"
4310
4311=== added file 'panel/applets/common/panelstyle.h'
4312--- panel/applets/common/panelstyle.h 1970-01-01 00:00:00 +0000
4313+++ panel/applets/common/panelstyle.h 2011-08-09 17:30:25 +0000
4314@@ -0,0 +1,72 @@
4315+/*
4316+ * This file is part of unity-2d
4317+ *
4318+ * Copyright 2011 Canonical Ltd.
4319+ *
4320+ * Authors:
4321+ * - Aurélien Gâteau <aurelien.gateau@canonical.com>
4322+ *
4323+ * This program is free software; you can redistribute it and/or modify
4324+ * it under the terms of the GNU General Public License as published by
4325+ * the Free Software Foundation; version 3.
4326+ *
4327+ * This program is distributed in the hope that it will be useful,
4328+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4329+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4330+ * GNU General Public License for more details.
4331+ *
4332+ * You should have received a copy of the GNU General Public License
4333+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4334+ */
4335+#ifndef PANELSTYLE_H
4336+#define PANELSTYLE_H
4337+
4338+// Local
4339+
4340+// Qt
4341+#include <QObject>
4342+
4343+class QPixmap;
4344+
4345+struct _GtkStyleContext;
4346+
4347+class PanelStylePrivate;
4348+/**
4349+ * Provides easy access to panel style context and track platform theme to
4350+ * ensure we have the correct background brush.
4351+ *
4352+ * FIXME: This class does not have a very clear focus and has side-effects
4353+ * (background brush handling). It should be refactored.
4354+ */
4355+class PanelStyle : public QObject
4356+{
4357+ Q_OBJECT
4358+public:
4359+ PanelStyle(QObject* parent = 0);
4360+ ~PanelStyle();
4361+
4362+ enum WindowButtonType {
4363+ CloseWindowButton,
4364+ MinimizeWindowButton,
4365+ UnmaximizeWindowButton
4366+ };
4367+
4368+ enum WindowButtonState {
4369+ NormalState,
4370+ PrelightState,
4371+ PressedState
4372+ };
4373+
4374+ static PanelStyle* instance();
4375+
4376+ struct _GtkStyleContext* styleContext() const;
4377+
4378+ QPixmap windowButtonPixmap(WindowButtonType, WindowButtonState);
4379+
4380+private:
4381+ friend class PanelStylePrivate;
4382+ // Use a pimpl to avoid the need for gtk includes here
4383+ PanelStylePrivate* const d;
4384+};
4385+
4386+#endif /* PANELSTYLE_H */
4387
4388=== modified file 'panel/applets/homebutton/homebutton.cpp'
4389--- panel/applets/homebutton/homebutton.cpp 2011-05-26 16:41:04 +0000
4390+++ panel/applets/homebutton/homebutton.cpp 2011-08-09 17:30:25 +0000
4391@@ -40,8 +40,10 @@
4392 setStyleSheet(
4393 "QToolButton { border: none; margin: 0; padding: 0; width: 61 }"
4394 "QToolButton:checked, QToolButton:pressed {"
4395- // Use border-image here, not background-image, because bfb_bg_active.png is 56px wide
4396- " border-image: url(theme:/bfb_bg_active.png);"
4397+ " padding-top: 1px;"
4398+ " padding-left: 1px;"
4399+ " padding-right: -1px;"
4400+ " padding-bottom: -1px;"
4401 "}"
4402 );
4403 }
4404
4405=== added directory 'panel/applets/indicator'
4406=== removed directory 'panel/applets/indicator'
4407=== removed file 'panel/applets/indicator-config.h.in'
4408--- panel/applets/indicator-config.h.in 2011-03-01 09:04:13 +0000
4409+++ panel/applets/indicator-config.h.in 1970-01-01 00:00:00 +0000
4410@@ -1,7 +0,0 @@
4411-#ifndef INDICATOR_CONFIG_H
4412-#define INDICATOR_CONFIG_H
4413-
4414-#define INDICATOR_ICONS_DIR "${INDICATOR_ICONS_DIR}"
4415-#define INDICATOR_DIR "${INDICATOR_DIR}"
4416-
4417-#endif /* INDICATOR_CONFIG_H */
4418
4419=== removed file 'panel/applets/indicator/abstractindicator.cpp'
4420--- panel/applets/indicator/abstractindicator.cpp 2011-01-15 01:41:03 +0000
4421+++ panel/applets/indicator/abstractindicator.cpp 1970-01-01 00:00:00 +0000
4422@@ -1,43 +0,0 @@
4423-/*
4424- * This file is part of unity-2d
4425- *
4426- * Copyright 2010 Canonical Ltd.
4427- *
4428- * Authors:
4429- * - Aurélien Gâteau <aurelien.gateau@canonical.com>
4430- *
4431- * This program is free software; you can redistribute it and/or modify
4432- * it under the terms of the GNU General Public License as published by
4433- * the Free Software Foundation; version 3.
4434- *
4435- * This program is distributed in the hope that it will be useful,
4436- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4437- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4438- * GNU General Public License for more details.
4439- *
4440- * You should have received a copy of the GNU General Public License
4441- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4442- */
4443-
4444-// Self
4445-#include "abstractindicator.h"
4446-
4447-// Local
4448-
4449-// Qt
4450-#include <QAction>
4451-
4452-AbstractIndicator::AbstractIndicator(QObject* parent)
4453-: QObject(parent)
4454-{
4455-}
4456-
4457-AbstractIndicator::~AbstractIndicator()
4458-{
4459-}
4460-
4461-void AbstractIndicator::init()
4462-{
4463-}
4464-
4465-#include "abstractindicator.moc"
4466
4467=== removed file 'panel/applets/indicator/abstractindicator.h'
4468--- panel/applets/indicator/abstractindicator.h 2011-01-15 01:41:03 +0000
4469+++ panel/applets/indicator/abstractindicator.h 1970-01-01 00:00:00 +0000
4470@@ -1,53 +0,0 @@
4471-/*
4472- * This file is part of unity-2d
4473- *
4474- * Copyright 2010 Canonical Ltd.
4475- *
4476- * Authors:
4477- * - Aurélien Gâteau <aurelien.gateau@canonical.com>
4478- *
4479- * This program is free software; you can redistribute it and/or modify
4480- * it under the terms of the GNU General Public License as published by
4481- * the Free Software Foundation; version 3.
4482- *
4483- * This program is distributed in the hope that it will be useful,
4484- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4485- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4486- * GNU General Public License for more details.
4487- *
4488- * You should have received a copy of the GNU General Public License
4489- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4490- */
4491-
4492-#ifndef ABSTRACTINDICATOR_H
4493-#define ABSTRACTINDICATOR_H
4494-
4495-// Local
4496-
4497-// Qt
4498-#include <QObject>
4499-
4500-class QAction;
4501-
4502-class AbstractIndicator : public QObject
4503-{
4504- Q_OBJECT
4505-public:
4506- AbstractIndicator(QObject* parent=0);
4507- ~AbstractIndicator();
4508-
4509- /**
4510- * Called when the indicator has been constructed and its owner is connected to signals.
4511- * It's the right place to emit actionAdded()
4512- */
4513- virtual void init();
4514-
4515-Q_SIGNALS:
4516- void actionAdded(QAction*);
4517- void actionRemoved(QAction*);
4518-
4519-private:
4520- Q_DISABLE_COPY(AbstractIndicator)
4521-};
4522-
4523-#endif /* ABSTRACTINDICATOR_H */
4524
4525=== removed file 'panel/applets/indicator/datetimeindicator.cpp'
4526--- panel/applets/indicator/datetimeindicator.cpp 2011-02-10 01:10:19 +0000
4527+++ panel/applets/indicator/datetimeindicator.cpp 1970-01-01 00:00:00 +0000
4528@@ -1,94 +0,0 @@
4529-/*
4530- * This file is part of unity-2d
4531- *
4532- * Copyright 2010 Canonical Ltd.
4533- *
4534- * Authors:
4535- * - Aurélien Gâteau <aurelien.gateau@canonical.com>
4536- *
4537- * This program is free software; you can redistribute it and/or modify
4538- * it under the terms of the GNU General Public License as published by
4539- * the Free Software Foundation; version 3.
4540- *
4541- * This program is distributed in the hope that it will be useful,
4542- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4543- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4544- * GNU General Public License for more details.
4545- *
4546- * You should have received a copy of the GNU General Public License
4547- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4548- */
4549-
4550-// Self
4551-#include "datetimeindicator.h"
4552-
4553-// Local
4554-#include "indicatorservicemanager.h"
4555-
4556-// dbusmenu-qt
4557-#include "dbusmenuimporter.h"
4558-
4559-// Qt
4560-#include <QAction>
4561-#include <QDateTime>
4562-
4563-// From dbus-shared.h
4564-#define SERVICE_NAME "com.canonical.indicator.datetime"
4565-#define SERVICE_IFACE "com.canonical.indicator.datetime.service"
4566-#define SERVICE_OBJ "/com.canonical/indicator/datetime/service"
4567-#define SERVICE_VERSION 1
4568-
4569-#define MENU_OBJ "/com.canonical/indicator/datetime/menu"
4570-
4571-#define DBUSMENU_CALENDAR_MENUITEM_TYPE "x-canonical-calendar-item"
4572-////
4573-
4574-DateTimeIndicator::DateTimeIndicator(QObject* parent)
4575-: AbstractIndicator(parent)
4576-, m_action(new QAction(this))
4577-, m_timer(new QTimer(this))
4578-{
4579- new IndicatorServiceManager(SERVICE_NAME, SERVICE_VERSION, this);
4580-
4581- readConfig();
4582- setupMenu();
4583- setupTimer();
4584- updateText();
4585-}
4586-
4587-void DateTimeIndicator::init()
4588-{
4589- actionAdded(m_action);
4590-}
4591-
4592-void DateTimeIndicator::setupMenu()
4593-{
4594- DBusMenuImporter* importer = new DBusMenuImporter(SERVICE_NAME, MENU_OBJ, this);
4595- m_action->setMenu(importer->menu());
4596-}
4597-
4598-void DateTimeIndicator::setupTimer()
4599-{
4600- m_timer->setSingleShot(false);
4601- connect(m_timer, SIGNAL(timeout()), SLOT(updateText()));
4602- updateTimer();
4603- m_timer->start();
4604-}
4605-
4606-void DateTimeIndicator::updateTimer()
4607-{
4608- m_timer->setInterval(1000);
4609-}
4610-
4611-void DateTimeIndicator::updateText()
4612-{
4613- QString text = QDateTime::currentDateTime().toString(m_format);
4614- m_action->setText(text);
4615-}
4616-
4617-void DateTimeIndicator::readConfig()
4618-{
4619- m_format = "hh:mm:ss";
4620-}
4621-
4622-#include "datetimeindicator.moc"
4623
4624=== removed file 'panel/applets/indicator/datetimeindicator.h'
4625--- panel/applets/indicator/datetimeindicator.h 2011-01-15 01:41:03 +0000
4626+++ panel/applets/indicator/datetimeindicator.h 1970-01-01 00:00:00 +0000
4627@@ -1,53 +0,0 @@
4628-/*
4629- * This file is part of unity-2d
4630- *
4631- * Copyright 2010 Canonical Ltd.
4632- *
4633- * Authors:
4634- * - Aurélien Gâteau <aurelien.gateau@canonical.com>
4635- *
4636- * This program is free software; you can redistribute it and/or modify
4637- * it under the terms of the GNU General Public License as published by
4638- * the Free Software Foundation; version 3.
4639- *
4640- * This program is distributed in the hope that it will be useful,
4641- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4642- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4643- * GNU General Public License for more details.
4644- *
4645- * You should have received a copy of the GNU General Public License
4646- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4647- */
4648-
4649-#ifndef DATETIMEINDICATOR_H
4650-#define DATETIMEINDICATOR_H
4651-
4652-// Local
4653-#include "abstractindicator.h"
4654-
4655-// Qt
4656-#include <QTimer>
4657-
4658-class DateTimeIndicator : public AbstractIndicator
4659-{
4660- Q_OBJECT
4661-public:
4662- DateTimeIndicator(QObject* parent=0);
4663-
4664- virtual void init();
4665-
4666-private Q_SLOTS:
4667- void updateText();
4668-private:
4669- Q_DISABLE_COPY(DateTimeIndicator)
4670- QAction* m_action;
4671- QTimer* m_timer;
4672- QString m_format;
4673-
4674- void setupTimer();
4675- void setupMenu();
4676- void readConfig();
4677- void updateTimer();
4678-};
4679-
4680-#endif /* DATETIMEINDICATOR_H */
4681
4682=== removed file 'panel/applets/indicator/indicator.c'
4683--- panel/applets/indicator/indicator.c 2011-07-01 03:58:28 +0000
4684+++ panel/applets/indicator/indicator.c 1970-01-01 00:00:00 +0000
4685@@ -1,525 +0,0 @@
4686-/* Copyright (c) 2009 Mark Trompell <mark@foresightlinux.org>
4687- *
4688- * This program is free software; you can redistribute it and/or modify
4689- * it under the terms of the GNU General Public License as published by
4690- * the Free Software Foundation; either version 2 of the License, or
4691- * (at your option) any later version.
4692- *
4693- * This program is distributed in the hope that it will be useful,
4694- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4695- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4696- * GNU Library General Public License for more details.
4697- *
4698- * You should have received a copy of the GNU General Public License
4699- * along with this program; if not, write to the Free Software
4700- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4701- */
4702-
4703-#include <string.h>
4704-
4705-#include <gtk/gtk.h>
4706-#include <libindicator/indicator-object.h>
4707-
4708-#include "indicator.h"
4709-
4710-#include "indicator-config.h"
4711-
4712-/* default settings */
4713-#define DEFAULT_SETTING1 NULL
4714-#define DEFAULT_SETTING2 1
4715-#define DEFAULT_SETTING3 FALSE
4716-
4717-typedef enum {
4718- PANEL_APPLET_ORIENT_LEFT,
4719- PANEL_APPLET_ORIENT_RIGHT,
4720- PANEL_APPLET_ORIENT_TOP,
4721- PANEL_APPLET_ORIENT_BOTTOM
4722-} PanelAppletOrient;
4723-
4724-// <indicator-applet-copy>
4725-static gchar * indicator_order[] = {
4726- "libappmenu.so",
4727- "libapplication.so",
4728- "libsoundmenu.so",
4729- "libnetworkmenu.so",
4730- "libmessaging.so",
4731- "libdatetime.so",
4732- "libme.so",
4733- "libsession.so",
4734- NULL
4735-};
4736-
4737-static GtkPackDirection packdirection;
4738-static PanelAppletOrient orient;
4739-
4740-#define MENU_DATA_INDICATOR_OBJECT "indicator-object"
4741-#define MENU_DATA_INDICATOR_ENTRY "indicator-entry"
4742-
4743-#define IO_DATA_ORDER_NUMBER "indicator-order-number"
4744-
4745-static gint
4746-name2order (const gchar * name) {
4747- int i;
4748-
4749- for (i = 0; indicator_order[i] != NULL; i++) {
4750- if (g_strcmp0(name, indicator_order[i]) == 0) {
4751- return i;
4752- }
4753- }
4754-
4755- return -1;
4756-}
4757-
4758-typedef struct _incoming_position_t incoming_position_t;
4759-struct _incoming_position_t {
4760- gint objposition;
4761- gint entryposition;
4762- gint menupos;
4763- gboolean found;
4764-};
4765-
4766-/* This function helps by determining where in the menu list
4767- this new entry should be placed. It compares the objects
4768- that they're on, and then the individual entries. Each
4769- is progressively more expensive. */
4770-static void
4771-place_in_menu (GtkWidget * widget, gpointer user_data)
4772-{
4773- incoming_position_t * position = (incoming_position_t *)user_data;
4774- if (position->found) {
4775- /* We've already been placed, just finish the foreach */
4776- return;
4777- }
4778-
4779- IndicatorObject * io = INDICATOR_OBJECT(g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_OBJECT));
4780- g_assert(io != NULL);
4781-
4782- gint objposition = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(io), IO_DATA_ORDER_NUMBER));
4783- /* We've already passed it, well, then this is where
4784- we should be be. Stop! */
4785- if (objposition > position->objposition) {
4786- position->found = TRUE;
4787- return;
4788- }
4789-
4790- /* The objects don't match yet, keep looking */
4791- if (objposition < position->objposition) {
4792- position->menupos++;
4793- return;
4794- }
4795-
4796- /* The objects are the same, let's start looking at entries. */
4797- IndicatorObjectEntry * entry = (IndicatorObjectEntry *)g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
4798- gint entryposition = indicator_object_get_location(io, entry);
4799-
4800- if (entryposition > position->entryposition) {
4801- position->found = TRUE;
4802- return;
4803- }
4804-
4805- if (entryposition < position->entryposition) {
4806- position->menupos++;
4807- return;
4808- }
4809-
4810- /* We've got the same object and the same entry. Well,
4811- let's just put it right here then. */
4812- position->found = TRUE;
4813- return;
4814-}
4815-
4816-static void
4817-something_shown (GtkWidget * widget, gpointer user_data)
4818-{
4819- GtkWidget * menuitem = GTK_WIDGET(user_data);
4820- gtk_widget_show(menuitem);
4821-}
4822-
4823-static void
4824-something_hidden (GtkWidget * widget, gpointer user_data)
4825-{
4826- GtkWidget * menuitem = GTK_WIDGET(user_data);
4827- gtk_widget_hide(menuitem);
4828-}
4829-
4830-static void
4831-sensitive_cb (GObject * obj, GParamSpec * pspec, gpointer user_data)
4832-{
4833- g_return_if_fail(GTK_IS_WIDGET(obj));
4834- g_return_if_fail(GTK_IS_WIDGET(user_data));
4835-
4836- gtk_widget_set_sensitive(GTK_WIDGET(user_data), gtk_widget_get_sensitive(GTK_WIDGET(obj)));
4837- return;
4838-}
4839-
4840-static gboolean
4841-entry_scrolled (GtkWidget *menuitem, GdkEventScroll *event, gpointer data)
4842-{
4843- IndicatorObject *io = g_object_get_data (G_OBJECT (menuitem), MENU_DATA_INDICATOR_OBJECT);
4844- IndicatorObjectEntry *entry = g_object_get_data (G_OBJECT (menuitem), MENU_DATA_INDICATOR_ENTRY);
4845-
4846- g_return_val_if_fail(INDICATOR_IS_OBJECT(io), FALSE);
4847-
4848- g_signal_emit_by_name (io, "scroll", 1, event->direction);
4849- g_signal_emit_by_name (io, "scroll-entry", entry, 1, event->direction);
4850-
4851- return FALSE;
4852-}
4853-
4854-static void
4855-entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, GtkWidget * menubar)
4856-{
4857- g_debug("Signal: Entry Added");
4858- gboolean something_visible = FALSE;
4859- gboolean something_sensitive = FALSE;
4860-
4861- GtkWidget * menuitem = gtk_menu_item_new();
4862- GtkWidget * box = (packdirection == GTK_PACK_DIRECTION_LTR) ?
4863- gtk_hbox_new(FALSE, 3) : gtk_vbox_new(FALSE, 3);
4864-
4865- g_object_set_data (G_OBJECT (menuitem), "indicator", io);
4866- g_object_set_data (G_OBJECT (menuitem), "box", box);
4867-
4868- if (entry->image != NULL) {
4869- gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(entry->image), FALSE, FALSE, 0);
4870- if (gtk_widget_get_visible(GTK_WIDGET(entry->image))) {
4871- something_visible = TRUE;
4872- }
4873-
4874- if (gtk_widget_get_sensitive(GTK_WIDGET(entry->image))) {
4875- something_sensitive = TRUE;
4876- }
4877-
4878- g_signal_connect(G_OBJECT(entry->image), "show", G_CALLBACK(something_shown), menuitem);
4879- g_signal_connect(G_OBJECT(entry->image), "hide", G_CALLBACK(something_hidden), menuitem);
4880-
4881- g_signal_connect(G_OBJECT(entry->image), "notify::sensitive", G_CALLBACK(sensitive_cb), menuitem);
4882- }
4883- if (entry->label != NULL) {
4884- switch(packdirection) {
4885- case GTK_PACK_DIRECTION_LTR:
4886- gtk_label_set_angle(GTK_LABEL(entry->label), 0.0);
4887- break;
4888- case GTK_PACK_DIRECTION_TTB:
4889- gtk_label_set_angle(GTK_LABEL(entry->label),
4890- (orient == PANEL_APPLET_ORIENT_LEFT) ?
4891- 270.0 : 90.0);
4892- break;
4893- default:
4894- break;
4895- }
4896- gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(entry->label), FALSE, FALSE, 0);
4897-
4898- if (gtk_widget_get_visible(GTK_WIDGET(entry->label))) {
4899- something_visible = TRUE;
4900- }
4901-
4902- if (gtk_widget_get_sensitive(GTK_WIDGET(entry->label))) {
4903- something_sensitive = TRUE;
4904- }
4905-
4906- g_signal_connect(G_OBJECT(entry->label), "show", G_CALLBACK(something_shown), menuitem);
4907- g_signal_connect(G_OBJECT(entry->label), "hide", G_CALLBACK(something_hidden), menuitem);
4908-
4909- g_signal_connect(G_OBJECT(entry->label), "notify::sensitive", G_CALLBACK(sensitive_cb), menuitem);
4910- }
4911- gtk_container_add(GTK_CONTAINER(menuitem), box);
4912- gtk_widget_show(box);
4913-
4914- if (entry->menu != NULL) {
4915- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(entry->menu));
4916- }
4917-
4918- incoming_position_t position;
4919- position.objposition = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(io), IO_DATA_ORDER_NUMBER));
4920- position.entryposition = indicator_object_get_location(io, entry);
4921- position.menupos = 0;
4922- position.found = FALSE;
4923-
4924- gtk_container_foreach(GTK_CONTAINER(menubar), place_in_menu, &position);
4925-
4926- gtk_menu_shell_insert(GTK_MENU_SHELL(menubar), menuitem, position.menupos);
4927-
4928- if (something_visible) {
4929- gtk_widget_show(menuitem);
4930- }
4931- gtk_widget_set_sensitive(menuitem, something_sensitive);
4932-
4933- g_object_set_data(G_OBJECT(menuitem), MENU_DATA_INDICATOR_ENTRY, entry);
4934- g_object_set_data(G_OBJECT(menuitem), MENU_DATA_INDICATOR_OBJECT, io);
4935- g_signal_connect(G_OBJECT (menuitem), "scroll-event", G_CALLBACK(entry_scrolled), NULL);
4936-
4937- return;
4938-}
4939-
4940-static void
4941-entry_removed_cb (GtkWidget * widget, gpointer userdata)
4942-{
4943- gpointer data = g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
4944-
4945- if (data != userdata) {
4946- return;
4947- }
4948-
4949- IndicatorObjectEntry * entry = (IndicatorObjectEntry *)data;
4950- if (entry->label != NULL) {
4951- g_signal_handlers_disconnect_by_func(G_OBJECT(entry->label), G_CALLBACK(something_shown), widget);
4952- g_signal_handlers_disconnect_by_func(G_OBJECT(entry->label), G_CALLBACK(something_hidden), widget);
4953- g_signal_handlers_disconnect_by_func(G_OBJECT(entry->label), G_CALLBACK(sensitive_cb), widget);
4954- }
4955- if (entry->image != NULL) {
4956- g_signal_handlers_disconnect_by_func(G_OBJECT(entry->image), G_CALLBACK(something_shown), widget);
4957- g_signal_handlers_disconnect_by_func(G_OBJECT(entry->image), G_CALLBACK(something_hidden), widget);
4958- g_signal_handlers_disconnect_by_func(G_OBJECT(entry->image), G_CALLBACK(sensitive_cb), widget);
4959- }
4960-
4961- gtk_widget_destroy(widget);
4962- return;
4963-}
4964-
4965-static void
4966-entry_removed (IndicatorObject * io G_GNUC_UNUSED, IndicatorObjectEntry * entry,
4967- gpointer user_data)
4968-{
4969- g_debug("Signal: Entry Removed");
4970-
4971- gtk_container_foreach(GTK_CONTAINER(user_data), entry_removed_cb, entry);
4972-
4973- return;
4974-}
4975-
4976-static void
4977-entry_moved_find_cb (GtkWidget * widget, gpointer userdata)
4978-{
4979- gpointer * array = (gpointer *)userdata;
4980- if (array[1] != NULL) {
4981- return;
4982- }
4983-
4984- gpointer data = g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
4985-
4986- if (data != array[0]) {
4987- return;
4988- }
4989-
4990- array[1] = widget;
4991- return;
4992-}
4993-
4994-/* Gets called when an entry for an object was moved. */
4995-static void
4996-entry_moved (IndicatorObject * io, IndicatorObjectEntry * entry,
4997- gint old G_GNUC_UNUSED, gint new G_GNUC_UNUSED, gpointer user_data)
4998-{
4999- GtkWidget * menubar = GTK_WIDGET(user_data);
5000-
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches