Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(403)

Side by Side Diff: ash/wm/workspace/workspace_cycler.cc

Issue 11417150: Implement workspace scrubbing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/wm/workspace/workspace_cycler.h"
6
7 #include "ash/shell.h"
8 #include "ash/wm/workspace/workspace_manager.h"
9 #include "ui/aura/window.h"
10 #include "ui/base/events/event.h"
11
12 namespace ash {
13 namespace internal {
14
15 namespace {
16
17 // The required vertical distance to scrub to the next workspace.
18 const int kWorkspaceStepSize = 50;
19
20 // The maximum horizontal movement in between switching between two workspaces
21 // before the workspace scrubbing session is cancelled.
22 const int kMaxHorizontalMovementPerWorkspaceStep = 50;
23
24 // Returns true is scrubbing is enabled.
25 bool IsScrubbingEnabled() {
26 // Scrubbing is disabled if the screen is locked or a modal dialog is open.
27 return !Shell::GetInstance()->IsScreenLocked() &&
28 !Shell::GetInstance()->IsSystemModalWindowOpen();
29 }
30
31 } // namespace
32
33 WorkspaceCycler::WorkspaceCycler(WorkspaceManager* workspace_manager)
34 : workspace_manager_(workspace_manager),
35 scrub_state_(NOT_SCRUBBING),
36 initial_workspace_window_(NULL) {
37 ash::Shell::GetInstance()->AddPreTargetHandler(this);
38 }
39
40 WorkspaceCycler::~WorkspaceCycler() {
41 }
42
43 void WorkspaceCycler::StartScrubbing() {
44 scrub_state_ = SCRUBBING;
45 initial_workspace_window_ = workspace_manager_->GetActiveWorkspaceWindow();
46 DCHECK(initial_workspace_window_->IsVisible());
47 initial_workspace_window_->AddObserver(this);
48 }
49
50 void WorkspaceCycler::StopScrubbing() {
51 if (initial_workspace_window_)
52 initial_workspace_window_->RemoveObserver(this);
53 initial_workspace_window_ = NULL;
54
55 scrub_state_ = NOT_SCRUBBING;
56 }
57
58 void WorkspaceCycler::OnWindowDestroyed(aura::Window* window) {
59 DCHECK_EQ(window, initial_workspace_window_);
60 window->RemoveObserver(this);
61
62 // |initial_workspace_window_| may be destroyed while scrubbing is active
63 // if the user closes or unmaximizes windows via the keyboard in the
64 // workspace corresponding to |initial_workspace_window_|.
65 initial_workspace_window_ = NULL;
66 scrub_state_ = CANCELLED_SCRUBBING;
67 }
68
69 ui::EventResult WorkspaceCycler::OnKeyEvent(ui::KeyEvent* event) {
70 return ui::ER_UNHANDLED;
71 }
72
73 ui::EventResult WorkspaceCycler::OnMouseEvent(ui::MouseEvent* event) {
74 if (!IsScrubbingEnabled())
75 return ui::ER_UNHANDLED;
76
77 if (!(event->type() == ui::ET_MOUSE_PRESSED ||
78 event->type() == ui::ET_MOUSE_DRAGGED ||
79 event->type() == ui::ET_MOUSE_RELEASED)) {
80 return ui::ER_UNHANDLED;
81 }
82
83 if (event->type() == ui::ET_MOUSE_RELEASED ||
84 !(event->flags() & ui::EF_CONTROL_DOWN) ||
85 !(event->flags() & ui::EF_LEFT_MOUSE_BUTTON)) {
86 StopScrubbing();
87 return ui::ER_UNHANDLED;
88 }
89
90 if (scrub_state_ == CANCELLED_SCRUBBING)
91 return ui::ER_UNHANDLED;
92
93 if (scrub_state_ == NOT_SCRUBBING) {
94 StartScrubbing();
95 last_transition_position_ = event->root_location();
96 return ui::ER_HANDLED;
97 }
98
99 gfx::Point event_location = event->root_location();
100 int delta_x = event_location.x() - last_transition_position_.x();
101 int delta_y = event_location.y() - last_transition_position_.y();
102 if (std::abs(delta_x) > kMaxHorizontalMovementPerWorkspaceStep) {
103 scrub_state_ = CANCELLED_SCRUBBING;
104 return ui::ER_UNHANDLED;
105 }
106
107 int num_scrub_steps = std::abs(delta_y / kWorkspaceStepSize);
108 for (int i = 0; i < num_scrub_steps; ++i) {
sadrul 2012/11/23 20:02:07 Why the loop here?
109 bool switching_succeeded = false;
110 if (delta_y > 0) {
111 switching_succeeded =
112 workspace_manager_->CycleAwayFromCurrentlyActiveWorkspace();
113 } else {
114 // If the initial workspace is visible, then cycling to hidden workspaces
115 // should be disabled as not to scrub to workspaces which were minimized
116 // before scrubbing was initiated.
sadrul 2012/11/23 20:02:07 Do we not want to go to previously minimized windo
pkotwicz 2012/11/23 22:08:32 I am unsure. My personal preference is not to scru
sadrul 2012/11/26 16:55:50 We should confirm this with UX
117 if (initial_workspace_window_->IsVisible())
118 break;
119
120 switching_succeeded = workspace_manager_->CycleToNextHiddenWorkspace();
121 }
122 if (!switching_succeeded)
123 break;
124 }
125
126 if (delta_y != 0) {
127 // Set |last_transition_y| such that it is the minimum y position which
128 // would have produced |num_scrub_steps|.
129 int last_transition_y = event_location.y();
130 if (delta_y > 0)
131 last_transition_y -= delta_y % kWorkspaceStepSize;
132 else if (delta_y < 0)
133 last_transition_y += std::abs(delta_y) % kWorkspaceStepSize;
134
135 last_transition_position_ =
136 gfx::Point(event_location.x(), last_transition_y);
137 }
138
139 return ui::ER_HANDLED;
sadrul 2012/11/23 20:02:07 The logic in this function seems rather complex. I
140 }
141
142 ui::EventResult WorkspaceCycler::OnScrollEvent(ui::ScrollEvent* event) {
143 return ui::ER_UNHANDLED;
144 }
145
146 ui::EventResult WorkspaceCycler::OnTouchEvent(ui::TouchEvent* event) {
147 return ui::ER_UNHANDLED;
148 }
149
150 ui::EventResult WorkspaceCycler::OnGestureEvent(ui::GestureEvent* event) {
151 return ui::ER_UNHANDLED;
152 }
153
154 } // namespace internal
155 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698