Merge lp:~renatofilho/unity/unity-lp876017 into lp:unity
- unity-lp876017
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Renato Araujo Oliveira Filho |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2650 |
Proposed branch: | lp:~renatofilho/unity/unity-lp876017 |
Merge into: | lp:unity |
Diff against target: |
729 lines (+507/-31) 6 files modified
CMakeLists.txt (+1/-2) plugins/unityshell/CMakeLists.txt (+1/-1) plugins/unityshell/src/unityshell.cpp (+428/-0) plugins/unityshell/src/unityshell.h (+39/-1) unity-shared/PanelStyle.cpp (+37/-27) unity-shared/PanelStyle.h (+1/-0) |
To merge this branch: | bzr merge lp:~renatofilho/unity/unity-lp876017 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sam Spilsbury (community) | Approve | ||
Review via email: mp+120450@code.launchpad.net |
Commit message
UnityWindow now implements ScaleWindowInte
Implemented support to close window during the scale plugin.
Fake windows decoration rendering using panel code as base.
Description of the change
UnityWindow now implements ScaleWindowInte
Implemented support to close window during the scale plugin.
Fake windows decoration rendering using panel code as base.
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
> I think you can just overload scaleSelectWindow to determine what the
> currently hovered window is. From there you will need to damage and re-render
> both the new and old window. Have a look at the scaleaddon plugin.
> #ifdef USE_MODERN_
> gWindow-
> #else
> 151 + gWindow->geometry ().reset ();
> #endif
> 152 + if (width && height)
> 153 + gWindow-
> 154 +
> #ifdef USE_MODERN_
> gWindow-
> if (gWindow-
> #else
> 155 + if (gWindow->geometry ().vCount)
> #endif
> 156 + {
> #ifdef USE_MODERN_
> 157 + GLFragment::Attrib fragment (attrib);
> #endif
> 158 + GLMatrix wTransform (transform);
> 159 +
> 160 + wTransform.
> 161 +
> #ifdef USE_MODERN_
> gWindow-
> #else
> 162 + glPushMatrix ();
> 163 + glLoadMatrixf (wTransform.
> 164 + gWindow-
> 165 + glPopMatrix ();
> #endif
> 166 + }
Fixed on rev: 2577
I have implemented the "scaleSelectWindow" based on scaleaddon plugin, but I did not understand why I need this code. (The implementation is working well without this)
>
> 172 + // BG
> 173 + glColor3f (0.0f, 0.0f, 0.0f);
> 174 + glRectf (x, y2, x2, y);
>
> Preferably use client side buffers for this
Fixed on rev: 2574
Thanks for the example code.
> Make this a constant
Fixed on rev: 2575
>
> Also avoid the 65535, use OPAQUE
Fixed on rev: 2576
>
> 121 + CompString name (PKGDATADIR"
>
> Is that the correct asset?
Based on designer docs, yes this is the correct icon.
>
> That needs to be under test.
Any suggestion or example how to test it?
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
> > That needs to be under test.
My suggestion to make the code testable is split unityshell.(h/cpp) file into different files (UnityWindow/
What do you think?
Sam Spilsbury (smspillaz) wrote : | # |
> > I think you can just overload scaleSelectWindow to determine what the
> > currently hovered window is. From there you will need to damage and re-
> render
> > both the new and old window. Have a look at the scaleaddon plugin.
> > #ifdef USE_MODERN_
> > gWindow-
> > #else
> > 151 + gWindow->geometry ().reset ();
> > #endif
> > 152 + if (width && height)
> > 153 + gWindow-
> > 154 +
> > #ifdef USE_MODERN_
> > gWindow-
> > if (gWindow-
> > #else
> > 155 + if (gWindow->geometry ().vCount)
> > #endif
> > 156 + {
> > #ifdef USE_MODERN_
> > 157 + GLFragment::Attrib fragment (attrib);
> > #endif
> > 158 + GLMatrix wTransform (transform);
> > 159 +
> > 160 + wTransform.
> > 161 +
> > #ifdef USE_MODERN_
> > gWindow-
> > #else
> > 162 + glPushMatrix ();
> > 163 + glLoadMatrixf (wTransform.
> > 164 + gWindow-
> > 165 + glPopMatrix ();
> > #endif
> > 166 + }
> Fixed on rev: 2577
> I have implemented the "scaleSelectWindow" based on scaleaddon plugin, but I
> did not understand why I need this code. (The implementation is working well
> without this)
Hmm, what do you mean by this? If you're saying that you don't need either I guess you can remove them both? Its just that overriding scaleSelectWindow is the preferred way to finding out the currently highlighted window as opposed to reimplementing checkForWindowAt.
>
> >
> > 172 + // BG
> > 173 + glColor3f (0.0f, 0.0f, 0.0f);
> > 174 + glRectf (x, y2, x2, y);
> >
> > Preferably use client side buffers for this
> Fixed on rev: 2574
> Thanks for the example code.
>
> > Make this a constant
> Fixed on rev: 2575
>
> >
> > Also avoid the 65535, use OPAQUE
> Fixed on rev: 2576
Thanks.
>
> >
> > 121 + CompString name (PKGDATADIR"
> >
> > Is that the correct asset?
> Based on designer docs, yes this is the correct icon.
+1
>
> >
> > That needs to be under test.
> Any suggestion or example how to test it?
My suggestion to make the code testable is split unityshell.(h/cpp) file into different files (UnityWindow/
What do you think?
^ This suggestion is the right way to do it :)
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
> Hmm, what do you mean by this? If you're saying that you don't need either I
> guess you can remove them both? Its just that overriding scaleSelectWindow is
> the preferred way to finding out the currently highlighted window as opposed
> to reimplementing checkForWindowAt.
I have implemented "scaleSelectWindow" but I did not use all the code you suggested, what I did was:
+void UnityWindow:
210 +{
211 + UnityScreen* us = UnityScreen:
212 +
213 + if (us->highlighte
214 + {
215 + CompositeWindow *cWindow = CompositeWindow
216 + if (cWindow)
217 + cWindow->addDamage ();
218 +
219 + cWindow = 0;
220 + CompWindow *old_window = screen->findWindow (us->highlighte
221 + if (old_window)
222 + cWindow = CompositeWindow
223 +
224 + if (cWindow)
225 + cWindow->addDamage ();
226 +
227 + us->highlighted
228 + }
229 +
230 + ScaleWindow *sWindow = ScaleWindow::get (window);
231 + if (sWindow)
232 + sWindow-
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
> > >
> > > That needs to be under test.
> > Any suggestion or example how to test it?
>
> My suggestion to make the code testable is split unityshell.(h/cpp) file into
> different files (UnityWindow/
> and UnityShell), with this we can instantiate only the private class inside of
> the tests and call/test the "private" functions.
>
> What do you think?
>
> ^ This suggestion is the right way to do it :)
This will be a big change in the code, because of that me and Olivier think this is not the best moment to do it, since this is our last week working on Unity bug fixes, and the code is already in feature freeze.
Sam Spilsbury (smspillaz) wrote : | # |
This looks good. I don't know how much of this is testable, but I agree at this point its probably better in than out. I'll put my +1 here and hopefully someone can give a second opinion in the next few hours.
Sam Spilsbury (smspillaz) : | # |
Unity Merger (unity-merger) wrote : | # |
No commit message specified.
Unity Merger (unity-merger) wrote : | # |
The Jenkins job https:/
Not merging it.
Sam Spilsbury (smspillaz) wrote : | # |
Hey renato.
You need to add xrender to the pkgconfig deps in the top level cmakelists file.
Sent from Samsung Mobile
Unity Merger <email address hidden> wrote:
The Jenkins job https:/
Not merging it.
--
https:/
You are reviewing the proposed merge of lp:~renatofilho/unity/unity-lp876017 into lp:unity.
Unity Merger (unity-merger) wrote : | # |
There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
64 + WindowCairoContext ()
When you have some time, could you please update this code to match the unity coding stiles (i.e. no spaces between methods and brackets)
Instead of GetTextProperty and GetTextProperty why not just using gdk_x11_
Also, these functions should actually be in WindowManager class (implemented by PluginAdapterCo
441 + if (window_
442 + g_object_unref (window_
You should have used glib::Object for this, and try to get rid of some manual deletion using smart pointers.
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2012-08-30 12:52:53 +0000 |
3 | +++ CMakeLists.txt 2012-08-31 13:28:34 +0000 |
4 | @@ -130,8 +130,7 @@ |
5 | # |
6 | # Compiz Plugins |
7 | # |
8 | - |
9 | -set (UNITY_PLUGIN_DEPS "compiz;nux-3.0>=3.0.0;libbamf3;dee-1.0;gio-2.0;gio-unix-2.0;gmodule-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator3-0.4>=0.4.90;atk;unity-misc>=0.4.0;dbus-glib-1;gtk+-3.0>=3.1;sigc++-2.0;json-glib-1.0;libnotify;xfixes;unity-protocol-private>=5.95.1;libgeis") |
10 | +set (UNITY_PLUGIN_DEPS "compiz;nux-3.0>=3.0.0;libbamf3;dee-1.0;gio-2.0;gio-unix-2.0;gmodule-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator3-0.4>=0.4.90;atk;unity-misc>=0.4.0;dbus-glib-1;gtk+-3.0>=3.1;sigc++-2.0;json-glib-1.0;libnotify;xfixes;unity-protocol-private>=5.95.1;libgeis;xrender>=0.9") |
11 | set (UNITY_PROTOCOL_PRIVATE_DEPS "unity-protocol-private>=5.95.1") |
12 | |
13 | find_package (PkgConfig) |
14 | |
15 | === modified file 'plugins/unityshell/CMakeLists.txt' |
16 | --- plugins/unityshell/CMakeLists.txt 2012-08-03 12:51:02 +0000 |
17 | +++ plugins/unityshell/CMakeLists.txt 2012-08-31 13:28:34 +0000 |
18 | @@ -6,7 +6,7 @@ |
19 | |
20 | compiz_plugin (unityshell |
21 | PKGDEPS ${UNITY_PLUGIN_DEPS} |
22 | - PLUGINDEPS composite opengl compiztoolbox |
23 | + PLUGINDEPS composite opengl compiztoolbox scale |
24 | CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${PKGDATADIR}\"' -I${CMAKE_BINARY_DIR} -I${CMAKE_SOURCE_DIR} ${BOOT_LOGGER_FLAG} -DGETTEXT_PACKAGE='\"unity\"' ${MAINTAINER_CFLAGS} -I${CMAKE_SOURCE_DIR}/dash/ -I${CMAKE_SOURCE_DIR}/launcher/ -I${CMAKE_SOURCE_DIR}/hud/ -I${CMAKE_SOURCE_DIR}/panel/ -I${CMAKE_SOURCE_DIR}/shortcuts/ -I${CMAKE_SOURCE_DIR}/unity-shared/" |
25 | LIBDIRS "${CMAKE_BINARY_DIR}/UnityCore" |
26 | ) |
27 | |
28 | === modified file 'plugins/unityshell/src/unityshell.cpp' |
29 | --- plugins/unityshell/src/unityshell.cpp 2012-08-31 09:15:33 +0000 |
30 | +++ plugins/unityshell/src/unityshell.cpp 2012-08-31 13:28:34 +0000 |
31 | @@ -43,6 +43,9 @@ |
32 | #include <gdk/gdk.h> |
33 | #include <gdk/gdkx.h> |
34 | #include <libnotify/notify.h> |
35 | +#include <cairo-xlib-xrender.h> |
36 | + |
37 | +#include <text/text.h> |
38 | |
39 | #include <sstream> |
40 | #include <memory> |
41 | @@ -80,6 +83,10 @@ |
42 | |
43 | UnityScreen* uScreen = 0; |
44 | |
45 | +static unsigned int CLOSE_ICON_SIZE = 19; |
46 | +static unsigned int CLOSE_ICON_SPACE = 5; |
47 | +static unsigned int SCALE_WINDOW_TITLE_SIZE = 28; |
48 | + |
49 | void reset_glib_logging(); |
50 | void configure_logging(); |
51 | void capture_g_log_calls(const gchar* log_domain, |
52 | @@ -100,6 +107,34 @@ |
53 | } // namespace local |
54 | } // anon namespace |
55 | |
56 | +class WindowCairoContext |
57 | +{ |
58 | + public: |
59 | + Pixmap pixmap_; |
60 | + cairo_surface_t* surface_; |
61 | + GLTexture::List texture_; |
62 | + cairo_t *cr_; |
63 | + |
64 | + WindowCairoContext () |
65 | + : pixmap_ (0), surface_ (0), cr_ (0) |
66 | + { |
67 | + } |
68 | + |
69 | + ~WindowCairoContext () |
70 | + { |
71 | + if (cr_) |
72 | + cairo_destroy (cr_); |
73 | + |
74 | + if (surface_) |
75 | + cairo_surface_destroy (surface_); |
76 | + |
77 | + texture_.clear (); |
78 | + |
79 | + if (pixmap_) |
80 | + XFreePixmap (screen->dpy (), pixmap_); |
81 | + } |
82 | +}; |
83 | + |
84 | UnityScreen::UnityScreen(CompScreen* screen) |
85 | : BaseSwitchScreen (screen) |
86 | , PluginClassHandler <UnityScreen, CompScreen> (screen) |
87 | @@ -128,6 +163,7 @@ |
88 | , panel_texture_has_changed_(true) |
89 | , paint_panel_(false) |
90 | , scale_just_activated_(false) |
91 | + , highlighted_window_(0) |
92 | , minimize_speed_controller(new WindowMinimizeSpeedController()) |
93 | { |
94 | Timer timer; |
95 | @@ -1221,6 +1257,11 @@ |
96 | } |
97 | } |
98 | |
99 | +CompRect UnityWindow::closeButtonArea () |
100 | +{ |
101 | + return close_button_area_; |
102 | +} |
103 | + |
104 | bool UnityScreen::shellCouldBeHidden(CompOutput const& output) |
105 | { |
106 | std::vector<Window> const& nuxwins(nux::XInputWindow::NativeHandleList()); |
107 | @@ -1588,6 +1629,24 @@ |
108 | launcher_controller_->KeyNavTerminate(false); |
109 | EnableCancelAction(CancelActionTarget::LAUNCHER_SWITCHER, false); |
110 | } |
111 | + if (PluginAdapter::Default()->IsScaleActive() && |
112 | + event->xbutton.button == Button1 && |
113 | + highlighted_window_ != 0) |
114 | + { |
115 | + CompWindow *w = screen->findWindow (highlighted_window_); |
116 | + if (w) |
117 | + { |
118 | + UnityWindow *uw = UnityWindow::get (w); |
119 | + CompPoint pointer (pointerX, pointerY); |
120 | + if (uw->closeButtonArea ().contains (pointer)) |
121 | + { |
122 | + w->close (0); |
123 | + skip_other_plugins = true; |
124 | + } |
125 | + } |
126 | + |
127 | + } |
128 | + |
129 | break; |
130 | case ButtonRelease: |
131 | if (switcher_controller_ && switcher_controller_->Visible()) |
132 | @@ -3409,9 +3468,11 @@ |
133 | , gWindow(GLWindow::get(window)) |
134 | , mMinimizeHandler() |
135 | , mShowdesktopHandler(nullptr) |
136 | + , window_header_style_(0) |
137 | { |
138 | WindowInterface::setHandler(window); |
139 | GLWindowInterface::setHandler(gWindow); |
140 | + ScaleWindowInterface::setHandler (ScaleWindow::get (window)); |
141 | |
142 | if (UnityScreen::get (screen)->optionGetShowMinimizedWindows () && |
143 | window->mapNum ()) |
144 | @@ -3456,6 +3517,292 @@ |
145 | } |
146 | } |
147 | |
148 | +void UnityWindow::DrawTexture (GLTexture* icon, |
149 | + const GLWindowPaintAttrib& attrib, |
150 | + const GLMatrix& transform, |
151 | + unsigned int mask, |
152 | + float x, float y, |
153 | + int &maxWidth, int &maxHeight) |
154 | +{ |
155 | + if (icon) |
156 | + { |
157 | + int width, height; |
158 | + width = icon->width (); |
159 | + height = icon->height (); |
160 | + |
161 | + if (height > maxHeight) |
162 | + maxHeight = height; |
163 | + |
164 | + if (width > maxWidth) |
165 | + maxWidth = width; |
166 | + |
167 | + CompRegion iconReg (0, 0, width, height); |
168 | + GLTexture::MatrixList ml (1); |
169 | + |
170 | + ml[0] = icon->matrix (); |
171 | + gWindow->vertexBuffer ()->begin (); |
172 | + if (width && height) |
173 | + gWindow->glAddGeometry (ml, iconReg, iconReg); |
174 | + |
175 | + if (gWindow->vertexBuffer ()->end ()) |
176 | + { |
177 | + GLMatrix wTransform (transform); |
178 | + |
179 | + wTransform.translate (x, y, 0.0f); |
180 | + |
181 | + gWindow->glDrawTexture (icon, wTransform, attrib, mask); |
182 | + } |
183 | + } |
184 | +} |
185 | + |
186 | +WindowCairoContext* UnityWindow::CreateCairoContext (float width, float height) |
187 | +{ |
188 | + XRenderPictFormat *format; |
189 | + Screen *xScreen; |
190 | + WindowCairoContext *context = new WindowCairoContext(); |
191 | + |
192 | + xScreen = ScreenOfDisplay (screen->dpy (), screen->screenNum ()); |
193 | + |
194 | + format = XRenderFindStandardFormat (screen->dpy (), PictStandardARGB32); |
195 | + context->pixmap_ = XCreatePixmap (screen->dpy (), |
196 | + screen->root (), |
197 | + width, height, 32); |
198 | + |
199 | + context->texture_ = GLTexture::bindPixmapToTexture (context->pixmap_, |
200 | + width, height, |
201 | + 32); |
202 | + if (context->texture_.empty ()) |
203 | + { |
204 | + delete context; |
205 | + return 0; |
206 | + } |
207 | + |
208 | + context->surface_ = cairo_xlib_surface_create_with_xrender_format (screen->dpy (), |
209 | + context->pixmap_, |
210 | + xScreen, |
211 | + format, |
212 | + width, |
213 | + height); |
214 | + context->cr_ = cairo_create (context->surface_); |
215 | + |
216 | + // clear |
217 | + cairo_save (context->cr_); |
218 | + cairo_set_operator (context->cr_, CAIRO_OPERATOR_CLEAR); |
219 | + cairo_paint (context->cr_); |
220 | + cairo_restore (context->cr_); |
221 | + |
222 | + return context; |
223 | +} |
224 | + |
225 | +void UnityWindow::RenderText (WindowCairoContext *context, |
226 | + float x, float y, |
227 | + float maxWidth, float maxHeight) |
228 | +{ |
229 | + PangoFontDescription* font = pango_font_description_new (); |
230 | + pango_font_description_set_family (font, "sans"); |
231 | + pango_font_description_set_absolute_size (font, 12 * PANGO_SCALE); |
232 | + pango_font_description_set_style (font, PANGO_STYLE_NORMAL); |
233 | + pango_font_description_set_weight (font, PANGO_WEIGHT_BOLD); |
234 | + |
235 | + PangoLayout* layout = pango_cairo_create_layout (context->cr_); |
236 | + pango_layout_set_font_description (layout, font); |
237 | + pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); |
238 | + pango_layout_set_height (layout, maxHeight); |
239 | + |
240 | + pango_layout_set_auto_dir (layout, false); |
241 | + pango_layout_set_text (layout, |
242 | + GetWindowName (window->id ()).c_str (), |
243 | + -1); |
244 | + |
245 | + /* update the size of the pango layout */ |
246 | + pango_layout_set_width (layout, maxWidth * PANGO_SCALE); |
247 | + pango_cairo_update_layout (context->cr_, layout); |
248 | + |
249 | + cairo_set_operator (context->cr_, CAIRO_OPERATOR_OVER); |
250 | + |
251 | + cairo_set_source_rgba (context->cr_, |
252 | + 1.0, |
253 | + 1.0, |
254 | + 1.0, |
255 | + 1.0); |
256 | + |
257 | + // alignment |
258 | + int lWidth, lHeight; |
259 | + pango_layout_get_pixel_size (layout, &lWidth, &lHeight); |
260 | + |
261 | + y = ((maxHeight - lHeight) / 2.0) + y; |
262 | + cairo_translate (context->cr_, x, y); |
263 | + pango_cairo_show_layout (context->cr_, layout); |
264 | +} |
265 | + |
266 | +void UnityWindow::DrawWindowTitle (const GLWindowPaintAttrib& attrib, |
267 | + const GLMatrix& transform, |
268 | + unsigned int mask, |
269 | + float x, float y, float x2, float y2) |
270 | +{ |
271 | + const float width = x2 - x; |
272 | + |
273 | + // Paint a fake window decoration |
274 | + WindowCairoContext *context = CreateCairoContext (width, SCALE_WINDOW_TITLE_SIZE); |
275 | + |
276 | + cairo_save (context->cr_); |
277 | + cairo_push_group (context->cr_); |
278 | + |
279 | + // Round window decoration top border |
280 | + const double height = SCALE_WINDOW_TITLE_SIZE; |
281 | + const double aspect = 1.0; |
282 | + const double corner_radius = height / 10.0; |
283 | + const double radius = corner_radius / aspect; |
284 | + const double degrees = M_PI / 180.0; |
285 | + |
286 | + cairo_new_sub_path (context->cr_); |
287 | + |
288 | + cairo_arc (context->cr_, radius, radius, radius, 180 * degrees, 270 * degrees); |
289 | + cairo_arc (context->cr_, width - radius, radius, radius, -90 * degrees, 0 * degrees); |
290 | + cairo_line_to (context->cr_, width, height); |
291 | + cairo_line_to (context->cr_, 0, height); |
292 | + |
293 | + cairo_close_path (context->cr_); |
294 | + cairo_clip (context->cr_); |
295 | + |
296 | + // Draw window decoration abased on gtk style |
297 | + gtk_render_background (window_header_style_, context->cr_, 0, 0, width, SCALE_WINDOW_TITLE_SIZE); |
298 | + gtk_render_frame (window_header_style_, context->cr_, 0, 0, width, SCALE_WINDOW_TITLE_SIZE); |
299 | + |
300 | + cairo_pop_group_to_source (context->cr_); |
301 | + |
302 | + cairo_paint_with_alpha (context->cr_, 1.0); |
303 | + cairo_restore (context->cr_); |
304 | + |
305 | + // Draw windows title |
306 | + RenderText (context, |
307 | + CLOSE_ICON_SPACE * 2 + CLOSE_ICON_SIZE, |
308 | + 0.0, |
309 | + width, SCALE_WINDOW_TITLE_SIZE); |
310 | + |
311 | + mask |= PAINT_WINDOW_BLEND_MASK; |
312 | + int maxWidth, maxHeight; |
313 | + foreach(GLTexture *icon, context->texture_) |
314 | + { |
315 | + DrawTexture (icon, attrib, transform, mask, |
316 | + x, y, |
317 | + maxWidth , maxHeight); |
318 | + } |
319 | + |
320 | + delete context; |
321 | +} |
322 | + |
323 | +void UnityWindow::scalePaintDecoration (const GLWindowPaintAttrib& attrib, |
324 | + const GLMatrix& transform, |
325 | + const CompRegion& region, |
326 | + unsigned int mask) |
327 | +{ |
328 | + ScaleWindow *sWindow = ScaleWindow::get (window); |
329 | + if (!sWindow) |
330 | + return; |
331 | + |
332 | + sWindow->scalePaintDecoration (attrib, transform, region, mask); |
333 | + |
334 | + if (!sWindow->hasSlot()) // animation not finished |
335 | + return; |
336 | + |
337 | + if (!window_header_style_) |
338 | + { |
339 | + GtkWidgetPath* widget_path = gtk_widget_path_new (); |
340 | + gint pos = gtk_widget_path_append_type (widget_path, GTK_TYPE_WINDOW); |
341 | + gtk_widget_path_iter_set_name (widget_path, pos, "UnityPanelWidget"); |
342 | + |
343 | + window_header_style_ = gtk_style_context_new (); |
344 | + gtk_style_context_set_path (window_header_style_, widget_path); |
345 | + gtk_style_context_add_class (window_header_style_, "gnome-panel-menu-bar"); |
346 | + gtk_style_context_add_class (window_header_style_, "unity-panel"); |
347 | + |
348 | + // get close button |
349 | + panel::Style& style = panel::Style::Instance(); |
350 | + |
351 | + std::vector<std::string> files = style.GetWindowButtonFileNames (panel::WindowButtonType::CLOSE, |
352 | + panel::WindowState::NORMAL); |
353 | + |
354 | + CompString pName ("unityshell"); |
355 | + foreach (std::string file, files) |
356 | + { |
357 | + CompString fileName (file.c_str ()); |
358 | + CompSize size (CLOSE_ICON_SIZE, CLOSE_ICON_SIZE); |
359 | + close_icon_ = GLTexture::readImageToTexture (fileName, |
360 | + pName, |
361 | + size); |
362 | + if (close_icon_.size () != 0) |
363 | + break; |
364 | + } |
365 | + |
366 | + if (close_icon_.size () == 0) |
367 | + { |
368 | + CompString fileName (PKGDATADIR"/close_dash.png"); |
369 | + CompSize size (CLOSE_ICON_SIZE, CLOSE_ICON_SIZE); |
370 | + close_icon_ = GLTexture::readImageToTexture (fileName, |
371 | + pName, |
372 | + size); |
373 | + } |
374 | + } |
375 | + |
376 | + // Make the windows header opaque to override the original |
377 | + GLWindowPaintAttrib sAttrib (attrib); |
378 | + sAttrib.opacity = OPAQUE; |
379 | + |
380 | + ScalePosition pos = sWindow->getCurrentPosition (); |
381 | + int maxHeight, maxWidth; |
382 | + // Use "2" as margin to make sure to cover all originial decoration |
383 | + const float width = (window->width () + 4) * pos.scale; |
384 | + const float x = pos.x () + window->x () - (2 * pos.scale); |
385 | + const float y = pos.y () + window->y () - SCALE_WINDOW_TITLE_SIZE; |
386 | + const float iconX = x + CLOSE_ICON_SPACE; |
387 | + const float iconY = y + ((SCALE_WINDOW_TITLE_SIZE - CLOSE_ICON_SIZE) / 2.0); |
388 | + |
389 | + maxHeight = maxWidth = 0; |
390 | + |
391 | + DrawWindowTitle (sAttrib, |
392 | + transform, |
393 | + mask, |
394 | + x, y, |
395 | + x + width, y + SCALE_WINDOW_TITLE_SIZE); |
396 | + |
397 | + mask |= PAINT_WINDOW_BLEND_MASK; |
398 | + foreach(GLTexture *icon, close_icon_) |
399 | + { |
400 | + DrawTexture (icon, sAttrib, transform, mask, |
401 | + iconX, iconY, |
402 | + maxWidth , maxHeight); |
403 | + } |
404 | + |
405 | + close_button_area_ = CompRect (iconX, iconY, maxWidth, maxHeight); |
406 | +} |
407 | + |
408 | +void UnityWindow::scaleSelectWindow () |
409 | +{ |
410 | + UnityScreen* us = UnityScreen::get(screen); |
411 | + |
412 | + if (us->highlighted_window_ != window->id ()) |
413 | + { |
414 | + CompositeWindow *cWindow = CompositeWindow::get (window); |
415 | + if (cWindow) |
416 | + cWindow->addDamage (); |
417 | + |
418 | + cWindow = 0; |
419 | + CompWindow *old_window = screen->findWindow (us->highlighted_window_); |
420 | + if (old_window) |
421 | + cWindow = CompositeWindow::get (old_window); |
422 | + |
423 | + if (cWindow) |
424 | + cWindow->addDamage (); |
425 | + |
426 | + us->highlighted_window_ = window->id (); |
427 | + } |
428 | + |
429 | + ScaleWindow *sWindow = ScaleWindow::get (window); |
430 | + if (sWindow) |
431 | + sWindow->scaleSelectWindow (); |
432 | +} |
433 | + |
434 | UnityWindow::~UnityWindow() |
435 | { |
436 | UnityScreen* us = UnityScreen::get(screen); |
437 | @@ -3474,6 +3821,9 @@ |
438 | window->minimize (); |
439 | } |
440 | |
441 | + if (window_header_style_) |
442 | + g_object_unref (window_header_style_); |
443 | + |
444 | ShowdesktopHandler::animating_windows.remove (static_cast <ShowdesktopHandlerWindowInterface *> (this)); |
445 | |
446 | if (mShowdesktopHandler) |
447 | @@ -3513,6 +3863,84 @@ |
448 | return true; |
449 | } |
450 | |
451 | +CompString UnityWindow::GetUtf8Property (Window id, |
452 | + Atom atom) |
453 | +{ |
454 | + Atom type; |
455 | + int result, format; |
456 | + unsigned long nItems, bytesAfter; |
457 | + char *val; |
458 | + CompString retval; |
459 | + Atom utf8StringAtom; |
460 | + |
461 | + utf8StringAtom = XInternAtom (screen->dpy (), "UTF8_STRING", 0); |
462 | + result = XGetWindowProperty (screen->dpy (), id, atom, 0L, 65536, False, |
463 | + utf8StringAtom, &type, &format, &nItems, |
464 | + &bytesAfter, (unsigned char **) &val); |
465 | + |
466 | + if (result != Success) |
467 | + return retval; |
468 | + |
469 | + if (type == utf8StringAtom && format == 8 && val && nItems > 0) |
470 | + { |
471 | + char valueString[nItems + 1]; |
472 | + strncpy (valueString, val, nItems); |
473 | + valueString[nItems] = 0; |
474 | + retval = valueString; |
475 | + } |
476 | + if (val) |
477 | + XFree (val); |
478 | + |
479 | + return retval; |
480 | +} |
481 | + |
482 | +CompString UnityWindow::GetTextProperty (Window id, |
483 | + Atom atom) |
484 | +{ |
485 | + XTextProperty text; |
486 | + CompString retval; |
487 | + |
488 | + text.nitems = 0; |
489 | + if (XGetTextProperty (screen->dpy (), id, &text, atom)) |
490 | + { |
491 | + if (text.value) |
492 | + { |
493 | + char valueString[text.nitems + 1]; |
494 | + |
495 | + strncpy (valueString, (char *) text.value, text.nitems); |
496 | + valueString[text.nitems] = 0; |
497 | + |
498 | + retval = valueString; |
499 | + |
500 | + XFree (text.value); |
501 | + } |
502 | + } |
503 | + |
504 | + return retval; |
505 | +} |
506 | + |
507 | + |
508 | +CompString UnityWindow::GetWindowName (Window id) |
509 | +{ |
510 | + CompString name; |
511 | + Atom visibleNameAtom; |
512 | + |
513 | + visibleNameAtom = XInternAtom (screen->dpy (), "_NET_WM_VISIBLE_NAME", 0); |
514 | + name = GetUtf8Property (id, visibleNameAtom); |
515 | + if (name.empty ()) |
516 | + { |
517 | + Atom wmNameAtom = XInternAtom (screen->dpy (), "_NET_WM_NAME", 0); |
518 | + name = GetUtf8Property (id, wmNameAtom); |
519 | + } |
520 | + |
521 | + |
522 | + if (name.empty ()) |
523 | + name = GetTextProperty (id, XA_WM_NAME); |
524 | + |
525 | + return name; |
526 | +} |
527 | + |
528 | + |
529 | |
530 | namespace |
531 | { |
532 | |
533 | === modified file 'plugins/unityshell/src/unityshell.h' |
534 | --- plugins/unityshell/src/unityshell.h 2012-08-27 13:51:29 +0000 |
535 | +++ plugins/unityshell/src/unityshell.h 2012-08-31 13:28:34 +0000 |
536 | @@ -29,6 +29,7 @@ |
537 | #include <sigc++/sigc++.h> |
538 | #include <boost/shared_ptr.hpp> |
539 | |
540 | +#include <scale/scale.h> |
541 | #include <core/core.h> |
542 | #include <core/pluginclasshandler.h> |
543 | #include <composite/composite.h> |
544 | @@ -70,6 +71,8 @@ |
545 | namespace unity |
546 | { |
547 | |
548 | +class WindowCairoContext; |
549 | + |
550 | /* base screen class */ |
551 | class UnityScreen : |
552 | public unity::debug::Introspectable, |
553 | @@ -344,8 +347,9 @@ |
554 | glib::SourceManager sources_; |
555 | unity::ThumbnailGenerator thumb_generator; |
556 | |
557 | + Window highlighted_window_; |
558 | + |
559 | WindowMinimizeSpeedController* minimize_speed_controller; |
560 | - |
561 | friend class UnityWindow; |
562 | }; |
563 | |
564 | @@ -354,6 +358,7 @@ |
565 | public GLWindowInterface, |
566 | public ShowdesktopHandlerWindowInterface, |
567 | public compiz::WindowInputRemoverLockAcquireInterface, |
568 | + public WrapableHandler<ScaleWindowInterface, 4>, |
569 | public BaseSwitchWindow, |
570 | public PluginClassHandler <UnityWindow, CompWindow> |
571 | { |
572 | @@ -414,6 +419,8 @@ |
573 | |
574 | void handleEvent (XEvent *event); |
575 | |
576 | + CompRect closeButtonArea (); |
577 | + |
578 | typedef compiz::CompizMinimizedWindowHandler<UnityScreen, UnityWindow> |
579 | UnityMinimizedHandler; |
580 | std::unique_ptr <UnityMinimizedHandler> mMinimizeHandler; |
581 | @@ -422,6 +429,13 @@ |
582 | |
583 | //! Emited when CompWindowNotifyBeforeDestroy is received |
584 | sigc::signal<void> being_destroyed; |
585 | + |
586 | + void scaleSelectWindow (); |
587 | + void scalePaintDecoration (const GLWindowPaintAttrib &, |
588 | + const GLMatrix &, |
589 | + const CompRegion &, |
590 | + unsigned int); |
591 | + |
592 | private: |
593 | void DoEnableFocus (); |
594 | void DoDisableFocus (); |
595 | @@ -453,8 +467,32 @@ |
596 | |
597 | compiz::WindowInputRemoverLock::Ptr GetInputRemover (); |
598 | |
599 | + void DrawWindowTitle (const GLWindowPaintAttrib& attrib, |
600 | + const GLMatrix& transform, |
601 | + unsigned int mask, |
602 | + float x, float y, float x2, float y2); |
603 | + void DrawTexture (GLTexture *icon, |
604 | + const GLWindowPaintAttrib& attrib, |
605 | + const GLMatrix& transform, |
606 | + unsigned int mask, |
607 | + float x, float y, |
608 | + int &maxWidth, int &maxHeight); |
609 | + void RenderText (WindowCairoContext *context, |
610 | + float x, float y, |
611 | + float maxWidth, float maxHeight); |
612 | + WindowCairoContext* CreateCairoContext (float width, float height); |
613 | + |
614 | + // based on compiz text plugin |
615 | + CompString GetWindowName (Window id); |
616 | + CompString GetUtf8Property (Window id, Atom atom); |
617 | + CompString GetTextProperty (Window id, Atom atom); |
618 | + |
619 | compiz::WindowInputRemoverLock::Weak input_remover_; |
620 | glib::Source::UniquePtr focus_desktop_timeout_; |
621 | + |
622 | + GLTexture::List close_icon_; |
623 | + CompRect close_button_area_; |
624 | + GtkStyleContext* window_header_style_; |
625 | }; |
626 | |
627 | |
628 | |
629 | === modified file 'unity-shared/PanelStyle.cpp' |
630 | --- unity-shared/PanelStyle.cpp 2012-08-01 20:46:31 +0000 |
631 | +++ unity-shared/PanelStyle.cpp 2012-08-31 13:28:34 +0000 |
632 | @@ -182,9 +182,17 @@ |
633 | return context.GetBitmap(); |
634 | } |
635 | |
636 | -nux::BaseTexture* Style::GetWindowButton(WindowButtonType type, WindowState state) |
637 | +/*! |
638 | + Return a vector with the possible file names sorted by priority |
639 | + |
640 | + @param type The type of the button. |
641 | + @param state The button state. |
642 | + |
643 | + @return A vector of strings with the possible file names sorted by priority. |
644 | +*/ |
645 | +std::vector<std::string> Style::GetWindowButtonFileNames(WindowButtonType type, WindowState state) |
646 | { |
647 | - nux::BaseTexture* texture = NULL; |
648 | + std::vector<std::string> files; |
649 | std::string names[] = { "close", "minimize", "unmaximize", "maximize" }; |
650 | std::string states[] = { "", "_focused_prelight", "_focused_pressed", "_unfocused", |
651 | "_unfocused", "_unfocused_prelight", "_unfocused_pressed"}; |
652 | @@ -200,38 +208,40 @@ |
653 | glib::String filename(g_build_filename(home_dir, ".themes", _theme_name.c_str(), subpath.str().c_str(), NULL)); |
654 | |
655 | if (g_file_test(filename.Value(), G_FILE_TEST_EXISTS)) |
656 | - { |
657 | - glib::Error error; |
658 | - |
659 | - // Found a file, try loading the pixbuf |
660 | - glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file(filename.Value(), &error)); |
661 | - if (error) |
662 | - LOG_WARNING(logger) << "Unable to load window button " << filename.Value() << ": " << error.Message(); |
663 | - else |
664 | - texture = nux::CreateTexture2DFromPixbuf(pixbuf, true); |
665 | - } |
666 | + files.push_back (filename.Value()); |
667 | } |
668 | |
669 | - // texture is NULL if the pixbuf is not loaded |
670 | - if (!texture) |
671 | + const char* var = g_getenv("GTK_DATA_PREFIX"); |
672 | + if (!var) |
673 | + var = "/usr"; |
674 | + |
675 | + glib::String filename(g_build_filename(var, "share", "themes", _theme_name.c_str(), subpath.str().c_str(), NULL)); |
676 | + if (g_file_test(filename.Value(), G_FILE_TEST_EXISTS)) |
677 | + files.push_back (filename.Value()); |
678 | + |
679 | + return files; |
680 | +} |
681 | + |
682 | +nux::BaseTexture* Style::GetWindowButton(WindowButtonType type, WindowState state) |
683 | +{ |
684 | + nux::BaseTexture* texture = NULL; |
685 | + |
686 | + std::vector<std::string> files = GetWindowButtonFileNames (type, state); |
687 | + for (unsigned int i=0; i < files.size(); i++) |
688 | { |
689 | - const char* var = g_getenv("GTK_DATA_PREFIX"); |
690 | - if (!var) |
691 | - var = "/usr"; |
692 | - |
693 | - glib::String filename(g_build_filename(var, "share", "themes", _theme_name.c_str(), subpath.str().c_str(), NULL)); |
694 | - |
695 | - if (g_file_test(filename.Value(), G_FILE_TEST_EXISTS)) |
696 | - { |
697 | glib::Error error; |
698 | - |
699 | - // Found a file, try loading the pixbuf |
700 | - glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file(filename.Value(), &error)); |
701 | + // Try loading the pixbuf |
702 | + glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file(files[i].c_str (), &error)); |
703 | if (error) |
704 | - LOG_WARNING(logger) << "Unable to load window button " << filename.Value() << ": " << error.Message(); |
705 | + { |
706 | + LOG_WARNING(logger) << "Unable to load window button " << files[i] << ": " << error.Message(); |
707 | + } |
708 | else |
709 | + { |
710 | texture = nux::CreateTexture2DFromPixbuf(pixbuf, true); |
711 | - } |
712 | + if (texture) |
713 | + break; |
714 | + } |
715 | } |
716 | |
717 | if (!texture) |
718 | |
719 | === modified file 'unity-shared/PanelStyle.h' |
720 | --- unity-shared/PanelStyle.h 2012-08-01 20:46:31 +0000 |
721 | +++ unity-shared/PanelStyle.h 2012-08-31 13:28:34 +0000 |
722 | @@ -71,6 +71,7 @@ |
723 | GtkStyleContext* GetStyleContext(); |
724 | nux::NBitmapData* GetBackground(int width, int height, float opacity); |
725 | nux::BaseTexture* GetWindowButton(WindowButtonType type, WindowState state); |
726 | + std::vector<std::string> GetWindowButtonFileNames(WindowButtonType type, WindowState state); |
727 | nux::BaseTexture* GetFallbackWindowButton(WindowButtonType type, WindowState state); |
728 | glib::Object<GdkPixbuf> GetHomeButton(); |
729 | std::string GetFontDescription(PanelItem item); |
Right approach, some pointers:
76 +// Based on Scale plugin code :checkForWindow At (int x, int y) :reverse_ iterator rit = screen->windows ().rbegin (); osition ();
77 +CompWindow* UnityScreen:
78 +{
79 + int x1, y1, x2, y2;
80 + CompWindowList:
81 +
82 + for (; rit != screen->windows ().rend (); ++rit)
83 + {
84 + CompWindow *w = *rit;
85 + SCALE_WINDOW (w);
86 +
87 + ScalePosition pos = sw->getCurrentP
88 + if (sw->hasSlot ())
89 + {
90 + x1 = w->x () - w->input ().left * pos.scale;
91 + y1 = w->y () - w->input ().top * pos.scale;
92 + x2 = w->x () + (w->width () + w->input ().right) * pos.scale;
93 + y2 = w->y () + (w->height () + w->input ().bottom) * pos.scale;
94 + x1 += pos.x ();
95 + y1 += pos.y ();
96 + x2 += pos.x ();
97 + y2 += pos.y ();
98 + if (x1 <= x && y1 <= y && x2 > x && y2 > y)
99 + return w;
100 + }
101 + }
102 + return NULL;
103 +}
Is this necessary?
I think you can just overload scaleSelectWindow to determine what the currently hovered window is. From there you will need to damage and re-render both the new and old window. Have a look at the scaleaddon plugin.
151 + gWindow->geometry ().reset (); >glAddGeometry (ml, iconReg, iconReg); translate (x, y, 0.0f); getMatrix ()); >glDrawTexture (icon, fragment, mask);
152 + if (width && height)
153 + gWindow-
154 +
155 + if (gWindow->geometry ().vCount)
156 + {
157 + GLFragment::Attrib fragment (attrib);
158 + GLMatrix wTransform (transform);
159 +
160 + wTransform.
161 +
162 + glPushMatrix ();
163 + glLoadMatrixf (wTransform.
164 + gWindow-
165 + glPopMatrix ();
166 + }
You will need to put this inside of #if USE_MODERN_ COMPIZ_ GL ifdefs. Sorry :( Here's how to do it:
#ifdef USE_MODERN_ COMPIZ_ GL >vertexBuffer ()->begin (); >glAddGeometry (ml, iconReg, iconReg); COMPIZ_ GL >vertexBuffer ().end (); >vertexBuffer ().countVertices ()) COMPIZ_ GL translate (x, y, 0.0f); COMPIZ_ GL >glDrawTexture (icon, wTransform, attrib, mask); getMatrix ()); >glDrawTexture (icon, fragment, mask);
gWindow-
#else
151 + gWindow->geometry ().reset ();
#endif
152 + if (width && height)
153 + gWindow-
154 +
#ifdef USE_MODERN_
gWindow-
if (gWindow-
#else
155 + if (gWindow->geometry ().vCount)
#endif
156 + {
#ifdef USE_MODERN_
157 + GLFragment::Attrib fragment (attrib);
#endif
158 + GLMatrix wTransform (transform);
159 +
160 + wTransform.
161 +
#ifdef USE_MODERN_
gWindow-
#else
162 + glPushMatrix ();
163 + glLoadMatrixf (wTransform.
164 + gWindow-
165 + glPopMatrix ();
#endif
166 + }
172 + // BG
173 + glColor3f (0.0f, 0.0f, 0.0f);
174 + glRectf (x, y2, x2, y);
Preferably use client side buffers for this, eg
#ifndef USE_MODERN_ COMPIZ_ GL :streamingBuffe r ();
172 + // BG
173 + glColor3f (0.0f, 0.0f, 0.0f);
174 + glRectf (x, y2, x2, y);
#else
GLVertexBuffer *vertexBuffer = GLVertexBuffer:
vertexBuffer->begin (GL_TRIANGLE_STRIP)
const GLfloat vertices[] =
{
x, y2, 0.0f,
x, y, 0.0f,
x2, y, 0.0f,
x2, y2, 0.0f
};
vertexBuffer- >addVertices (4, vertices); >color4f (0.0f, 0.0f, 0.0f, 1.0f); >render (transform, attrib);
vertexBuffer-
vertexBuffer->end ();
vertexBuffer-
209 + x + CLOSE_ICON_SPACE, iconY,
210 + maxWidth , maxHeight);
Make this a constant
190 + if (!sWindow- >hasSlot( ) || // animation finished
191 + ...