Merge lp:~3v1n0/unity/scale-close-middle-click-6.0 into lp:unity/6.0
- scale-close-middle-click-6.0
- Merge into 6.0
Proposed by
Marco Trevisan (Treviño)
Status: | Merged |
---|---|
Approved by: | Brandon Schaefer |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2737 |
Proposed branch: | lp:~3v1n0/unity/scale-close-middle-click-6.0 |
Merge into: | lp:unity/6.0 |
Diff against target: |
1018 lines (+472/-175) 6 files modified
plugins/unityshell/src/ScreenIntrospection.h (+48/-0) plugins/unityshell/src/unityshell.cpp (+223/-156) plugins/unityshell/src/unityshell.h (+23/-19) tests/autopilot/unity/emulators/screen.py (+42/-0) tests/autopilot/unity/tests/__init__.py (+12/-0) tests/autopilot/unity/tests/test_spread.py (+124/-0) |
To merge this branch: | bzr merge lp:~3v1n0/unity/scale-close-middle-click-6.0 |
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brandon Schaefer (community) | Approve | ||
Review via email: mp+126077@code.launchpad.net |
Commit message
UnityShell: enable closing on middle-click, fix scaled decoration sizes, fix theming issues, added scale autopilot tests
Description of the change
Backporting branch lp:~3v1n0/unity/scale-close-middle-click/+merge/126044
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'plugins/unityshell/src/ScreenIntrospection.h' | |||
2 | --- plugins/unityshell/src/ScreenIntrospection.h 1970-01-01 00:00:00 +0000 | |||
3 | +++ plugins/unityshell/src/ScreenIntrospection.h 2012-09-24 19:39:25 +0000 | |||
4 | @@ -0,0 +1,48 @@ | |||
5 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
6 | 2 | /* | ||
7 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
8 | 4 | * | ||
9 | 5 | * This program is free software: you can redistribute it and/or modify | ||
10 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
11 | 7 | * published by the Free Software Foundation. | ||
12 | 8 | * | ||
13 | 9 | * This program is distributed in the hope that it will be useful, | ||
14 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | 12 | * GNU General Public License for more details. | ||
17 | 13 | * | ||
18 | 14 | * You should have received a copy of the GNU General Public License | ||
19 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | 16 | * | ||
21 | 17 | * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com> | ||
22 | 18 | */ | ||
23 | 19 | |||
24 | 20 | #ifndef SCREEN_INTROSPECTION_H | ||
25 | 21 | #define SCREEN_INTROSPECTION_H | ||
26 | 22 | |||
27 | 23 | #include "Introspectable.h" | ||
28 | 24 | #include <core/core.h> | ||
29 | 25 | |||
30 | 26 | namespace unity | ||
31 | 27 | { | ||
32 | 28 | namespace debug | ||
33 | 29 | { | ||
34 | 30 | |||
35 | 31 | class ScreenIntrospection : public Introspectable | ||
36 | 32 | { | ||
37 | 33 | public: | ||
38 | 34 | ScreenIntrospection(CompScreen* screen); | ||
39 | 35 | |||
40 | 36 | protected: | ||
41 | 37 | std::string GetName() const; | ||
42 | 38 | void AddProperties(GVariantBuilder* builder); | ||
43 | 39 | IntrospectableList GetIntrospectableChildren(); | ||
44 | 40 | |||
45 | 41 | private: | ||
46 | 42 | CompScreen* screen_; | ||
47 | 43 | }; | ||
48 | 44 | |||
49 | 45 | } | ||
50 | 46 | } | ||
51 | 47 | |||
52 | 48 | #endif | ||
53 | 0 | 49 | ||
54 | === modified file 'plugins/unityshell/src/unityshell.cpp' | |||
55 | --- plugins/unityshell/src/unityshell.cpp 2012-09-19 13:58:01 +0000 | |||
56 | +++ plugins/unityshell/src/unityshell.cpp 2012-09-24 19:39:25 +0000 | |||
57 | @@ -26,6 +26,8 @@ | |||
58 | 26 | #include <Nux/WindowCompositor.h> | 26 | #include <Nux/WindowCompositor.h> |
59 | 27 | #include <Nux/NuxTimerTickSource.h> | 27 | #include <Nux/NuxTimerTickSource.h> |
60 | 28 | 28 | ||
61 | 29 | #include <UnityCore/Variant.h> | ||
62 | 30 | |||
63 | 29 | #include "BaseWindowRaiserImp.h" | 31 | #include "BaseWindowRaiserImp.h" |
64 | 30 | #include "IconRenderer.h" | 32 | #include "IconRenderer.h" |
65 | 31 | #include "Launcher.h" | 33 | #include "Launcher.h" |
66 | @@ -125,7 +127,6 @@ | |||
67 | 125 | , allowWindowPaint(false) | 127 | , allowWindowPaint(false) |
68 | 126 | , _key_nav_mode_requested(false) | 128 | , _key_nav_mode_requested(false) |
69 | 127 | , _last_output(nullptr) | 129 | , _last_output(nullptr) |
70 | 128 | , _bghash(NULL) | ||
71 | 129 | , grab_index_ (0) | 130 | , grab_index_ (0) |
72 | 130 | , painting_tray_ (false) | 131 | , painting_tray_ (false) |
73 | 131 | , last_scroll_event_(0) | 132 | , last_scroll_event_(0) |
74 | @@ -133,7 +134,7 @@ | |||
75 | 133 | , panel_texture_has_changed_(true) | 134 | , panel_texture_has_changed_(true) |
76 | 134 | , paint_panel_(false) | 135 | , paint_panel_(false) |
77 | 135 | , scale_just_activated_(false) | 136 | , scale_just_activated_(false) |
79 | 136 | , minimize_speed_controller(new WindowMinimizeSpeedController()) | 137 | , screen_introspection_(screen) |
80 | 137 | { | 138 | { |
81 | 138 | Timer timer; | 139 | Timer timer; |
82 | 139 | #ifndef USE_GLES | 140 | #ifndef USE_GLES |
83 | @@ -244,7 +245,7 @@ | |||
84 | 244 | // _bghash is a pointer. We don't want it to be created before Nux system has had a chance | 245 | // _bghash is a pointer. We don't want it to be created before Nux system has had a chance |
85 | 245 | // to start. BGHash relies on animations. Nux animation system starts after the WindowThread | 246 | // to start. BGHash relies on animations. Nux animation system starts after the WindowThread |
86 | 246 | // has been created. | 247 | // has been created. |
88 | 247 | _bghash = new BGHash(); | 248 | _bghash.reset(new BGHash()); |
89 | 248 | 249 | ||
90 | 249 | unity_a11y_init(wt.get()); | 250 | unity_a11y_init(wt.get()); |
91 | 250 | 251 | ||
92 | @@ -375,13 +376,15 @@ | |||
93 | 375 | Display* display = gdk_x11_display_get_xdisplay(gdk_display_get_default());; | 376 | Display* display = gdk_x11_display_get_xdisplay(gdk_display_get_default());; |
94 | 376 | XSelectInput(display, GDK_ROOT_WINDOW(), PropertyChangeMask); | 377 | XSelectInput(display, GDK_ROOT_WINDOW(), PropertyChangeMask); |
95 | 377 | LOG_INFO(logger) << "UnityScreen constructed: " << timer.ElapsedSeconds() << "s"; | 378 | LOG_INFO(logger) << "UnityScreen constructed: " << timer.ElapsedSeconds() << "s"; |
96 | 379 | |||
97 | 380 | panel::Style::Instance().changed.connect(sigc::mem_fun(this, &UnityScreen::OnPanelStyleChanged)); | ||
98 | 381 | |||
99 | 382 | minimize_speed_controller_.DurationChanged.connect( | ||
100 | 383 | sigc::mem_fun(this, &UnityScreen::OnMinimizeDurationChanged) | ||
101 | 384 | ); | ||
102 | 385 | |||
103 | 386 | AddChild(&screen_introspection_); | ||
104 | 378 | } | 387 | } |
105 | 379 | |||
106 | 380 | panel::Style::Instance().changed.connect(sigc::mem_fun(this, &UnityScreen::OnPanelStyleChanged)); | ||
107 | 381 | |||
108 | 382 | minimize_speed_controller->DurationChanged.connect( | ||
109 | 383 | sigc::mem_fun(this, &UnityScreen::OnMinimizeDurationChanged) | ||
110 | 384 | ); | ||
111 | 385 | } | 388 | } |
112 | 386 | 389 | ||
113 | 387 | UnityScreen::~UnityScreen() | 390 | UnityScreen::~UnityScreen() |
114 | @@ -391,7 +394,6 @@ | |||
115 | 391 | unity_a11y_finalize(); | 394 | unity_a11y_finalize(); |
116 | 392 | ::unity::ui::IconRenderer::DestroyTextures(); | 395 | ::unity::ui::IconRenderer::DestroyTextures(); |
117 | 393 | QuicklistManager::Destroy(); | 396 | QuicklistManager::Destroy(); |
118 | 394 | delete _bghash; | ||
119 | 395 | 397 | ||
120 | 396 | reset_glib_logging(); | 398 | reset_glib_logging(); |
121 | 397 | } | 399 | } |
122 | @@ -659,10 +661,15 @@ | |||
123 | 659 | wy = y + (last_bound.height - height) / 2; | 661 | wy = y + (last_bound.height - height) / 2; |
124 | 660 | } | 662 | } |
125 | 661 | 663 | ||
128 | 662 | void | 664 | void UnityScreen::OnPanelStyleChanged() |
127 | 663 | UnityScreen::OnPanelStyleChanged() | ||
129 | 664 | { | 665 | { |
130 | 665 | panel_texture_has_changed_ = true; | 666 | panel_texture_has_changed_ = true; |
131 | 667 | |||
132 | 668 | // Reload the windows themed textures | ||
133 | 669 | UnityWindow::CleanupSharedTextures(); | ||
134 | 670 | |||
135 | 671 | if (WindowManager::Default()->IsScaleActive()) | ||
136 | 672 | UnityWindow::SetupSharedTextures(); | ||
137 | 666 | } | 673 | } |
138 | 667 | 674 | ||
139 | 668 | void UnityScreen::paintDisplay() | 675 | void UnityScreen::paintDisplay() |
140 | @@ -1136,6 +1143,12 @@ | |||
141 | 1136 | DoAddDamage(); | 1143 | DoAddDamage(); |
142 | 1137 | handled = true; | 1144 | handled = true; |
143 | 1138 | } | 1145 | } |
144 | 1146 | else if (event->xbutton.button == Button2 && | ||
145 | 1147 | GetScaledGeometry().IsPointInside(event->xbutton.x_root, event->xbutton.y_root)) | ||
146 | 1148 | { | ||
147 | 1149 | middle_clicked_ = true; | ||
148 | 1150 | handled = true; | ||
149 | 1151 | } | ||
150 | 1139 | break; | 1152 | break; |
151 | 1140 | 1153 | ||
152 | 1141 | case ButtonRelease: | 1154 | case ButtonRelease: |
153 | @@ -1155,6 +1168,18 @@ | |||
154 | 1155 | 1168 | ||
155 | 1156 | handled = true; | 1169 | handled = true; |
156 | 1157 | } | 1170 | } |
157 | 1171 | |||
158 | 1172 | if (middle_clicked_) | ||
159 | 1173 | { | ||
160 | 1174 | if (event->xbutton.button == Button2 && | ||
161 | 1175 | GetScaledGeometry().IsPointInside(event->xbutton.x_root, event->xbutton.y_root)) | ||
162 | 1176 | { | ||
163 | 1177 | window->close(0); | ||
164 | 1178 | } | ||
165 | 1179 | |||
166 | 1180 | middle_clicked_ = false; | ||
167 | 1181 | handled = true; | ||
168 | 1182 | } | ||
169 | 1158 | } | 1183 | } |
170 | 1159 | break; | 1184 | break; |
171 | 1160 | 1185 | ||
172 | @@ -2277,8 +2302,7 @@ | |||
173 | 2277 | } | 2302 | } |
174 | 2278 | 2303 | ||
175 | 2279 | void UnityScreen::AddProperties(GVariantBuilder* builder) | 2304 | void UnityScreen::AddProperties(GVariantBuilder* builder) |
178 | 2280 | { | 2305 | {} |
177 | 2281 | } | ||
179 | 2282 | 2306 | ||
180 | 2283 | std::string UnityScreen::GetName() const | 2307 | std::string UnityScreen::GetName() const |
181 | 2284 | { | 2308 | { |
182 | @@ -2469,10 +2493,10 @@ | |||
183 | 2469 | CompOption::Value& value = o.value(); | 2493 | CompOption::Value& value = o.value(); |
184 | 2470 | CompOption::Value::Vector& list = value.list(); | 2494 | CompOption::Value::Vector& list = value.list(); |
185 | 2471 | CompOption::Value::Vector::iterator i = list.begin(); | 2495 | CompOption::Value::Vector::iterator i = list.begin(); |
190 | 2472 | if (i != list.end()) { | 2496 | if (i != list.end()) |
191 | 2473 | i->set(minimize_speed_controller->getDuration()); | 2497 | i->set(minimize_speed_controller_.getDuration()); |
192 | 2474 | } | 2498 | |
193 | 2475 | value.set(list); | 2499 | value.set(list); |
194 | 2476 | screen->setOptionForPlugin(p->vTable->name().c_str(), | 2500 | screen->setOptionForPlugin(p->vTable->name().c_str(), |
195 | 2477 | o.name().c_str(), value); | 2501 | o.name().c_str(), value); |
196 | 2478 | break; | 2502 | break; |
197 | @@ -2603,7 +2627,7 @@ | |||
198 | 2603 | case CompWindowNotifyMinimize: | 2627 | case CompWindowNotifyMinimize: |
199 | 2604 | /* Updating the count in dconf will trigger a "changed" signal to which | 2628 | /* Updating the count in dconf will trigger a "changed" signal to which |
200 | 2605 | * the method setting the new animation speed is attached */ | 2629 | * the method setting the new animation speed is attached */ |
202 | 2606 | UnityScreen::get(screen)->minimize_speed_controller->UpdateCount(); | 2630 | UnityScreen::get(screen)->minimize_speed_controller_.UpdateCount(); |
203 | 2607 | break; | 2631 | break; |
204 | 2608 | default: | 2632 | default: |
205 | 2609 | break; | 2633 | break; |
206 | @@ -3458,107 +3482,117 @@ | |||
207 | 3458 | WindowManager::Default()->terminate_spread.connect(sigc::mem_fun(this, &UnityWindow::OnTerminateSpreed)); | 3482 | WindowManager::Default()->terminate_spread.connect(sigc::mem_fun(this, &UnityWindow::OnTerminateSpreed)); |
208 | 3459 | } | 3483 | } |
209 | 3460 | 3484 | ||
219 | 3461 | void | 3485 | void UnityWindow::AddProperties(GVariantBuilder* builder) |
220 | 3462 | UnityWindow::DrawTexture(GLTexture* icon, | 3486 | { |
221 | 3463 | const GLWindowPaintAttrib& attrib, | 3487 | Window xid = window->id(); |
222 | 3464 | const GLMatrix& transform, | 3488 | auto const& swins = ScaleScreen::get(screen)->getWindows(); |
223 | 3465 | unsigned int mask, | 3489 | bool scaled = std::find(swins.begin(), swins.end(), ScaleWindow::get(window)) != swins.end(); |
224 | 3466 | float x, float y, | 3490 | auto wm = WindowManager::Default(); |
225 | 3467 | int &maxWidth, int &maxHeight) | 3491 | |
226 | 3468 | { | 3492 | variant::BuilderWrapper(builder) |
227 | 3469 | if (icon) | 3493 | .add(scaled ? GetScaledGeometry() : wm->GetWindowGeometry(xid)) |
228 | 3494 | .add("xid", xid) | ||
229 | 3495 | .add("title", wm->GetWindowName(xid)) | ||
230 | 3496 | .add("scaled", scaled) | ||
231 | 3497 | .add("scaled_close_x", close_button_geo_.x) | ||
232 | 3498 | .add("scaled_close_y", close_button_geo_.y) | ||
233 | 3499 | .add("scaled_close_width", close_button_geo_.width) | ||
234 | 3500 | .add("scaled_close_height", close_button_geo_.height); | ||
235 | 3501 | } | ||
236 | 3502 | |||
237 | 3503 | std::string UnityWindow::GetName() const | ||
238 | 3504 | { | ||
239 | 3505 | return "Window"; | ||
240 | 3506 | } | ||
241 | 3507 | |||
242 | 3508 | void UnityWindow::DrawTexture(GLTexture::List const& textures, GLWindowPaintAttrib const& attrib, | ||
243 | 3509 | GLMatrix const& transform, unsigned int mask, int x, int y) | ||
244 | 3510 | { | ||
245 | 3511 | for (auto const& texture : textures) | ||
246 | 3470 | { | 3512 | { |
261 | 3471 | int width, height; | 3513 | if (!texture) |
262 | 3472 | width = icon->width(); | 3514 | continue; |
263 | 3473 | height = icon->height(); | 3515 | |
250 | 3474 | |||
251 | 3475 | if (height > maxHeight) | ||
252 | 3476 | maxHeight = height; | ||
253 | 3477 | |||
254 | 3478 | if (width > maxWidth) | ||
255 | 3479 | maxWidth = width; | ||
256 | 3480 | |||
257 | 3481 | CompRegion iconReg(0, 0, width, height); | ||
258 | 3482 | GLTexture::MatrixList ml(1); | ||
259 | 3483 | |||
260 | 3484 | ml[0] = icon->matrix(); | ||
264 | 3485 | gWindow->vertexBuffer()->begin(); | 3516 | gWindow->vertexBuffer()->begin(); |
267 | 3486 | if (width && height) | 3517 | |
268 | 3487 | gWindow->glAddGeometry(ml, iconReg, iconReg); | 3518 | if (texture->width() && texture->height()) |
269 | 3519 | { | ||
270 | 3520 | GLTexture::MatrixList ml(1); | ||
271 | 3521 | ml[0] = texture->matrix(); | ||
272 | 3522 | CompRegion texture_region(0, 0, texture->width(), texture->height()); | ||
273 | 3523 | gWindow->glAddGeometry(ml, texture_region, texture_region); | ||
274 | 3524 | } | ||
275 | 3488 | 3525 | ||
276 | 3489 | if (gWindow->vertexBuffer()->end()) | 3526 | if (gWindow->vertexBuffer()->end()) |
277 | 3490 | { | 3527 | { |
278 | 3491 | GLMatrix wTransform(transform); | 3528 | GLMatrix wTransform(transform); |
279 | 3492 | |||
280 | 3493 | wTransform.translate(x, y, 0.0f); | 3529 | wTransform.translate(x, y, 0.0f); |
281 | 3494 | 3530 | ||
283 | 3495 | gWindow->glDrawTexture(icon, wTransform, attrib, mask); | 3531 | gWindow->glDrawTexture(texture, wTransform, attrib, mask); |
284 | 3496 | } | 3532 | } |
285 | 3497 | } | 3533 | } |
286 | 3498 | } | 3534 | } |
287 | 3499 | 3535 | ||
292 | 3500 | void | 3536 | void UnityWindow::RenderText(CairoContext const& context, int x, int y, int width, int height) |
289 | 3501 | UnityWindow::RenderText(UnityWindow::CairoContext const& context, | ||
290 | 3502 | float x, float y, | ||
291 | 3503 | float maxWidth, float maxHeight) | ||
293 | 3504 | { | 3537 | { |
294 | 3505 | panel::Style& style = panel::Style::Instance(); | 3538 | panel::Style& style = panel::Style::Instance(); |
296 | 3506 | std::string fontDescription(style.GetFontDescription(panel::PanelItem::TITLE)); | 3539 | std::string const& font_desc = style.GetFontDescription(panel::PanelItem::TITLE); |
297 | 3507 | 3540 | ||
298 | 3508 | glib::Object<PangoLayout> layout(pango_cairo_create_layout(context.cr_)); | 3541 | glib::Object<PangoLayout> layout(pango_cairo_create_layout(context.cr_)); |
300 | 3509 | std::shared_ptr<PangoFontDescription> font(pango_font_description_from_string(fontDescription.c_str()), | 3542 | std::shared_ptr<PangoFontDescription> font(pango_font_description_from_string(font_desc.c_str()), |
301 | 3510 | pango_font_description_free); | 3543 | pango_font_description_free); |
302 | 3511 | 3544 | ||
303 | 3512 | pango_layout_set_font_description(layout, font.get()); | 3545 | pango_layout_set_font_description(layout, font.get()); |
304 | 3513 | 3546 | ||
307 | 3514 | GdkScreen* gdkScreen = gdk_screen_get_default(); | 3547 | GdkScreen* gdk_screen = gdk_screen_get_default(); |
308 | 3515 | PangoContext* pCxt = pango_layout_get_context(layout); | 3548 | PangoContext* pango_ctx = pango_layout_get_context(layout); |
309 | 3516 | int dpi = style.GetTextDPI(); | 3549 | int dpi = style.GetTextDPI(); |
310 | 3517 | 3550 | ||
313 | 3518 | pango_cairo_context_set_font_options(pCxt, gdk_screen_get_font_options(gdkScreen)); | 3551 | pango_cairo_context_set_font_options(pango_ctx, gdk_screen_get_font_options(gdk_screen)); |
314 | 3519 | pango_cairo_context_set_resolution(pCxt, dpi / static_cast<float>(PANGO_SCALE)); | 3552 | pango_cairo_context_set_resolution(pango_ctx, dpi / static_cast<float>(PANGO_SCALE)); |
315 | 3520 | pango_layout_context_changed(layout); | 3553 | pango_layout_context_changed(layout); |
316 | 3521 | 3554 | ||
318 | 3522 | pango_layout_set_height(layout, maxHeight); | 3555 | std::string const& win_title = WindowManager::Default()->GetWindowName(window->id()); |
319 | 3556 | pango_layout_set_height(layout, height); | ||
320 | 3523 | pango_layout_set_width(layout, -1); //avoid wrap lines | 3557 | pango_layout_set_width(layout, -1); //avoid wrap lines |
321 | 3524 | pango_layout_set_auto_dir(layout, false); | 3558 | pango_layout_set_auto_dir(layout, false); |
325 | 3525 | pango_layout_set_text(layout, | 3559 | pango_layout_set_text(layout, win_title.c_str(), -1); |
323 | 3526 | WindowManager::Default()->GetWindowName(window->id()).c_str(), | ||
324 | 3527 | -1); | ||
326 | 3528 | 3560 | ||
327 | 3529 | /* update the size of the pango layout */ | 3561 | /* update the size of the pango layout */ |
328 | 3530 | pango_cairo_update_layout(context.cr_, layout); | 3562 | pango_cairo_update_layout(context.cr_, layout); |
335 | 3531 | cairo_set_operator(context.cr_, CAIRO_OPERATOR_OVER); | 3563 | |
336 | 3532 | cairo_set_source_rgba(context.cr_, | 3564 | GtkStyleContext* style_context = style.GetStyleContext(); |
337 | 3533 | 1.0, | 3565 | gtk_style_context_save(style_context); |
338 | 3534 | 1.0, | 3566 | |
339 | 3535 | 1.0, | 3567 | std::shared_ptr<GtkWidgetPath> widget_path(gtk_widget_path_new(), gtk_widget_path_free); |
340 | 3536 | 1.0); | 3568 | gtk_widget_path_append_type(widget_path.get(), GTK_TYPE_MENU_BAR); |
341 | 3569 | gtk_widget_path_append_type(widget_path.get(), GTK_TYPE_MENU_ITEM); | ||
342 | 3570 | gtk_widget_path_iter_set_name(widget_path.get(), -1 , "UnityPanelWidget"); | ||
343 | 3571 | |||
344 | 3572 | gtk_style_context_set_path(style_context, widget_path.get()); | ||
345 | 3573 | gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR); | ||
346 | 3574 | gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM); | ||
347 | 3537 | 3575 | ||
348 | 3538 | // alignment | 3576 | // alignment |
349 | 3539 | PangoRectangle lRect; | 3577 | PangoRectangle lRect; |
360 | 3540 | int textWidth, textHeight; | 3578 | pango_layout_get_extents(layout, nullptr, &lRect); |
361 | 3541 | 3579 | int text_width = lRect.width / PANGO_SCALE; | |
362 | 3542 | pango_layout_get_extents(layout, NULL, &lRect); | 3580 | int text_height = lRect.height / PANGO_SCALE; |
363 | 3543 | textWidth = lRect.width / PANGO_SCALE; | 3581 | y += (height - text_height) / 2.0f; |
364 | 3544 | textHeight = lRect.height / PANGO_SCALE; | 3582 | int text_space = width - x; |
365 | 3545 | 3583 | ||
366 | 3546 | y = ((maxHeight - textHeight) / 2.0) + y; | 3584 | if (text_width > text_space) |
357 | 3547 | cairo_translate(context.cr_, x, y); | ||
358 | 3548 | |||
359 | 3549 | if (textWidth > maxWidth) | ||
367 | 3550 | { | 3585 | { |
372 | 3551 | // apply a fade effect in the right corner | 3586 | // Cut the text with fade |
373 | 3552 | const int outPixels = textWidth - maxWidth; | 3587 | int out_pixels = text_width - text_space; |
374 | 3553 | const int fadingPixels = 35; | 3588 | const int fading_pixels = 35; |
375 | 3554 | const int fadingWidth = outPixels < fadingPixels ? outPixels : fadingPixels; | 3589 | int fading_width = (out_pixels < fading_pixels) ? out_pixels : fading_pixels; |
376 | 3555 | 3590 | ||
377 | 3556 | cairo_push_group(context.cr_); | 3591 | cairo_push_group(context.cr_); |
379 | 3557 | pango_cairo_show_layout(context.cr_, layout); | 3592 | gtk_render_layout(style_context, context.cr_, x, y, layout); |
380 | 3558 | cairo_pop_group_to_source(context.cr_); | 3593 | cairo_pop_group_to_source(context.cr_); |
381 | 3559 | 3594 | ||
384 | 3560 | std::shared_ptr<cairo_pattern_t> linpat(cairo_pattern_create_linear(maxWidth - fadingWidth, | 3595 | std::shared_ptr<cairo_pattern_t> linpat(cairo_pattern_create_linear(width - fading_width, y, width, y), |
383 | 3561 | y, maxWidth, y), | ||
385 | 3562 | cairo_pattern_destroy); | 3596 | cairo_pattern_destroy); |
386 | 3563 | cairo_pattern_add_color_stop_rgba(linpat.get(), 0, 0, 0, 0, 1); | 3597 | cairo_pattern_add_color_stop_rgba(linpat.get(), 0, 0, 0, 0, 1); |
387 | 3564 | cairo_pattern_add_color_stop_rgba(linpat.get(), 1, 0, 0, 0, 0); | 3598 | cairo_pattern_add_color_stop_rgba(linpat.get(), 1, 0, 0, 0, 0); |
388 | @@ -3566,61 +3600,55 @@ | |||
389 | 3566 | } | 3600 | } |
390 | 3567 | else | 3601 | else |
391 | 3568 | { | 3602 | { |
393 | 3569 | pango_cairo_show_layout(context.cr_, layout); | 3603 | gtk_render_layout(style_context, context.cr_, x, y, layout); |
394 | 3570 | } | 3604 | } |
395 | 3605 | |||
396 | 3606 | gtk_style_context_restore(style_context); | ||
397 | 3571 | } | 3607 | } |
398 | 3572 | 3608 | ||
405 | 3573 | void | 3609 | void UnityWindow::DrawWindowDecoration(GLWindowPaintAttrib const& attrib, |
406 | 3574 | UnityWindow::DrawWindowDecoration(GLWindowPaintAttrib const& attrib, | 3610 | GLMatrix const& transform, |
407 | 3575 | GLMatrix const& transform, | 3611 | unsigned int mask, |
408 | 3576 | unsigned int mask, | 3612 | bool highlighted, |
409 | 3577 | bool highlighted, | 3613 | int x, int y, unsigned width, unsigned height) |
404 | 3578 | int x, int y, unsigned width, unsigned height) | ||
410 | 3579 | { | 3614 | { |
411 | 3580 | // Paint a fake window decoration | 3615 | // Paint a fake window decoration |
412 | 3581 | CairoContext context(width, height); | 3616 | CairoContext context(width, height); |
413 | 3582 | 3617 | ||
414 | 3583 | cairo_save(context.cr_); | 3618 | cairo_save(context.cr_); |
415 | 3619 | |||
416 | 3620 | // Draw window decoration based on gtk style | ||
417 | 3584 | cairo_push_group(context.cr_); | 3621 | cairo_push_group(context.cr_); |
418 | 3622 | auto& style = panel::Style::Instance(); | ||
419 | 3623 | gtk_render_background(style.GetStyleContext(), context.cr_, 0, 0, width, height); | ||
420 | 3624 | gtk_render_frame(style.GetStyleContext(), context.cr_, 0, 0, width, height); | ||
421 | 3625 | cairo_pop_group_to_source(context.cr_); | ||
422 | 3585 | 3626 | ||
423 | 3586 | // Round window decoration top border | 3627 | // Round window decoration top border |
428 | 3587 | const double aspect = 1.0; | 3628 | const double aspect = ScaleWindow::get(window)->getCurrentPosition().scale; |
429 | 3588 | const double corner_radius = height / 10.0; | 3629 | const double radius = 8.0 * aspect; |
426 | 3589 | const double radius = corner_radius / aspect; | ||
427 | 3590 | const double degrees = M_PI / 180.0; | ||
430 | 3591 | 3630 | ||
431 | 3592 | cairo_new_sub_path(context.cr_); | 3631 | cairo_new_sub_path(context.cr_); |
435 | 3593 | 3632 | cairo_line_to(context.cr_, 0, height); | |
436 | 3594 | cairo_arc(context.cr_, radius, radius, radius, 180 * degrees, 270 * degrees); | 3633 | cairo_arc(context.cr_, radius, radius, radius, M_PI, -M_PI * 0.5f); |
437 | 3595 | cairo_arc(context.cr_, width - radius, radius, radius, -90 * degrees, 0 * degrees); | 3634 | cairo_line_to(context.cr_, width - radius, 0); |
438 | 3635 | cairo_arc(context.cr_, width - radius, radius, radius, M_PI * 0.5f, 0); | ||
439 | 3596 | cairo_line_to(context.cr_, width, height); | 3636 | cairo_line_to(context.cr_, width, height); |
440 | 3597 | cairo_line_to(context.cr_, 0, height); | ||
441 | 3598 | |||
442 | 3599 | cairo_close_path(context.cr_); | 3637 | cairo_close_path(context.cr_); |
453 | 3600 | cairo_clip(context.cr_); | 3638 | |
454 | 3601 | 3639 | cairo_fill(context.cr_); | |
455 | 3602 | // Draw window decoration based on gtk style | 3640 | |
446 | 3603 | auto& style = panel::Style::Instance(); | ||
447 | 3604 | gtk_render_background(style.GetStyleContext(), context.cr_, 0, 0, width, height); | ||
448 | 3605 | gtk_render_frame(style.GetStyleContext(), context.cr_, 0, 0, width, height); | ||
449 | 3606 | |||
450 | 3607 | cairo_pop_group_to_source(context.cr_); | ||
451 | 3608 | |||
452 | 3609 | cairo_paint_with_alpha(context.cr_, 1.0); | ||
456 | 3610 | cairo_restore(context.cr_); | 3641 | cairo_restore(context.cr_); |
457 | 3611 | 3642 | ||
458 | 3612 | if (highlighted) | 3643 | if (highlighted) |
459 | 3613 | { | 3644 | { |
460 | 3614 | // Draw windows title | 3645 | // Draw windows title |
461 | 3615 | const float xText = SCALE_ITEMS_PADDING * 2 + SCALE_CLOSE_ICON_SIZE; | 3646 | const float xText = SCALE_ITEMS_PADDING * 2 + SCALE_CLOSE_ICON_SIZE; |
463 | 3616 | RenderText(context, xText, 0.0, width - xText - SCALE_ITEMS_PADDING, height); | 3647 | RenderText(context, xText, 0.0, width - SCALE_ITEMS_PADDING, height); |
464 | 3617 | } | 3648 | } |
465 | 3618 | 3649 | ||
466 | 3619 | mask |= PAINT_WINDOW_BLEND_MASK; | 3650 | mask |= PAINT_WINDOW_BLEND_MASK; |
471 | 3620 | int maxWidth, maxHeight; | 3651 | DrawTexture(context.texture_, attrib, transform, mask, x, y); |
468 | 3621 | |||
469 | 3622 | for (GLTexture *icon : context.texture_) | ||
470 | 3623 | DrawTexture(icon, attrib, transform, mask, x, y, maxWidth , maxHeight); | ||
472 | 3624 | } | 3652 | } |
473 | 3625 | 3653 | ||
474 | 3626 | void UnityWindow::LoadCloseIcon(panel::WindowState state, GLTexture::List& texture) | 3654 | void UnityWindow::LoadCloseIcon(panel::WindowState state, GLTexture::List& texture) |
475 | @@ -3631,12 +3659,12 @@ | |||
476 | 3631 | auto& style = panel::Style::Instance(); | 3659 | auto& style = panel::Style::Instance(); |
477 | 3632 | auto const& files = style.GetWindowButtonFileNames(panel::WindowButtonType::CLOSE, state); | 3660 | auto const& files = style.GetWindowButtonFileNames(panel::WindowButtonType::CLOSE, state); |
478 | 3633 | 3661 | ||
480 | 3634 | CompString pName("unityshell"); | 3662 | CompString plugin("unityshell"); |
481 | 3635 | for (std::string const& file : files) | 3663 | for (std::string const& file : files) |
482 | 3636 | { | 3664 | { |
484 | 3637 | CompString fileName(file.c_str()); | 3665 | CompString file_name = file; |
485 | 3638 | CompSize size(SCALE_CLOSE_ICON_SIZE, SCALE_CLOSE_ICON_SIZE); | 3666 | CompSize size(SCALE_CLOSE_ICON_SIZE, SCALE_CLOSE_ICON_SIZE); |
487 | 3639 | texture = GLTexture::readImageToTexture(fileName, pName, size); | 3667 | texture = GLTexture::readImageToTexture(file_name, plugin, size); |
488 | 3640 | if (!texture.empty()) | 3668 | if (!texture.empty()) |
489 | 3641 | break; | 3669 | break; |
490 | 3642 | } | 3670 | } |
491 | @@ -3649,49 +3677,57 @@ | |||
492 | 3649 | else if (state == panel::WindowState::PRESSED) | 3677 | else if (state == panel::WindowState::PRESSED) |
493 | 3650 | suffix = "_pressed"; | 3678 | suffix = "_pressed"; |
494 | 3651 | 3679 | ||
496 | 3652 | CompString fileName((PKGDATADIR"/close_dash" + suffix + ".png").c_str()); | 3680 | CompString file_name(PKGDATADIR"/close_dash" + suffix + ".png"); |
497 | 3653 | CompSize size(SCALE_CLOSE_ICON_SIZE, SCALE_CLOSE_ICON_SIZE); | 3681 | CompSize size(SCALE_CLOSE_ICON_SIZE, SCALE_CLOSE_ICON_SIZE); |
499 | 3654 | texture = GLTexture::readImageToTexture(fileName, pName, size); | 3682 | texture = GLTexture::readImageToTexture(file_name, plugin, size); |
500 | 3655 | } | 3683 | } |
501 | 3656 | } | 3684 | } |
502 | 3657 | 3685 | ||
504 | 3658 | void UnityWindow::SetupScaleHeaderStyle() | 3686 | void UnityWindow::SetupSharedTextures() |
505 | 3659 | { | 3687 | { |
506 | 3660 | LoadCloseIcon(panel::WindowState::NORMAL, close_normal_tex_); | 3688 | LoadCloseIcon(panel::WindowState::NORMAL, close_normal_tex_); |
507 | 3661 | LoadCloseIcon(panel::WindowState::PRELIGHT, close_prelight_tex_); | 3689 | LoadCloseIcon(panel::WindowState::PRELIGHT, close_prelight_tex_); |
508 | 3662 | LoadCloseIcon(panel::WindowState::PRESSED, close_pressed_tex_); | 3690 | LoadCloseIcon(panel::WindowState::PRESSED, close_pressed_tex_); |
509 | 3663 | } | 3691 | } |
510 | 3664 | 3692 | ||
511 | 3693 | void UnityWindow::CleanupSharedTextures() | ||
512 | 3694 | { | ||
513 | 3695 | close_normal_tex_.clear(); | ||
514 | 3696 | close_prelight_tex_.clear(); | ||
515 | 3697 | close_pressed_tex_.clear(); | ||
516 | 3698 | } | ||
517 | 3699 | |||
518 | 3665 | void UnityWindow::scalePaintDecoration(GLWindowPaintAttrib const& attrib, | 3700 | void UnityWindow::scalePaintDecoration(GLWindowPaintAttrib const& attrib, |
519 | 3666 | GLMatrix const& transform, | 3701 | GLMatrix const& transform, |
520 | 3667 | CompRegion const& region, | 3702 | CompRegion const& region, |
521 | 3668 | unsigned int mask) | 3703 | unsigned int mask) |
522 | 3669 | { | 3704 | { |
523 | 3670 | ScaleWindow *scale_win = ScaleWindow::get(window); | 3705 | ScaleWindow *scale_win = ScaleWindow::get(window); |
524 | 3671 | if (!scale_win) | ||
525 | 3672 | return; | ||
526 | 3673 | |||
527 | 3674 | scale_win->scalePaintDecoration(attrib, transform, region, mask); | 3706 | scale_win->scalePaintDecoration(attrib, transform, region, mask); |
528 | 3675 | 3707 | ||
529 | 3676 | if (!scale_win->hasSlot()) // animation not finished | 3708 | if (!scale_win->hasSlot()) // animation not finished |
530 | 3677 | return; | 3709 | return; |
531 | 3678 | 3710 | ||
532 | 3679 | ScaleScreen* ss = ScaleScreen::get(screen); | 3711 | ScaleScreen* ss = ScaleScreen::get(screen); |
533 | 3712 | auto state = ss->getState(); | ||
534 | 3713 | |||
535 | 3714 | if (state != ScaleScreen::Wait && state != ScaleScreen::Out) | ||
536 | 3715 | return; | ||
537 | 3716 | |||
538 | 3717 | auto const& scaled_geo = GetScaledGeometry(); | ||
539 | 3718 | auto const& decoration_extents = window->border(); | ||
540 | 3719 | auto const& pos = scale_win->getCurrentPosition(); | ||
541 | 3720 | |||
542 | 3680 | const bool highlighted = (ss->getSelectedWindow() == window->id()); | 3721 | const bool highlighted = (ss->getSelectedWindow() == window->id()); |
557 | 3681 | 3722 | int width = scaled_geo.width; | |
558 | 3682 | ScalePosition const& pos = scale_win->getCurrentPosition(); | 3723 | int height = decoration_extents.top; |
559 | 3683 | auto const& border_rect = window->borderRect(); | 3724 | int x = scaled_geo.x; |
560 | 3684 | auto const& deco_ext = window->border(); | 3725 | int y = scaled_geo.y; |
561 | 3685 | 3726 | ||
562 | 3686 | const unsigned decoration_height = deco_ext.top; | 3727 | |
563 | 3687 | unsigned width = (border_rect.width() + deco_ext.left + deco_ext.right) * pos.scale; | 3728 | // If window is not highlighted, we draw the decoration at scaled size |
564 | 3688 | unsigned height = decoration_height * pos.scale; | 3729 | if (!highlighted) |
565 | 3689 | int x = pos.x() + border_rect.x(); | 3730 | height *= pos.scale; |
552 | 3690 | int y = pos.y() + border_rect.y() + decoration_height - height - 1; | ||
553 | 3691 | |||
554 | 3692 | // If window is highlighted, we draw the decoration at full size | ||
555 | 3693 | if (highlighted) | ||
556 | 3694 | height = decoration_height; | ||
566 | 3695 | 3731 | ||
567 | 3696 | DrawWindowDecoration(attrib, transform, mask, highlighted, x, y, width, height); | 3732 | DrawWindowDecoration(attrib, transform, mask, highlighted, x, y, width, height); |
568 | 3697 | 3733 | ||
569 | @@ -3699,30 +3735,25 @@ | |||
570 | 3699 | { | 3735 | { |
571 | 3700 | x += SCALE_ITEMS_PADDING; | 3736 | x += SCALE_ITEMS_PADDING; |
572 | 3701 | y += (height - SCALE_CLOSE_ICON_SIZE) / 2.0f; | 3737 | y += (height - SCALE_CLOSE_ICON_SIZE) / 2.0f; |
573 | 3702 | int max_height = 0; | ||
574 | 3703 | int max_width = 0; | ||
575 | 3704 | mask |= PAINT_WINDOW_BLEND_MASK; | 3738 | mask |= PAINT_WINDOW_BLEND_MASK; |
576 | 3705 | 3739 | ||
578 | 3706 | switch(close_icon_state_) | 3740 | switch (close_icon_state_) |
579 | 3707 | { | 3741 | { |
580 | 3708 | case panel::WindowState::NORMAL: | 3742 | case panel::WindowState::NORMAL: |
581 | 3709 | default: | 3743 | default: |
584 | 3710 | for (GLTexture *icon : close_normal_tex_) | 3744 | DrawTexture(close_normal_tex_, attrib, transform, mask, x, y); |
583 | 3711 | DrawTexture(icon, attrib, transform, mask, x, y, max_width , max_height); | ||
585 | 3712 | break; | 3745 | break; |
586 | 3713 | 3746 | ||
587 | 3714 | case panel::WindowState::PRELIGHT: | 3747 | case panel::WindowState::PRELIGHT: |
590 | 3715 | for (GLTexture *icon : close_prelight_tex_) | 3748 | DrawTexture(close_prelight_tex_, attrib, transform, mask, x, y); |
589 | 3716 | DrawTexture(icon, attrib, transform, mask, x, y, max_width , max_height); | ||
591 | 3717 | break; | 3749 | break; |
592 | 3718 | 3750 | ||
593 | 3719 | case panel::WindowState::PRESSED: | 3751 | case panel::WindowState::PRESSED: |
596 | 3720 | for (GLTexture *icon : close_pressed_tex_) | 3752 | DrawTexture(close_pressed_tex_, attrib, transform, mask, x, y); |
595 | 3721 | DrawTexture(icon, attrib, transform, mask, x, y, max_width , max_height); | ||
597 | 3722 | break; | 3753 | break; |
598 | 3723 | } | 3754 | } |
599 | 3724 | 3755 | ||
601 | 3725 | close_button_geo_.Set(x, y, max_height, max_width); | 3756 | close_button_geo_.Set(x, y, SCALE_CLOSE_ICON_SIZE, SCALE_CLOSE_ICON_SIZE); |
602 | 3726 | } | 3757 | } |
603 | 3727 | else if (!close_button_geo_.IsNull()) | 3758 | else if (!close_button_geo_.IsNull()) |
604 | 3728 | { | 3759 | { |
605 | @@ -3730,14 +3761,27 @@ | |||
606 | 3730 | } | 3761 | } |
607 | 3731 | } | 3762 | } |
608 | 3732 | 3763 | ||
609 | 3764 | nux::Geometry UnityWindow::GetScaledGeometry() | ||
610 | 3765 | { | ||
611 | 3766 | ScaleWindow *scale_win = ScaleWindow::get(window); | ||
612 | 3767 | |||
613 | 3768 | ScalePosition const& pos = scale_win->getCurrentPosition(); | ||
614 | 3769 | auto const& border_rect = window->borderRect(); | ||
615 | 3770 | auto const& deco_ext = window->border(); | ||
616 | 3771 | |||
617 | 3772 | const unsigned width = std::floor(border_rect.width() * pos.scale); | ||
618 | 3773 | const unsigned height = std::floor(border_rect.height() * pos.scale); | ||
619 | 3774 | const int x = pos.x() + window->x() - std::floor(deco_ext.left * pos.scale); | ||
620 | 3775 | const int y = pos.y() + window->y() - std::floor(deco_ext.top * pos.scale); | ||
621 | 3776 | |||
622 | 3777 | return nux::Geometry(x, y, width, height); | ||
623 | 3778 | } | ||
624 | 3779 | |||
625 | 3733 | void UnityWindow::OnInitiateSpreed() | 3780 | void UnityWindow::OnInitiateSpreed() |
626 | 3734 | { | 3781 | { |
627 | 3735 | auto const& windows = screen->windows(); | ||
628 | 3736 | if (std::find(windows.begin(), windows.end(), window) == windows.end()) | ||
629 | 3737 | return; | ||
630 | 3738 | |||
631 | 3739 | close_icon_state_ = panel::WindowState::NORMAL; | 3782 | close_icon_state_ = panel::WindowState::NORMAL; |
633 | 3740 | SetupScaleHeaderStyle(); | 3783 | middle_clicked_ = false; |
634 | 3784 | SetupSharedTextures(); | ||
635 | 3741 | 3785 | ||
636 | 3742 | WindowManager *wm = WindowManager::Default(); | 3786 | WindowManager *wm = WindowManager::Default(); |
637 | 3743 | Window xid = window->id(); | 3787 | Window xid = window->id(); |
638 | @@ -3748,10 +3792,6 @@ | |||
639 | 3748 | 3792 | ||
640 | 3749 | void UnityWindow::OnTerminateSpreed() | 3793 | void UnityWindow::OnTerminateSpreed() |
641 | 3750 | { | 3794 | { |
642 | 3751 | auto const& windows = screen->windows(); | ||
643 | 3752 | if (std::find(windows.begin(), windows.end(), window) == windows.end()) | ||
644 | 3753 | return; | ||
645 | 3754 | |||
646 | 3755 | WindowManager *wm = WindowManager::Default(); | 3795 | WindowManager *wm = WindowManager::Default(); |
647 | 3756 | Window xid = window->id(); | 3796 | Window xid = window->id(); |
648 | 3757 | 3797 | ||
649 | @@ -3813,6 +3853,33 @@ | |||
650 | 3813 | return true; | 3853 | return true; |
651 | 3814 | } | 3854 | } |
652 | 3815 | 3855 | ||
653 | 3856 | namespace debug | ||
654 | 3857 | { | ||
655 | 3858 | |||
656 | 3859 | ScreenIntrospection::ScreenIntrospection(CompScreen* screen) | ||
657 | 3860 | : screen_(screen) | ||
658 | 3861 | {} | ||
659 | 3862 | |||
660 | 3863 | std::string ScreenIntrospection::GetName() const | ||
661 | 3864 | { | ||
662 | 3865 | return "Screen"; | ||
663 | 3866 | } | ||
664 | 3867 | |||
665 | 3868 | void ScreenIntrospection::AddProperties(GVariantBuilder* builder) | ||
666 | 3869 | {} | ||
667 | 3870 | |||
668 | 3871 | Introspectable::IntrospectableList ScreenIntrospection::GetIntrospectableChildren() | ||
669 | 3872 | { | ||
670 | 3873 | IntrospectableList children; | ||
671 | 3874 | |||
672 | 3875 | for (auto const& win : screen_->windows()) | ||
673 | 3876 | children.push_back(UnityWindow::get(win)); | ||
674 | 3877 | |||
675 | 3878 | return children; | ||
676 | 3879 | } | ||
677 | 3880 | |||
678 | 3881 | } // debug namespace | ||
679 | 3882 | |||
680 | 3816 | namespace | 3883 | namespace |
681 | 3817 | { | 3884 | { |
682 | 3818 | 3885 | ||
683 | 3819 | 3886 | ||
684 | === modified file 'plugins/unityshell/src/unityshell.h' | |||
685 | --- plugins/unityshell/src/unityshell.h 2012-09-19 16:57:39 +0000 | |||
686 | +++ plugins/unityshell/src/unityshell.h 2012-09-24 19:39:25 +0000 | |||
687 | @@ -27,7 +27,6 @@ | |||
688 | 27 | #include <Nux/WindowThread.h> | 27 | #include <Nux/WindowThread.h> |
689 | 28 | #include <NuxCore/Property.h> | 28 | #include <NuxCore/Property.h> |
690 | 29 | #include <sigc++/sigc++.h> | 29 | #include <sigc++/sigc++.h> |
691 | 30 | #include <boost/shared_ptr.hpp> | ||
692 | 31 | 30 | ||
693 | 32 | #include <scale/scale.h> | 31 | #include <scale/scale.h> |
694 | 33 | #include <core/core.h> | 32 | #include <core/core.h> |
695 | @@ -50,6 +49,7 @@ | |||
696 | 50 | #include "PanelStyle.h" | 49 | #include "PanelStyle.h" |
697 | 51 | #include "UScreen.h" | 50 | #include "UScreen.h" |
698 | 52 | #include "DebugDBusInterface.h" | 51 | #include "DebugDBusInterface.h" |
699 | 52 | #include "ScreenIntrospection.h" | ||
700 | 53 | #include "SwitcherController.h" | 53 | #include "SwitcherController.h" |
701 | 54 | #include "UBusWrapper.h" | 54 | #include "UBusWrapper.h" |
702 | 55 | #include "UnityshellPrivate.h" | 55 | #include "UnityshellPrivate.h" |
703 | @@ -69,7 +69,7 @@ | |||
704 | 69 | 69 | ||
705 | 70 | /* base screen class */ | 70 | /* base screen class */ |
706 | 71 | class UnityScreen : | 71 | class UnityScreen : |
708 | 72 | public unity::debug::Introspectable, | 72 | public debug::Introspectable, |
709 | 73 | public sigc::trackable, | 73 | public sigc::trackable, |
710 | 74 | public ScreenInterface, | 74 | public ScreenInterface, |
711 | 75 | public CompositeScreenInterface, | 75 | public CompositeScreenInterface, |
712 | @@ -307,7 +307,7 @@ | |||
713 | 307 | 307 | ||
714 | 308 | nux::Property<nux::Geometry> primary_monitor_; | 308 | nux::Property<nux::Geometry> primary_monitor_; |
715 | 309 | 309 | ||
717 | 310 | BGHash* _bghash; | 310 | std::unique_ptr<BGHash> _bghash; |
718 | 311 | 311 | ||
719 | 312 | ::GLFramebufferObject *oldFbo; | 312 | ::GLFramebufferObject *oldFbo; |
720 | 313 | 313 | ||
721 | @@ -329,11 +329,13 @@ | |||
722 | 329 | nux::ObjectPtr<nux::IOpenGLBaseTexture> panel_texture_; | 329 | nux::ObjectPtr<nux::IOpenGLBaseTexture> panel_texture_; |
723 | 330 | 330 | ||
724 | 331 | bool scale_just_activated_; | 331 | bool scale_just_activated_; |
725 | 332 | WindowMinimizeSpeedController minimize_speed_controller_; | ||
726 | 333 | |||
727 | 334 | debug::ScreenIntrospection screen_introspection_; | ||
728 | 332 | 335 | ||
729 | 333 | UBusManager ubus_manager_; | 336 | UBusManager ubus_manager_; |
730 | 334 | glib::SourceManager sources_; | 337 | glib::SourceManager sources_; |
731 | 335 | 338 | ||
732 | 336 | WindowMinimizeSpeedController* minimize_speed_controller; | ||
733 | 337 | friend class UnityWindow; | 339 | friend class UnityWindow; |
734 | 338 | }; | 340 | }; |
735 | 339 | 341 | ||
736 | @@ -345,6 +347,7 @@ | |||
737 | 345 | public WrapableHandler<ScaleWindowInterface, 4>, | 347 | public WrapableHandler<ScaleWindowInterface, 4>, |
738 | 346 | public BaseSwitchWindow, | 348 | public BaseSwitchWindow, |
739 | 347 | public PluginClassHandler <UnityWindow, CompWindow>, | 349 | public PluginClassHandler <UnityWindow, CompWindow>, |
740 | 350 | public debug::Introspectable, | ||
741 | 348 | public sigc::trackable | 351 | public sigc::trackable |
742 | 349 | { | 352 | { |
743 | 350 | public: | 353 | public: |
744 | @@ -391,6 +394,7 @@ | |||
745 | 391 | 394 | ||
746 | 392 | bool place(CompPoint& pos); | 395 | bool place(CompPoint& pos); |
747 | 393 | CompPoint tryNotIntersectUI(CompPoint& pos); | 396 | CompPoint tryNotIntersectUI(CompPoint& pos); |
748 | 397 | nux::Geometry GetScaledGeometry(); | ||
749 | 394 | 398 | ||
750 | 395 | void paintThumbnail (nux::Geometry const& bounding, float alpha); | 399 | void paintThumbnail (nux::Geometry const& bounding, float alpha); |
751 | 396 | 400 | ||
752 | @@ -413,6 +417,10 @@ | |||
753 | 413 | const CompRegion &, | 417 | const CompRegion &, |
754 | 414 | unsigned int); | 418 | unsigned int); |
755 | 415 | 419 | ||
756 | 420 | protected: | ||
757 | 421 | std::string GetName() const; | ||
758 | 422 | void AddProperties(GVariantBuilder* builder); | ||
759 | 423 | |||
760 | 416 | private: | 424 | private: |
761 | 417 | struct CairoContext; | 425 | struct CairoContext; |
762 | 418 | 426 | ||
763 | @@ -449,23 +457,16 @@ | |||
764 | 449 | 457 | ||
765 | 450 | compiz::WindowInputRemoverLock::Ptr GetInputRemover (); | 458 | compiz::WindowInputRemoverLock::Ptr GetInputRemover (); |
766 | 451 | 459 | ||
771 | 452 | void DrawWindowDecoration(GLWindowPaintAttrib const& attrib, | 460 | void DrawWindowDecoration(GLWindowPaintAttrib const& attrib, GLMatrix const& transform, |
772 | 453 | GLMatrix const& transform, | 461 | unsigned int mask, bool highlighted, |
769 | 454 | unsigned int mask, | ||
770 | 455 | bool highlighted, | ||
773 | 456 | int x, int y, unsigned width, unsigned height); | 462 | int x, int y, unsigned width, unsigned height); |
783 | 457 | void DrawTexture(GLTexture *icon, | 463 | void DrawTexture(GLTexture::List const& textures, GLWindowPaintAttrib const& attrib, |
784 | 458 | const GLWindowPaintAttrib& attrib, | 464 | GLMatrix const& transform, unsigned int mask, int x, int y); |
785 | 459 | const GLMatrix& transform, | 465 | void RenderText(CairoContext const& context, int x, int y, int width, int height); |
777 | 460 | unsigned int mask, | ||
778 | 461 | float x, float y, | ||
779 | 462 | int &maxWidth, int &maxHeight); | ||
780 | 463 | void RenderText(CairoContext const& context, | ||
781 | 464 | float x, float y, | ||
782 | 465 | float maxWidth, float maxHeight); | ||
786 | 466 | 466 | ||
789 | 467 | void SetupScaleHeaderStyle(); | 467 | static void SetupSharedTextures(); |
790 | 468 | void LoadCloseIcon(panel::WindowState state, GLTexture::List& texture); | 468 | static void CleanupSharedTextures(); |
791 | 469 | static void LoadCloseIcon(panel::WindowState state, GLTexture::List& texture); | ||
792 | 469 | 470 | ||
793 | 470 | static GLTexture::List close_normal_tex_; | 471 | static GLTexture::List close_normal_tex_; |
794 | 471 | static GLTexture::List close_prelight_tex_; | 472 | static GLTexture::List close_prelight_tex_; |
795 | @@ -473,7 +474,10 @@ | |||
796 | 473 | compiz::WindowInputRemoverLock::Weak input_remover_; | 474 | compiz::WindowInputRemoverLock::Weak input_remover_; |
797 | 474 | panel::WindowState close_icon_state_; | 475 | panel::WindowState close_icon_state_; |
798 | 475 | nux::Geometry close_button_geo_; | 476 | nux::Geometry close_button_geo_; |
799 | 477 | bool middle_clicked_; | ||
800 | 476 | glib::Source::UniquePtr focus_desktop_timeout_; | 478 | glib::Source::UniquePtr focus_desktop_timeout_; |
801 | 479 | |||
802 | 480 | friend class UnityScreen; | ||
803 | 477 | }; | 481 | }; |
804 | 478 | 482 | ||
805 | 479 | 483 | ||
806 | 480 | 484 | ||
807 | === added file 'tests/autopilot/unity/emulators/screen.py' | |||
808 | --- tests/autopilot/unity/emulators/screen.py 1970-01-01 00:00:00 +0000 | |||
809 | +++ tests/autopilot/unity/emulators/screen.py 2012-09-24 19:39:25 +0000 | |||
810 | @@ -0,0 +1,42 @@ | |||
811 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | ||
812 | 2 | # Copyright 2012 Canonical | ||
813 | 3 | # Author: Marco Trevisan (Treviño) | ||
814 | 4 | # | ||
815 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
816 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
817 | 7 | # by the Free Software Foundation. | ||
818 | 8 | # | ||
819 | 9 | |||
820 | 10 | from __future__ import absolute_import | ||
821 | 11 | |||
822 | 12 | import logging | ||
823 | 13 | from unity.emulators import UnityIntrospectionObject | ||
824 | 14 | logger = logging.getLogger(__name__) | ||
825 | 15 | |||
826 | 16 | |||
827 | 17 | class Screen(UnityIntrospectionObject): | ||
828 | 18 | """The Screen class.""" | ||
829 | 19 | |||
830 | 20 | @property | ||
831 | 21 | def windows(self): | ||
832 | 22 | """Return the available windows, or None.""" | ||
833 | 23 | return self.get_children_by_type(Window) | ||
834 | 24 | |||
835 | 25 | @property | ||
836 | 26 | def scaled_windows(self): | ||
837 | 27 | """Return the available scaled windows, or None.""" | ||
838 | 28 | return self.get_children_by_type(Window, scaled=True) | ||
839 | 29 | |||
840 | 30 | |||
841 | 31 | class Window(UnityIntrospectionObject): | ||
842 | 32 | """An individual window.""" | ||
843 | 33 | |||
844 | 34 | @property | ||
845 | 35 | def geometry(self): | ||
846 | 36 | """Returns a tuple of (x,y,w,h) for the current window.""" | ||
847 | 37 | return (self.x, self.y, self.width, self.height) | ||
848 | 38 | |||
849 | 39 | @property | ||
850 | 40 | def scale_close_geometry(self): | ||
851 | 41 | """Returns a tuple of (x,y,w,h) for the scale close button.""" | ||
852 | 42 | return (self.scaled_close_x, self.scaled_close_y, self.scaled_close_width, self.scaled_close_height) | ||
853 | 0 | 43 | ||
854 | === modified file 'tests/autopilot/unity/tests/__init__.py' | |||
855 | --- tests/autopilot/unity/tests/__init__.py 2012-07-12 20:54:59 +0000 | |||
856 | +++ tests/autopilot/unity/tests/__init__.py 2012-09-24 19:39:25 +0000 | |||
857 | @@ -20,6 +20,7 @@ | |||
858 | 20 | from testtools.content import text_content | 20 | from testtools.content import text_content |
859 | 21 | from testtools.matchers import Equals | 21 | from testtools.matchers import Equals |
860 | 22 | 22 | ||
861 | 23 | from unity.emulators.screen import Screen | ||
862 | 23 | from unity.emulators.dash import Dash | 24 | from unity.emulators.dash import Dash |
863 | 24 | from unity.emulators.hud import Hud | 25 | from unity.emulators.hud import Hud |
864 | 25 | from unity.emulators.launcher import LauncherController | 26 | from unity.emulators.launcher import LauncherController |
865 | @@ -114,6 +115,12 @@ | |||
866 | 114 | return True | 115 | return True |
867 | 115 | 116 | ||
868 | 116 | @property | 117 | @property |
869 | 118 | def screen(self): | ||
870 | 119 | if not getattr(self, '__screen', None): | ||
871 | 120 | self.__screen = self._get_screen() | ||
872 | 121 | return self.__screen | ||
873 | 122 | |||
874 | 123 | @property | ||
875 | 117 | def dash(self): | 124 | def dash(self): |
876 | 118 | if not getattr(self, '__dash', None): | 125 | if not getattr(self, '__dash', None): |
877 | 119 | self.__dash = Dash() | 126 | self.__dash = Dash() |
878 | @@ -155,6 +162,11 @@ | |||
879 | 155 | self.__workspace = WorkspaceManager() | 162 | self.__workspace = WorkspaceManager() |
880 | 156 | return self.__workspace | 163 | return self.__workspace |
881 | 157 | 164 | ||
882 | 165 | def _get_screen(self): | ||
883 | 166 | screens = Screen.get_all_instances() | ||
884 | 167 | self.assertThat(len(screens), Equals(1)) | ||
885 | 168 | return screens[0] | ||
886 | 169 | |||
887 | 158 | def _get_launcher_controller(self): | 170 | def _get_launcher_controller(self): |
888 | 159 | controllers = LauncherController.get_all_instances() | 171 | controllers = LauncherController.get_all_instances() |
889 | 160 | self.assertThat(len(controllers), Equals(1)) | 172 | self.assertThat(len(controllers), Equals(1)) |
890 | 161 | 173 | ||
891 | === added file 'tests/autopilot/unity/tests/test_spread.py' | |||
892 | --- tests/autopilot/unity/tests/test_spread.py 1970-01-01 00:00:00 +0000 | |||
893 | +++ tests/autopilot/unity/tests/test_spread.py 2012-09-24 19:39:25 +0000 | |||
894 | @@ -0,0 +1,124 @@ | |||
895 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | ||
896 | 2 | # Copyright 2012 Canonical | ||
897 | 3 | # Author: Marco Trevisan (Treviño) | ||
898 | 4 | # | ||
899 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
900 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
901 | 7 | # by the Free Software Foundation. | ||
902 | 8 | |||
903 | 9 | from __future__ import absolute_import | ||
904 | 10 | |||
905 | 11 | from autopilot.matchers import Eventually | ||
906 | 12 | import logging | ||
907 | 13 | from time import sleep | ||
908 | 14 | from testtools.matchers import Equals, NotEquals | ||
909 | 15 | |||
910 | 16 | from unity.tests import UnityTestCase | ||
911 | 17 | from unity.emulators.screen import Screen | ||
912 | 18 | |||
913 | 19 | |||
914 | 20 | class SpreadTests(UnityTestCase): | ||
915 | 21 | """Spread tests""" | ||
916 | 22 | |||
917 | 23 | def start_test_application_windows(self, app_name, num_windows=2): | ||
918 | 24 | """Start a given number of windows of the requested application""" | ||
919 | 25 | self.close_all_app(app_name) | ||
920 | 26 | windows = [] | ||
921 | 27 | |||
922 | 28 | for i in range(num_windows): | ||
923 | 29 | win = self.start_app_window(app_name) | ||
924 | 30 | if len(windows): | ||
925 | 31 | self.assertThat(win.application, Equals(windows[-1].application)) | ||
926 | 32 | |||
927 | 33 | windows.append(win) | ||
928 | 34 | |||
929 | 35 | self.assertThat(len(windows), Equals(num_windows)) | ||
930 | 36 | |||
931 | 37 | return windows | ||
932 | 38 | |||
933 | 39 | def initiate_spread_for_screen(self): | ||
934 | 40 | """Initiate the Spread for all windows""" | ||
935 | 41 | self.addCleanup(self.keybinding, "spread/cancel") | ||
936 | 42 | self.keybinding("spread/start") | ||
937 | 43 | sleep(1) | ||
938 | 44 | self.assertThat(self.window_manager.scale_active, Eventually(Equals(True))) | ||
939 | 45 | |||
940 | 46 | |||
941 | 47 | def initiate_spread_for_application(self, desktop_id): | ||
942 | 48 | """Initiate the Spread for windows of the given app""" | ||
943 | 49 | icon = self.launcher.model.get_icon(desktop_id=desktop_id) | ||
944 | 50 | self.assertThat(lambda: icon, Eventually(NotEquals(None))) | ||
945 | 51 | launcher = self.launcher.get_launcher_for_monitor(self.screen_geo.get_primary_monitor()) | ||
946 | 52 | |||
947 | 53 | self.addCleanup(self.keybinding, "spread/cancel") | ||
948 | 54 | launcher.click_launcher_icon(icon) | ||
949 | 55 | self.assertThat(self.window_manager.scale_active_for_group, Eventually(Equals(True))) | ||
950 | 56 | |||
951 | 57 | def assertWindowIsNotScaled(self, xid): | ||
952 | 58 | """Assert that a window is not scaled""" | ||
953 | 59 | refresh_fn = lambda: xid in [w.xid for w in self.screen.scaled_windows] | ||
954 | 60 | self.assertThat(refresh_fn, Eventually(Equals(False))) | ||
955 | 61 | |||
956 | 62 | def assertWindowIsClosed(self, xid): | ||
957 | 63 | """Assert that a window is not in the list of the open windows""" | ||
958 | 64 | refresh_fn = lambda: xid in [w.x_id for w in self.bamf.get_open_windows()] | ||
959 | 65 | self.assertThat(refresh_fn, Eventually(Equals(False))) | ||
960 | 66 | |||
961 | 67 | |||
962 | 68 | def test_scale_application_windows(self): | ||
963 | 69 | """Test if all the windows of an application are scaled when application spread is initiated""" | ||
964 | 70 | [win1, win2] = self.start_test_application_windows("Calculator") | ||
965 | 71 | self.initiate_spread_for_application(win1.application.desktop_file) | ||
966 | 72 | |||
967 | 73 | self.assertThat(lambda: len(self.screen.scaled_windows), Eventually(Equals(2))) | ||
968 | 74 | self.assertThat(lambda: (win1.x_id and win2.x_id) in [w.xid for w in self.screen.scaled_windows], | ||
969 | 75 | Eventually(Equals(True))) | ||
970 | 76 | |||
971 | 77 | def test_scaled_window_is_focused_on_click(self): | ||
972 | 78 | """Test that a window is focused when clicked in spread""" | ||
973 | 79 | windows = self.start_test_application_windows("Calculator", 3) | ||
974 | 80 | self.initiate_spread_for_application(windows[0].application.desktop_file) | ||
975 | 81 | |||
976 | 82 | not_focused = [w for w in windows if not w.is_focused][0] | ||
977 | 83 | |||
978 | 84 | target_xid = not_focused.x_id | ||
979 | 85 | [target_win] = [w for w in self.screen.scaled_windows if w.xid == target_xid] | ||
980 | 86 | |||
981 | 87 | (x, y, w, h) = target_win.geometry | ||
982 | 88 | self.mouse.move(x + w / 2, y + h / 2) | ||
983 | 89 | sleep(.5) | ||
984 | 90 | self.mouse.click() | ||
985 | 91 | |||
986 | 92 | self.assertThat(lambda: not_focused.is_focused, Eventually(Equals(True))) | ||
987 | 93 | |||
988 | 94 | def test_scaled_window_closes_on_middle_click(self): | ||
989 | 95 | """Test that a window is closed when middle-clicked in spread""" | ||
990 | 96 | win = self.start_test_application_windows("Calculator", 2)[0] | ||
991 | 97 | self.initiate_spread_for_application(win.application.desktop_file) | ||
992 | 98 | |||
993 | 99 | target_xid = win.x_id | ||
994 | 100 | [target_win] = [w for w in self.screen.scaled_windows if w.xid == target_xid] | ||
995 | 101 | |||
996 | 102 | (x, y, w, h) = target_win.geometry | ||
997 | 103 | self.mouse.move(x + w / 2, y + h / 2) | ||
998 | 104 | sleep(.5) | ||
999 | 105 | self.mouse.click(button=2) | ||
1000 | 106 | |||
1001 | 107 | self.assertWindowIsNotScaled(target_xid) | ||
1002 | 108 | self.assertWindowIsClosed(target_xid) | ||
1003 | 109 | |||
1004 | 110 | def test_scaled_window_closes_on_close_button_click(self): | ||
1005 | 111 | """Test that a window is closed when its close button is clicked in spread""" | ||
1006 | 112 | win = self.start_test_application_windows("Calculator", 1)[0] | ||
1007 | 113 | self.initiate_spread_for_screen() | ||
1008 | 114 | |||
1009 | 115 | target_xid = win.x_id | ||
1010 | 116 | [target_win] = [w for w in self.screen.scaled_windows if w.xid == target_xid] | ||
1011 | 117 | |||
1012 | 118 | (x, y, w, h) = target_win.scale_close_geometry | ||
1013 | 119 | self.mouse.move(x + w / 2, y + h / 2) | ||
1014 | 120 | sleep(.5) | ||
1015 | 121 | self.mouse.click() | ||
1016 | 122 | |||
1017 | 123 | self.assertWindowIsNotScaled(target_xid) | ||
1018 | 124 | self.assertWindowIsClosed(target_xid) |
Confirmed still working :)