Merge lp:~3v1n0/unity/super-arrows-shortcuts into lp:unity
- super-arrows-shortcuts
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Christopher Townsend |
Approved revision: | no longer in the source branch. |
Merged at revision: | 3509 |
Proposed branch: | lp:~3v1n0/unity/super-arrows-shortcuts |
Merge into: | lp:unity |
Diff against target: |
595 lines (+318/-20) 10 files modified
plugins/unityshell/src/unityshell.cpp (+23/-0) plugins/unityshell/src/unityshell.h (+2/-0) plugins/unityshell/unityshell.xml.in (+12/-0) shortcuts/CompizShortcutModeller.cpp (+11/-11) tests/autopilot/unity/tests/test_wm_keybindings.py (+110/-0) unity-shared/PluginAdapter.cpp (+69/-0) unity-shared/PluginAdapter.h (+8/-0) unity-shared/StandaloneWindowManager.cpp (+71/-7) unity-shared/StandaloneWindowManager.h (+7/-1) unity-shared/WindowManager.h (+5/-1) |
To merge this branch: | bzr merge lp:~3v1n0/unity/super-arrows-shortcuts |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Christopher Townsend | Approve | ||
Alex Launi | Pending | ||
Review via email: mp+185850@code.launchpad.net |
This proposal supersedes a proposal from 2012-01-28.
Commit message
UnityScreen: add support for Super+Arrows shortcuts to manage the focused window
Super+Arrows shortcut allows to move and maximize / restore / minimize
the focused window on the screen.
Description of the change
Added the Super+Left/Right arrows shortcuts support to manage the focused window, as defined on bug #751050
This branch requires lp:~3v1n0/autopilot/window-left+right-maximize-keys in order to make the tests pass.
The fixes is also complete when lp:~3v1n0/compiz/unity-wm-shortcuts-0.9.11 merges
Alex Launi (alexlauni) wrote : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1886
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Christopher Townsend (townsend) wrote : | # |
Works great!
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'plugins/unityshell/src/unityshell.cpp' | |||
2 | --- plugins/unityshell/src/unityshell.cpp 2013-09-12 03:12:04 +0000 | |||
3 | +++ plugins/unityshell/src/unityshell.cpp 2013-09-16 16:11:09 +0000 | |||
4 | @@ -349,6 +349,9 @@ | |||
5 | 349 | optionSetLauncherSwitcherPrevInitiate(boost::bind(&UnityScreen::launcherSwitcherPrevInitiate, this, _1, _2, _3)); | 349 | optionSetLauncherSwitcherPrevInitiate(boost::bind(&UnityScreen::launcherSwitcherPrevInitiate, this, _1, _2, _3)); |
6 | 350 | optionSetLauncherSwitcherForwardTerminate(boost::bind(&UnityScreen::launcherSwitcherTerminate, this, _1, _2, _3)); | 350 | optionSetLauncherSwitcherForwardTerminate(boost::bind(&UnityScreen::launcherSwitcherTerminate, this, _1, _2, _3)); |
7 | 351 | 351 | ||
8 | 352 | optionSetWindowRightMaximizeInitiate(boost::bind(&UnityScreen::rightMaximizeKeyInitiate, this, _1, _2, _3)); | ||
9 | 353 | optionSetWindowLeftMaximizeInitiate(boost::bind(&UnityScreen::leftMaximizeKeyInitiate, this, _1, _2, _3)); | ||
10 | 354 | |||
11 | 352 | optionSetStopVelocityNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); | 355 | optionSetStopVelocityNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
12 | 353 | optionSetRevealPressureNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); | 356 | optionSetRevealPressureNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
13 | 354 | optionSetEdgeResponsivenessNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); | 357 | optionSetEdgeResponsivenessNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
14 | @@ -2136,12 +2139,14 @@ | |||
15 | 2136 | action->setState(action->state() | CompAction::StateTermKey); | 2139 | action->setState(action->state() | CompAction::StateTermKey); |
16 | 2137 | return true; | 2140 | return true; |
17 | 2138 | } | 2141 | } |
18 | 2142 | |||
19 | 2139 | bool UnityScreen::launcherSwitcherPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) | 2143 | bool UnityScreen::launcherSwitcherPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) |
20 | 2140 | { | 2144 | { |
21 | 2141 | launcher_controller_->KeyNavPrevious(); | 2145 | launcher_controller_->KeyNavPrevious(); |
22 | 2142 | 2146 | ||
23 | 2143 | return true; | 2147 | return true; |
24 | 2144 | } | 2148 | } |
25 | 2149 | |||
26 | 2145 | bool UnityScreen::launcherSwitcherTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options) | 2150 | bool UnityScreen::launcherSwitcherTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options) |
27 | 2146 | { | 2151 | { |
28 | 2147 | bool accept_state = (state & CompAction::StateCancel) == 0; | 2152 | bool accept_state = (state & CompAction::StateCancel) == 0; |
29 | @@ -2164,6 +2169,20 @@ | |||
30 | 2164 | return true; | 2169 | return true; |
31 | 2165 | } | 2170 | } |
32 | 2166 | 2171 | ||
33 | 2172 | bool UnityScreen::rightMaximizeKeyInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) | ||
34 | 2173 | { | ||
35 | 2174 | auto& WM = WindowManager::Default(); | ||
36 | 2175 | WM.RightMaximize(WM.GetActiveWindow()); | ||
37 | 2176 | return true; | ||
38 | 2177 | } | ||
39 | 2178 | |||
40 | 2179 | bool UnityScreen::leftMaximizeKeyInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) | ||
41 | 2180 | { | ||
42 | 2181 | auto& WM = WindowManager::Default(); | ||
43 | 2182 | WM.LeftMaximize(WM.GetActiveWindow()); | ||
44 | 2183 | return true; | ||
45 | 2184 | } | ||
46 | 2185 | |||
47 | 2167 | void UnityScreen::OnLauncherStartKeyNav(GVariant* data) | 2186 | void UnityScreen::OnLauncherStartKeyNav(GVariant* data) |
48 | 2168 | { | 2187 | { |
49 | 2169 | // Put the launcher BaseWindow at the top of the BaseWindow stack. The | 2188 | // Put the launcher BaseWindow at the top of the BaseWindow stack. The |
50 | @@ -3554,6 +3573,10 @@ | |||
51 | 3554 | .add("xid", (uint64_t)xid) | 3573 | .add("xid", (uint64_t)xid) |
52 | 3555 | .add("title", wm.GetWindowName(xid)) | 3574 | .add("title", wm.GetWindowName(xid)) |
53 | 3556 | .add("fake_decorated", uScreen->fake_decorated_windows_.find(this) != uScreen->fake_decorated_windows_.end()) | 3575 | .add("fake_decorated", uScreen->fake_decorated_windows_.find(this) != uScreen->fake_decorated_windows_.end()) |
54 | 3576 | .add("maximized", wm.IsWindowVerticallyMaximized(xid)) | ||
55 | 3577 | .add("horizontally_maximized", wm.IsWindowHorizontallyMaximized(xid)) | ||
56 | 3578 | .add("vertically_maximized", wm.IsWindowVerticallyMaximized(xid)) | ||
57 | 3579 | .add("minimized", wm.IsWindowMinimized(xid)) | ||
58 | 3557 | .add("scaled", scaled) | 3580 | .add("scaled", scaled) |
59 | 3558 | .add("scaled_close_x", close_button_geo_.x) | 3581 | .add("scaled_close_x", close_button_geo_.x) |
60 | 3559 | .add("scaled_close_y", close_button_geo_.y) | 3582 | .add("scaled_close_y", close_button_geo_.y) |
61 | 3560 | 3583 | ||
62 | === modified file 'plugins/unityshell/src/unityshell.h' | |||
63 | --- plugins/unityshell/src/unityshell.h 2013-08-08 23:04:44 +0000 | |||
64 | +++ plugins/unityshell/src/unityshell.h 2013-09-16 16:11:09 +0000 | |||
65 | @@ -165,6 +165,8 @@ | |||
66 | 165 | bool launcherSwitcherForwardInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); | 165 | bool launcherSwitcherForwardInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); |
67 | 166 | bool launcherSwitcherPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); | 166 | bool launcherSwitcherPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); |
68 | 167 | bool launcherSwitcherTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options); | 167 | bool launcherSwitcherTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options); |
69 | 168 | bool rightMaximizeKeyInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); | ||
70 | 169 | bool leftMaximizeKeyInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); | ||
71 | 168 | 170 | ||
72 | 169 | /* handle option changes and change settings inside of the | 171 | /* handle option changes and change settings inside of the |
73 | 170 | * panel and dock views */ | 172 | * panel and dock views */ |
74 | 171 | 173 | ||
75 | === modified file 'plugins/unityshell/unityshell.xml.in' | |||
76 | --- plugins/unityshell/unityshell.xml.in 2013-09-11 19:32:34 +0000 | |||
77 | +++ plugins/unityshell/unityshell.xml.in 2013-09-16 16:11:09 +0000 | |||
78 | @@ -68,6 +68,18 @@ | |||
79 | 68 | <default><Alt>F10</default> | 68 | <default><Alt>F10</default> |
80 | 69 | </option> | 69 | </option> |
81 | 70 | 70 | ||
82 | 71 | <option name="window_right_maximize" type="key"> | ||
83 | 72 | <_short>Key to vertically maximize the focused window to the right</_short> | ||
84 | 73 | <_long>Semi-maximize vertically the focused window on the half right width of the screen</_long> | ||
85 | 74 | <default><Control><Super>Right</default> | ||
86 | 75 | </option> | ||
87 | 76 | |||
88 | 77 | <option name="window_left_maximize" type="key"> | ||
89 | 78 | <_short>Key to vertically maximize the focused window to the left</_short> | ||
90 | 79 | <_long>Semi-maximize vertically the focused window to the half left width of the screen</_long> | ||
91 | 80 | <default><Control><Super>Left</default> | ||
92 | 81 | </option> | ||
93 | 82 | |||
94 | 71 | <option name="panel_opacity" type="float"> | 83 | <option name="panel_opacity" type="float"> |
95 | 72 | <_short>Panel Opacity</_short> | 84 | <_short>Panel Opacity</_short> |
96 | 73 | <_long>The opacity of the Panel background.</_long> | 85 | <_long>The opacity of the Panel background.</_long> |
97 | 74 | 86 | ||
98 | === modified file 'shortcuts/CompizShortcutModeller.cpp' | |||
99 | --- shortcuts/CompizShortcutModeller.cpp 2013-07-07 02:46:28 +0000 | |||
100 | +++ shortcuts/CompizShortcutModeller.cpp 2013-09-16 16:11:09 +0000 | |||
101 | @@ -32,7 +32,6 @@ | |||
102 | 32 | // Compiz' plug-in names | 32 | // Compiz' plug-in names |
103 | 33 | const std::string CORE_PLUGIN_NAME = "core"; | 33 | const std::string CORE_PLUGIN_NAME = "core"; |
104 | 34 | const std::string EXPO_PLUGIN_NAME = "expo"; | 34 | const std::string EXPO_PLUGIN_NAME = "expo"; |
105 | 35 | const std::string GRID_PLUGIN_NAME = "grid"; | ||
106 | 36 | const std::string MOVE_PLUGIN_NAME = "move"; | 35 | const std::string MOVE_PLUGIN_NAME = "move"; |
107 | 37 | const std::string RESIZE_PLUGIN_NAME = "resize"; | 36 | const std::string RESIZE_PLUGIN_NAME = "resize"; |
108 | 38 | const std::string SCALE_PLUGIN_NAME = "scale"; | 37 | const std::string SCALE_PLUGIN_NAME = "scale"; |
109 | @@ -41,17 +40,14 @@ | |||
110 | 41 | 40 | ||
111 | 42 | // Compiz Core Options | 41 | // Compiz Core Options |
112 | 43 | const std::string CORE_OPTION_SHOW_DESKTOP_KEY = "show_desktop_key"; | 42 | const std::string CORE_OPTION_SHOW_DESKTOP_KEY = "show_desktop_key"; |
115 | 44 | const std::string CORE_OPTION_MAXIMIZE_WINDOW_KEY = "maximize_window_key"; | 43 | const std::string CORE_OPTION_MAXIMIZE_KEY = "maximize_window_key"; |
116 | 45 | const std::string CORE_OPTION_UNMAXIMIZE_OR_MINIMIZE_WINDOW_KEY = "unmaximize_or_minimize_window_key"; | 44 | const std::string CORE_OPTION_RESTORE_MINIMIZE_KEY = "unmaximize_or_minimize_window_key"; |
117 | 46 | const std::string CORE_OPTION_CLOSE_WINDOW_KEY = "close_window_key"; | 45 | const std::string CORE_OPTION_CLOSE_WINDOW_KEY = "close_window_key"; |
118 | 47 | const std::string CORE_OPTION_WINDOW_MENU_KEY = "window_menu_key"; | 46 | const std::string CORE_OPTION_WINDOW_MENU_KEY = "window_menu_key"; |
119 | 48 | 47 | ||
120 | 49 | // Compiz Expo Options | 48 | // Compiz Expo Options |
121 | 50 | const std::string EXPO_OPTION_EXPO_KEY = "expo_key"; | 49 | const std::string EXPO_OPTION_EXPO_KEY = "expo_key"; |
122 | 51 | 50 | ||
123 | 52 | // Compiz Grid Options | ||
124 | 53 | const std::string GRID_OPTION_PUT_LEFT_KEY = "put_left_key"; | ||
125 | 54 | |||
126 | 55 | // Compiz Move Options | 51 | // Compiz Move Options |
127 | 56 | const std::string MOVE_OPTION_INITIATE_BUTTON = "initiate_button"; | 52 | const std::string MOVE_OPTION_INITIATE_BUTTON = "initiate_button"; |
128 | 57 | 53 | ||
129 | @@ -69,6 +65,10 @@ | |||
130 | 69 | const std::string UNITYSHELL_OPTION_PANEL_FIRST_MENU = "panel_first_menu"; | 65 | const std::string UNITYSHELL_OPTION_PANEL_FIRST_MENU = "panel_first_menu"; |
131 | 70 | const std::string UNITYSHELL_OPTION_ALT_TAB_FORWARD = "alt_tab_forward"; | 66 | const std::string UNITYSHELL_OPTION_ALT_TAB_FORWARD = "alt_tab_forward"; |
132 | 71 | const std::string UNITYSHELL_OPTION_ALT_TAB_NEXT_WINDOW = "alt_tab_next_window"; | 67 | const std::string UNITYSHELL_OPTION_ALT_TAB_NEXT_WINDOW = "alt_tab_next_window"; |
133 | 68 | const std::string UNITYSHELL_OPTION_MAXIMIZE = "window_maximize"; | ||
134 | 69 | const std::string UNITYSHELL_OPTION_LEFT_MAXIMIZE = "window_left_maximize"; | ||
135 | 70 | const std::string UNITYSHELL_OPTION_RIGHT_MAXIMIZE = "window_right_maximize"; | ||
136 | 71 | const std::string UNITYSHELL_OPTION_RESTORE_MINIMIZE = "window_restore_minimize"; | ||
137 | 72 | 72 | ||
138 | 73 | // Compiz Wall Options | 73 | // Compiz Wall Options |
139 | 74 | const std::string WALL_OPTION_LEFT_KEY = "left_key"; | 74 | const std::string WALL_OPTION_LEFT_KEY = "left_key"; |
140 | @@ -304,19 +304,19 @@ | |||
141 | 304 | _("Maximises the current window."), | 304 | _("Maximises the current window."), |
142 | 305 | shortcut::OptionType::COMPIZ_KEY, | 305 | shortcut::OptionType::COMPIZ_KEY, |
143 | 306 | CORE_PLUGIN_NAME, | 306 | CORE_PLUGIN_NAME, |
145 | 307 | CORE_OPTION_MAXIMIZE_WINDOW_KEY)); | 307 | CORE_OPTION_MAXIMIZE_KEY)); |
146 | 308 | 308 | ||
147 | 309 | hints.push_back(std::make_shared<shortcut::Hint>(windows, "", "", | 309 | hints.push_back(std::make_shared<shortcut::Hint>(windows, "", "", |
148 | 310 | _("Restores or minimises the current window."), | 310 | _("Restores or minimises the current window."), |
149 | 311 | shortcut::OptionType::COMPIZ_KEY, | 311 | shortcut::OptionType::COMPIZ_KEY, |
150 | 312 | CORE_PLUGIN_NAME, | 312 | CORE_PLUGIN_NAME, |
152 | 313 | CORE_OPTION_UNMAXIMIZE_OR_MINIMIZE_WINDOW_KEY)); | 313 | CORE_OPTION_RESTORE_MINIMIZE_KEY)); |
153 | 314 | 314 | ||
154 | 315 | hints.push_back(std::make_shared<shortcut::Hint>(windows, "", _(" or Right"), | 315 | hints.push_back(std::make_shared<shortcut::Hint>(windows, "", _(" or Right"), |
155 | 316 | _("Semi-maximise the current window."), | 316 | _("Semi-maximise the current window."), |
156 | 317 | shortcut::OptionType::COMPIZ_KEY, | 317 | shortcut::OptionType::COMPIZ_KEY, |
159 | 318 | GRID_PLUGIN_NAME, | 318 | UNITYSHELL_PLUGIN_NAME, |
160 | 319 | GRID_OPTION_PUT_LEFT_KEY)); | 319 | UNITYSHELL_OPTION_LEFT_MAXIMIZE)); |
161 | 320 | 320 | ||
162 | 321 | hints.push_back(std::make_shared<shortcut::Hint>(windows, "", "", | 321 | hints.push_back(std::make_shared<shortcut::Hint>(windows, "", "", |
163 | 322 | _("Closes the current window."), | 322 | _("Closes the current window."), |
164 | @@ -333,7 +333,7 @@ | |||
165 | 333 | hints.push_back(std::make_shared<shortcut::Hint>(windows, "", "", | 333 | hints.push_back(std::make_shared<shortcut::Hint>(windows, "", "", |
166 | 334 | _("Places the window in corresponding position."), | 334 | _("Places the window in corresponding position."), |
167 | 335 | shortcut::OptionType::HARDCODED, | 335 | shortcut::OptionType::HARDCODED, |
169 | 336 | _("Ctrl + Alt + Num"))); | 336 | _("Ctrl + Alt + Num (keypad)"))); |
170 | 337 | 337 | ||
171 | 338 | hints.push_back(std::make_shared<shortcut::Hint>(windows, "", _(" Drag"), | 338 | hints.push_back(std::make_shared<shortcut::Hint>(windows, "", _(" Drag"), |
172 | 339 | _("Moves the window."), | 339 | _("Moves the window."), |
173 | 340 | 340 | ||
174 | === added file 'tests/autopilot/unity/tests/test_wm_keybindings.py' | |||
175 | --- tests/autopilot/unity/tests/test_wm_keybindings.py 1970-01-01 00:00:00 +0000 | |||
176 | +++ tests/autopilot/unity/tests/test_wm_keybindings.py 2013-09-16 16:11:09 +0000 | |||
177 | @@ -0,0 +1,110 @@ | |||
178 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | ||
179 | 2 | # Copyright 2013 Canonical | ||
180 | 3 | # Author: Marco Trevisan (Treviño) | ||
181 | 4 | # | ||
182 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
183 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
184 | 7 | # by the Free Software Foundation. | ||
185 | 8 | |||
186 | 9 | from __future__ import absolute_import | ||
187 | 10 | |||
188 | 11 | from autopilot.matchers import Eventually | ||
189 | 12 | from testtools.matchers import Equals, NotEquals | ||
190 | 13 | from unity.tests import UnityTestCase | ||
191 | 14 | |||
192 | 15 | class WindowManagerKeybindings(UnityTestCase): | ||
193 | 16 | """Window Manager keybindings tests""" | ||
194 | 17 | |||
195 | 18 | scenarios = [('Restored Window', {'start_restored': True}), | ||
196 | 19 | ('Maximized Window', {'start_restored': False})] | ||
197 | 20 | |||
198 | 21 | def setUp(self): | ||
199 | 22 | super(WindowManagerKeybindings, self).setUp() | ||
200 | 23 | self.start_test_window() | ||
201 | 24 | |||
202 | 25 | def keybinding_if_not_minimized(self, keybinding): | ||
203 | 26 | if not self.screen_win.minimized: | ||
204 | 27 | self.keybinding(keybinding) | ||
205 | 28 | |||
206 | 29 | def keybinding_if_not_restored(self, keybinding): | ||
207 | 30 | if self.screen_win.vertically_maximized or self.screen_win.horizontally_maximized: | ||
208 | 31 | self.keybinding(keybinding) | ||
209 | 32 | |||
210 | 33 | def start_test_window(self, app_name="Character Map"): | ||
211 | 34 | """Start a restored/maximized window of the requested application""" | ||
212 | 35 | self.process_manager.close_all_app(app_name) | ||
213 | 36 | self.bamf_win = self.process_manager.start_app_window(app_name) | ||
214 | 37 | win_fn = lambda: self.unity.screen.window(self.bamf_win.x_id) | ||
215 | 38 | self.assertThat(win_fn, Eventually(NotEquals(None))) | ||
216 | 39 | self.screen_win = win_fn() | ||
217 | 40 | |||
218 | 41 | if self.start_restored: | ||
219 | 42 | if self.screen_win.vertically_maximized or self.screen_win.horizontally_maximized: | ||
220 | 43 | self.addCleanup(self.keybinding_if_not_minimized, "window/maximize") | ||
221 | 44 | self.keybinding("window/restore") | ||
222 | 45 | else: | ||
223 | 46 | if not self.screen_win.vertically_maximized and not self.screen_win.horizontally_maximized: | ||
224 | 47 | self.addCleanup(self.keybinding_if_not_restored, "window/restore") | ||
225 | 48 | self.keybinding("window/maximize") | ||
226 | 49 | |||
227 | 50 | def get_window_workarea(self): | ||
228 | 51 | monitor = self.bamf_win.monitor | ||
229 | 52 | monitor_geo = self.display.get_screen_geometry(monitor) | ||
230 | 53 | launcher = self.unity.launcher.get_launcher_for_monitor(monitor) | ||
231 | 54 | launcher_w = 0 if launcher.hidemode else launcher.geometry[2] | ||
232 | 55 | panel_h = self.unity.panels.get_panel_for_monitor(monitor).geometry[3] | ||
233 | 56 | return (monitor_geo[0] + launcher_w, monitor_geo[1] + panel_h, | ||
234 | 57 | monitor_geo[2] - launcher_w, monitor_geo[3] - panel_h) | ||
235 | 58 | |||
236 | 59 | def test_maximize_window(self): | ||
237 | 60 | if self.start_restored: | ||
238 | 61 | self.addCleanup(self.keybinding, "window/restore") | ||
239 | 62 | self.keybinding("window/maximize") | ||
240 | 63 | self.assertThat(self.screen_win.maximized, Eventually(Equals(True))) | ||
241 | 64 | |||
242 | 65 | def test_restore_maximized_window(self): | ||
243 | 66 | if self.start_restored: | ||
244 | 67 | self.keybinding("window/maximize") | ||
245 | 68 | self.keybinding("window/restore") | ||
246 | 69 | self.assertThat(self.screen_win.maximized, Eventually(Equals(False))) | ||
247 | 70 | self.assertThat(self.screen_win.minimized, Eventually(Equals(False))) | ||
248 | 71 | |||
249 | 72 | def test_restore_vertically_maximized_window(self): | ||
250 | 73 | if not self.start_restored: | ||
251 | 74 | self.addCleanup(self.keybinding, "window/maximize") | ||
252 | 75 | self.keybinding("window/restore") | ||
253 | 76 | self.keyboard.press_and_release("Ctrl+Super+Right") | ||
254 | 77 | self.keybinding("window/restore") | ||
255 | 78 | self.assertThat(self.screen_win.vertically_maximized, Eventually(Equals(False))) | ||
256 | 79 | self.assertThat(self.screen_win.minimized, Eventually(Equals(False))) | ||
257 | 80 | |||
258 | 81 | def test_minimize_restored_window(self): | ||
259 | 82 | if not self.start_restored: | ||
260 | 83 | self.addCleanup(self.keybinding_if_not_minimized, "window/maximize") | ||
261 | 84 | self.keybinding("window/restore") | ||
262 | 85 | self.keybinding("window/restore") | ||
263 | 86 | self.assertThat(self.screen_win.minimized, Eventually(Equals(True))) | ||
264 | 87 | |||
265 | 88 | def test_left_maximize(self): | ||
266 | 89 | self.addCleanup(self.keybinding, "window/restore" if self.start_restored else "window/maximize") | ||
267 | 90 | self.keyboard.press_and_release("Ctrl+Super+Left") | ||
268 | 91 | self.assertThat(self.screen_win.vertically_maximized, Eventually(Equals(True))) | ||
269 | 92 | self.assertThat(self.screen_win.horizontally_maximized, Eventually(Equals(False))) | ||
270 | 93 | |||
271 | 94 | workarea_geo = self.get_window_workarea() | ||
272 | 95 | self.assertThat(self.screen_win.x, Eventually(Equals(workarea_geo[0]))) | ||
273 | 96 | self.assertThat(self.screen_win.y, Eventually(Equals(workarea_geo[1]))) | ||
274 | 97 | self.assertThat(self.screen_win.width, Eventually(Equals(workarea_geo[2]/2))) | ||
275 | 98 | self.assertThat(self.screen_win.height, Eventually(Equals(workarea_geo[3]))) | ||
276 | 99 | |||
277 | 100 | def test_right_maximize(self): | ||
278 | 101 | self.addCleanup(self.keybinding, "window/restore" if self.start_restored else "window/maximize") | ||
279 | 102 | self.keyboard.press_and_release("Ctrl+Super+Right") | ||
280 | 103 | self.assertThat(self.screen_win.vertically_maximized, Eventually(Equals(True))) | ||
281 | 104 | self.assertThat(self.screen_win.horizontally_maximized, Eventually(Equals(False))) | ||
282 | 105 | |||
283 | 106 | workarea_geo = self.get_window_workarea() | ||
284 | 107 | self.assertThat(self.screen_win.x, Eventually(Equals(workarea_geo[0]+workarea_geo[2]/2))) | ||
285 | 108 | self.assertThat(self.screen_win.y, Eventually(Equals(workarea_geo[1]))) | ||
286 | 109 | self.assertThat(self.screen_win.width, Eventually(Equals(workarea_geo[2]/2))) | ||
287 | 110 | self.assertThat(self.screen_win.height, Eventually(Equals(workarea_geo[3]))) | ||
288 | 0 | 111 | ||
289 | === modified file 'unity-shared/PluginAdapter.cpp' | |||
290 | --- unity-shared/PluginAdapter.cpp 2013-08-08 14:43:50 +0000 | |||
291 | +++ unity-shared/PluginAdapter.cpp 2013-09-16 16:11:09 +0000 | |||
292 | @@ -461,6 +461,22 @@ | |||
293 | 461 | return false; | 461 | return false; |
294 | 462 | } | 462 | } |
295 | 463 | 463 | ||
296 | 464 | bool PluginAdapter::IsWindowVerticallyMaximized(Window window_id) const | ||
297 | 465 | { | ||
298 | 466 | if (CompWindow* window = m_Screen->findWindow(window_id)) | ||
299 | 467 | return (window->state() & CompWindowStateMaximizedVertMask); | ||
300 | 468 | |||
301 | 469 | return false; | ||
302 | 470 | } | ||
303 | 471 | |||
304 | 472 | bool PluginAdapter::IsWindowHorizontallyMaximized(Window window_id) const | ||
305 | 473 | { | ||
306 | 474 | if (CompWindow* window = m_Screen->findWindow(window_id)) | ||
307 | 475 | return (window->state() & CompWindowStateMaximizedHorzMask); | ||
308 | 476 | |||
309 | 477 | return false; | ||
310 | 478 | } | ||
311 | 479 | |||
312 | 464 | unsigned long PluginAdapter::GetMwnDecorations(Window window_id) const | 480 | unsigned long PluginAdapter::GetMwnDecorations(Window window_id) const |
313 | 465 | { | 481 | { |
314 | 466 | Display* display = m_Screen->dpy(); | 482 | Display* display = m_Screen->dpy(); |
315 | @@ -697,6 +713,59 @@ | |||
316 | 697 | window->maximize(MAXIMIZE_STATE); | 713 | window->maximize(MAXIMIZE_STATE); |
317 | 698 | } | 714 | } |
318 | 699 | 715 | ||
319 | 716 | void PluginAdapter::VerticallyMaximizeWindowAt(CompWindow* window, nux::Geometry const& geo) | ||
320 | 717 | { | ||
321 | 718 | if (window && ((window->type() & CompWindowTypeNormalMask) || | ||
322 | 719 | ((window->actions() & CompWindowActionMaximizeVertMask) && | ||
323 | 720 | window->actions() & CompWindowActionResizeMask))) | ||
324 | 721 | { | ||
325 | 722 | /* First we unmaximize the Window */ | ||
326 | 723 | if (window->state() & MAXIMIZE_STATE) | ||
327 | 724 | window->maximize(0); | ||
328 | 725 | |||
329 | 726 | /* Then we vertically maximize the it so it can be unminimized correctly */ | ||
330 | 727 | if (!(window->state() & CompWindowStateMaximizedVertMask)) | ||
331 | 728 | window->maximize(CompWindowStateMaximizedVertMask); | ||
332 | 729 | |||
333 | 730 | /* Then we resize and move it on the requested place */ | ||
334 | 731 | MoveResizeWindow(window->id(), geo); | ||
335 | 732 | } | ||
336 | 733 | } | ||
337 | 734 | |||
338 | 735 | void PluginAdapter::LeftMaximize(Window window_id) | ||
339 | 736 | { | ||
340 | 737 | CompWindow* window = m_Screen->findWindow(window_id); | ||
341 | 738 | |||
342 | 739 | if (!window) | ||
343 | 740 | return; | ||
344 | 741 | |||
345 | 742 | /* Let's compute the area where the window should stay */ | ||
346 | 743 | CompRect workarea = m_Screen->getWorkareaForOutput(window->outputDevice()); | ||
347 | 744 | nux::Geometry win_geo(workarea.x() + window->border().left, | ||
348 | 745 | workarea.y() + window->border().top, | ||
349 | 746 | workarea.width() / 2 - (window->border().left + window->border().right), | ||
350 | 747 | workarea.height() - (window->border().top + window->border().bottom)); | ||
351 | 748 | |||
352 | 749 | VerticallyMaximizeWindowAt(window, win_geo); | ||
353 | 750 | } | ||
354 | 751 | |||
355 | 752 | void PluginAdapter::RightMaximize(Window window_id) | ||
356 | 753 | { | ||
357 | 754 | CompWindow* window = m_Screen->findWindow(window_id); | ||
358 | 755 | |||
359 | 756 | if (!window) | ||
360 | 757 | return; | ||
361 | 758 | |||
362 | 759 | /* Let's compute the area where the window should stay */ | ||
363 | 760 | CompRect workarea = m_Screen->getWorkareaForOutput(window->outputDevice()); | ||
364 | 761 | nux::Geometry win_geo(workarea.x() + workarea.width() / 2 + window->border().left, | ||
365 | 762 | workarea.y() + window->border().top, | ||
366 | 763 | workarea.width() / 2 - (window->border().left + window->border().right), | ||
367 | 764 | workarea.height() - (window->border().top + window->border().bottom)); | ||
368 | 765 | |||
369 | 766 | VerticallyMaximizeWindowAt(window, win_geo); | ||
370 | 767 | } | ||
371 | 768 | |||
372 | 700 | void PluginAdapter::Restore(Window window_id) | 769 | void PluginAdapter::Restore(Window window_id) |
373 | 701 | { | 770 | { |
374 | 702 | CompWindow* window = m_Screen->findWindow(window_id); | 771 | CompWindow* window = m_Screen->findWindow(window_id); |
375 | 703 | 772 | ||
376 | === modified file 'unity-shared/PluginAdapter.h' | |||
377 | --- unity-shared/PluginAdapter.h 2013-08-08 14:43:50 +0000 | |||
378 | +++ unity-shared/PluginAdapter.h 2013-09-16 16:11:09 +0000 | |||
379 | @@ -130,6 +130,8 @@ | |||
380 | 130 | 130 | ||
381 | 131 | // WindowManager implementation | 131 | // WindowManager implementation |
382 | 132 | bool IsWindowMaximized(Window window_id) const; | 132 | bool IsWindowMaximized(Window window_id) const; |
383 | 133 | bool IsWindowVerticallyMaximized(Window window_id) const; | ||
384 | 134 | bool IsWindowHorizontallyMaximized(Window window_id) const; | ||
385 | 133 | bool IsWindowDecorated(Window window_id) const; | 135 | bool IsWindowDecorated(Window window_id) const; |
386 | 134 | bool IsWindowOnCurrentDesktop(Window window_id) const; | 136 | bool IsWindowOnCurrentDesktop(Window window_id) const; |
387 | 135 | bool IsWindowObscured(Window window_id) const; | 137 | bool IsWindowObscured(Window window_id) const; |
388 | @@ -143,6 +145,8 @@ | |||
389 | 143 | bool HasWindowDecorations(Window window_id) const; | 145 | bool HasWindowDecorations(Window window_id) const; |
390 | 144 | 146 | ||
391 | 145 | void Maximize(Window window_id); | 147 | void Maximize(Window window_id); |
392 | 148 | void LeftMaximize(Window window_id); | ||
393 | 149 | void RightMaximize(Window window_id); | ||
394 | 146 | void Restore(Window window_id); | 150 | void Restore(Window window_id); |
395 | 147 | void RestoreAt(Window window_id, int x, int y); | 151 | void RestoreAt(Window window_id, int x, int y); |
396 | 148 | void Minimize(Window window_id); | 152 | void Minimize(Window window_id); |
397 | @@ -196,6 +200,8 @@ | |||
398 | 196 | 200 | ||
399 | 197 | Window GetTopWindowAbove(Window xid) const; | 201 | Window GetTopWindowAbove(Window xid) const; |
400 | 198 | 202 | ||
401 | 203 | void MoveResizeWindow(guint32 xid, nux::Geometry geometry); | ||
402 | 204 | |||
403 | 199 | protected: | 205 | protected: |
404 | 200 | PluginAdapter(CompScreen* screen); | 206 | PluginAdapter(CompScreen* screen); |
405 | 201 | void AddProperties(GVariantBuilder* builder); | 207 | void AddProperties(GVariantBuilder* builder); |
406 | @@ -215,6 +221,8 @@ | |||
407 | 215 | std::string GetUtf8Property(Window xid, Atom atom) const; | 221 | std::string GetUtf8Property(Window xid, Atom atom) const; |
408 | 216 | std::vector<long> GetCardinalProperty(Window xid, Atom atom) const; | 222 | std::vector<long> GetCardinalProperty(Window xid, Atom atom) const; |
409 | 217 | 223 | ||
410 | 224 | void VerticallyMaximizeWindowAt(CompWindow* window, nux::Geometry const& geo); | ||
411 | 225 | |||
412 | 218 | CompScreen* m_Screen; | 226 | CompScreen* m_Screen; |
413 | 219 | MultiActionList m_ExpoActionList; | 227 | MultiActionList m_ExpoActionList; |
414 | 220 | MultiActionList m_ScaleActionList; | 228 | MultiActionList m_ScaleActionList; |
415 | 221 | 229 | ||
416 | === modified file 'unity-shared/StandaloneWindowManager.cpp' | |||
417 | --- unity-shared/StandaloneWindowManager.cpp 2013-08-08 14:43:50 +0000 | |||
418 | +++ unity-shared/StandaloneWindowManager.cpp 2013-09-16 16:11:09 +0000 | |||
419 | @@ -43,7 +43,8 @@ | |||
420 | 43 | , active(false) | 43 | , active(false) |
421 | 44 | , mapped(true) | 44 | , mapped(true) |
422 | 45 | , visible(true) | 45 | , visible(true) |
424 | 46 | , maximized(false) | 46 | , v_maximized(false) |
425 | 47 | , h_maximized(false) | ||
426 | 47 | , minimized(false) | 48 | , minimized(false) |
427 | 48 | , decorated(true) | 49 | , decorated(true) |
428 | 49 | , has_decorations(true) | 50 | , has_decorations(true) |
429 | @@ -67,6 +68,20 @@ | |||
430 | 67 | 68 | ||
431 | 68 | return false; | 69 | return false; |
432 | 69 | }); | 70 | }); |
433 | 71 | |||
434 | 72 | maximized.SetGetterFunction([this] { return v_maximized && h_maximized; }); | ||
435 | 73 | maximized.SetSetterFunction([this] (bool value) { | ||
436 | 74 | if (maximized() == value) | ||
437 | 75 | return false; | ||
438 | 76 | |||
439 | 77 | v_maximized = value; | ||
440 | 78 | h_maximized = value; | ||
441 | 79 | decorated = !value; | ||
442 | 80 | return true; | ||
443 | 81 | }); | ||
444 | 82 | |||
445 | 83 | v_maximized.changed.connect([this] (bool value) { maximized.changed.emit(maximized()); }); | ||
446 | 84 | h_maximized.changed.connect([this] (bool value) { maximized.changed.emit(maximized()); }); | ||
447 | 70 | } | 85 | } |
448 | 71 | 86 | ||
449 | 72 | WindowManagerPtr create_window_manager() | 87 | WindowManagerPtr create_window_manager() |
450 | @@ -125,6 +140,24 @@ | |||
451 | 125 | return false; | 140 | return false; |
452 | 126 | } | 141 | } |
453 | 127 | 142 | ||
454 | 143 | bool StandaloneWindowManager::IsWindowVerticallyMaximized(Window window_id) const | ||
455 | 144 | { | ||
456 | 145 | auto window = GetWindowByXid(window_id); | ||
457 | 146 | if (window) | ||
458 | 147 | return window->v_maximized; | ||
459 | 148 | |||
460 | 149 | return false; | ||
461 | 150 | } | ||
462 | 151 | |||
463 | 152 | bool StandaloneWindowManager::IsWindowHorizontallyMaximized(Window window_id) const | ||
464 | 153 | { | ||
465 | 154 | auto window = GetWindowByXid(window_id); | ||
466 | 155 | if (window) | ||
467 | 156 | return window->h_maximized; | ||
468 | 157 | |||
469 | 158 | return false; | ||
470 | 159 | } | ||
471 | 160 | |||
472 | 128 | bool StandaloneWindowManager::IsWindowDecorated(Window window_id) const | 161 | bool StandaloneWindowManager::IsWindowDecorated(Window window_id) const |
473 | 129 | { | 162 | { |
474 | 130 | auto window = GetWindowByXid(window_id); | 163 | auto window = GetWindowByXid(window_id); |
475 | @@ -249,20 +282,51 @@ | |||
476 | 249 | { | 282 | { |
477 | 250 | auto window = GetWindowByXid(window_id); | 283 | auto window = GetWindowByXid(window_id); |
478 | 251 | if (window) | 284 | if (window) |
479 | 252 | { | ||
480 | 253 | window->maximized = true; | 285 | window->maximized = true; |
483 | 254 | Undecorate(window_id); | 286 | } |
484 | 255 | } | 287 | |
485 | 288 | void StandaloneWindowManager::LeftMaximize(Window window_id) | ||
486 | 289 | { | ||
487 | 290 | auto window = GetWindowByXid(window_id); | ||
488 | 291 | |||
489 | 292 | if (!window) | ||
490 | 293 | return; | ||
491 | 294 | |||
492 | 295 | /* Let's compute the area where the window should be put */ | ||
493 | 296 | auto workarea = GetWorkAreaGeometry(window_id); | ||
494 | 297 | workarea.width /= 2; | ||
495 | 298 | |||
496 | 299 | if (window->maximized) | ||
497 | 300 | window->maximized = false; | ||
498 | 301 | |||
499 | 302 | window->v_maximized = true; | ||
500 | 303 | MoveResizeWindow(window_id, workarea); | ||
501 | 304 | } | ||
502 | 305 | |||
503 | 306 | void StandaloneWindowManager::RightMaximize(Window window_id) | ||
504 | 307 | { | ||
505 | 308 | auto window = GetWindowByXid(window_id); | ||
506 | 309 | |||
507 | 310 | if (!window) | ||
508 | 311 | return; | ||
509 | 312 | |||
510 | 313 | /* Let's compute the area where the window should be put */ | ||
511 | 314 | auto workarea = GetWorkAreaGeometry(window_id); | ||
512 | 315 | workarea.width /= 2; | ||
513 | 316 | workarea.x += workarea.width; | ||
514 | 317 | |||
515 | 318 | if (window->maximized) | ||
516 | 319 | window->maximized = false; | ||
517 | 320 | |||
518 | 321 | window->v_maximized = true; | ||
519 | 322 | MoveResizeWindow(window_id, workarea); | ||
520 | 256 | } | 323 | } |
521 | 257 | 324 | ||
522 | 258 | void StandaloneWindowManager::Restore(Window window_id) | 325 | void StandaloneWindowManager::Restore(Window window_id) |
523 | 259 | { | 326 | { |
524 | 260 | auto window = GetWindowByXid(window_id); | 327 | auto window = GetWindowByXid(window_id); |
525 | 261 | if (window) | 328 | if (window) |
526 | 262 | { | ||
527 | 263 | window->maximized = false; | 329 | window->maximized = false; |
528 | 264 | Decorate(window_id); | ||
529 | 265 | } | ||
530 | 266 | } | 330 | } |
531 | 267 | 331 | ||
532 | 268 | void StandaloneWindowManager::RestoreAt(Window window_id, int x, int y) | 332 | void StandaloneWindowManager::RestoreAt(Window window_id, int x, int y) |
533 | 269 | 333 | ||
534 | === modified file 'unity-shared/StandaloneWindowManager.h' | |||
535 | --- unity-shared/StandaloneWindowManager.h 2013-08-08 14:43:50 +0000 | |||
536 | +++ unity-shared/StandaloneWindowManager.h 2013-09-16 16:11:09 +0000 | |||
537 | @@ -48,7 +48,9 @@ | |||
538 | 48 | nux::Property<bool> active; | 48 | nux::Property<bool> active; |
539 | 49 | nux::Property<bool> mapped; | 49 | nux::Property<bool> mapped; |
540 | 50 | nux::Property<bool> visible; | 50 | nux::Property<bool> visible; |
542 | 51 | nux::Property<bool> maximized; | 51 | nux::RWProperty<bool> maximized; |
543 | 52 | nux::Property<bool> v_maximized; | ||
544 | 53 | nux::Property<bool> h_maximized; | ||
545 | 52 | nux::Property<bool> minimized; | 54 | nux::Property<bool> minimized; |
546 | 53 | nux::Property<bool> decorated; | 55 | nux::Property<bool> decorated; |
547 | 54 | nux::Property<bool> has_decorations; | 56 | nux::Property<bool> has_decorations; |
548 | @@ -70,6 +72,8 @@ | |||
549 | 70 | std::vector<Window> GetWindowsInStackingOrder() const override; | 72 | std::vector<Window> GetWindowsInStackingOrder() const override; |
550 | 71 | 73 | ||
551 | 72 | virtual bool IsWindowMaximized(Window window_id) const; | 74 | virtual bool IsWindowMaximized(Window window_id) const; |
552 | 75 | virtual bool IsWindowVerticallyMaximized(Window window_id) const; | ||
553 | 76 | virtual bool IsWindowHorizontallyMaximized(Window window_id) const; | ||
554 | 73 | virtual bool IsWindowDecorated(Window window_id) const; | 77 | virtual bool IsWindowDecorated(Window window_id) const; |
555 | 74 | virtual bool IsWindowOnCurrentDesktop(Window window_id) const; | 78 | virtual bool IsWindowOnCurrentDesktop(Window window_id) const; |
556 | 75 | virtual bool IsWindowObscured(Window window_id) const; | 79 | virtual bool IsWindowObscured(Window window_id) const; |
557 | @@ -86,6 +90,8 @@ | |||
558 | 86 | virtual bool InShowDesktop() const; | 90 | virtual bool InShowDesktop() const; |
559 | 87 | 91 | ||
560 | 88 | virtual void Maximize(Window window_id); | 92 | virtual void Maximize(Window window_id); |
561 | 93 | virtual void LeftMaximize(Window window_id); | ||
562 | 94 | virtual void RightMaximize(Window window_id); | ||
563 | 89 | virtual void Restore(Window window_id); | 95 | virtual void Restore(Window window_id); |
564 | 90 | virtual void RestoreAt(Window window_id, int x, int y); | 96 | virtual void RestoreAt(Window window_id, int x, int y); |
565 | 91 | virtual void Minimize(Window window_id); | 97 | virtual void Minimize(Window window_id); |
566 | 92 | 98 | ||
567 | === modified file 'unity-shared/WindowManager.h' | |||
568 | --- unity-shared/WindowManager.h 2013-08-08 14:43:50 +0000 | |||
569 | +++ unity-shared/WindowManager.h 2013-09-16 16:11:09 +0000 | |||
570 | @@ -77,6 +77,9 @@ | |||
571 | 77 | virtual std::vector<Window> GetWindowsInStackingOrder() const = 0; | 77 | virtual std::vector<Window> GetWindowsInStackingOrder() const = 0; |
572 | 78 | 78 | ||
573 | 79 | virtual bool IsWindowMaximized(Window window_id) const = 0; | 79 | virtual bool IsWindowMaximized(Window window_id) const = 0; |
574 | 80 | virtual bool IsWindowVerticallyMaximized(Window window_id) const = 0; | ||
575 | 81 | virtual bool IsWindowHorizontallyMaximized(Window window_id) const = 0; | ||
576 | 82 | virtual bool IsWindowMaximizable(Window window_id) const = 0; | ||
577 | 80 | virtual bool IsWindowDecorated(Window window_id) const = 0; | 83 | virtual bool IsWindowDecorated(Window window_id) const = 0; |
578 | 81 | virtual bool IsWindowOnCurrentDesktop(Window window_id) const = 0; | 84 | virtual bool IsWindowOnCurrentDesktop(Window window_id) const = 0; |
579 | 82 | virtual bool IsWindowObscured(Window window_id) const = 0; | 85 | virtual bool IsWindowObscured(Window window_id) const = 0; |
580 | @@ -86,13 +89,14 @@ | |||
581 | 86 | virtual bool IsWindowClosable(Window window_id) const = 0; | 89 | virtual bool IsWindowClosable(Window window_id) const = 0; |
582 | 87 | virtual bool IsWindowMinimized(Window window_id) const = 0; | 90 | virtual bool IsWindowMinimized(Window window_id) const = 0; |
583 | 88 | virtual bool IsWindowMinimizable(Window window_id) const = 0; | 91 | virtual bool IsWindowMinimizable(Window window_id) const = 0; |
584 | 89 | virtual bool IsWindowMaximizable(Window window_id) const = 0; | ||
585 | 90 | virtual bool HasWindowDecorations(Window window_id) const = 0; | 92 | virtual bool HasWindowDecorations(Window window_id) const = 0; |
586 | 91 | 93 | ||
587 | 92 | virtual void ShowDesktop() = 0; | 94 | virtual void ShowDesktop() = 0; |
588 | 93 | virtual bool InShowDesktop() const = 0; | 95 | virtual bool InShowDesktop() const = 0; |
589 | 94 | 96 | ||
590 | 95 | virtual void Maximize(Window window_id) = 0; | 97 | virtual void Maximize(Window window_id) = 0; |
591 | 98 | virtual void LeftMaximize(Window window_id) = 0; | ||
592 | 99 | virtual void RightMaximize(Window window_id) = 0; | ||
593 | 96 | virtual void Restore(Window window_id) = 0; | 100 | virtual void Restore(Window window_id) = 0; |
594 | 97 | virtual void RestoreAt(Window window_id, int x, int y) = 0; | 101 | virtual void RestoreAt(Window window_id, int x, int y) = 0; |
595 | 98 | virtual void Minimize(Window window_id) = 0; | 102 | virtual void Minimize(Window window_id) = 0; |
These tests could be written with autopilot. Please make the necessary adjustments to automate these tests.