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

Side by Side Diff: ash/wm/common/window_positioner.cc

Issue 1926913002: Moves more code to ash/wm/common (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@refactor_workspace_layout_manager
Patch Set: merge to trunk Created 4 years, 7 months 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
« no previous file with comments | « ash/wm/common/window_positioner.h ('k') | ash/wm/common/workspace/workspace_layout_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/wm/window_positioner.h" 5 #include "ash/wm/common/window_positioner.h"
6 6
7 #include "ash/wm/common/window_positioning_utils.h" 7 #include "ash/wm/common/window_positioning_utils.h"
8 #include "ash/wm/common/window_state.h" 8 #include "ash/wm/common/window_state.h"
9 #include "ash/wm/common/wm_globals.h" 9 #include "ash/wm/common/wm_globals.h"
10 #include "ash/wm/common/wm_screen_util.h" 10 #include "ash/wm/common/wm_screen_util.h"
11 #include "ash/wm/common/wm_window.h" 11 #include "ash/wm/common/wm_window.h"
12 #include "ui/compositor/layer.h" 12 #include "ui/compositor/layer.h"
13 #include "ui/display/screen.h" 13 #include "ui/display/screen.h"
14 #include "ui/gfx/geometry/insets.h" 14 #include "ui/gfx/geometry/insets.h"
15 15
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 if ((child_bounds.x() <= work_area.x() && 101 if ((child_bounds.x() <= work_area.x() &&
102 new_child_bounds.x() <= work_area.x()) || 102 new_child_bounds.x() <= work_area.x()) ||
103 (child_bounds.right() >= work_area.right() && 103 (child_bounds.right() >= work_area.right() &&
104 new_child_bounds.right() >= work_area.right())) { 104 new_child_bounds.right() >= work_area.right())) {
105 continue; 105 continue;
106 } 106 }
107 if (new_child_bounds.right() > work_area.right()) 107 if (new_child_bounds.right() > work_area.right())
108 new_child_bounds.set_x(work_area.right() - bounds.width()); 108 new_child_bounds.set_x(work_area.right() - bounds.width());
109 else if (new_child_bounds.x() < work_area.x()) 109 else if (new_child_bounds.x() < work_area.x())
110 new_child_bounds.set_x(work_area.x()); 110 new_child_bounds.set_x(work_area.x());
111 SetBoundsAndOffsetTransientChildren(transient_child, 111 SetBoundsAndOffsetTransientChildren(transient_child, new_child_bounds,
112 new_child_bounds, work_area, offset); 112 work_area, offset);
113 } 113 }
114 114
115 window->SetBoundsWithTransitionDelay( 115 window->SetBoundsWithTransitionDelay(
116 bounds, base::TimeDelta::FromMilliseconds(kWindowAutoMoveDurationMS)); 116 bounds, base::TimeDelta::FromMilliseconds(kWindowAutoMoveDurationMS));
117 } 117 }
118 118
119 // Move a |window| to new |bounds|. Animate if desired by user. 119 // Move a |window| to new |bounds|. Animate if desired by user.
120 // Note: The function will do nothing if the bounds did not change. 120 // Note: The function will do nothing if the bounds did not change.
121 void SetBoundsAnimated(wm::WmWindow* window, 121 void SetBoundsAnimated(wm::WmWindow* window,
122 const gfx::Rect& bounds, 122 const gfx::Rect& bounds,
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 *show_state_out = ui::SHOW_STATE_MAXIMIZED; 247 *show_state_out = ui::SHOW_STATE_MAXIMIZED;
248 } 248 }
249 return; 249 return;
250 } 250 }
251 251
252 wm::WindowState* top_window_state = top_window->GetWindowState(); 252 wm::WindowState* top_window_state = top_window->GetWindowState();
253 bool maximized = top_window_state->IsMaximized(); 253 bool maximized = top_window_state->IsMaximized();
254 // We ignore the saved show state, but look instead for the top level 254 // We ignore the saved show state, but look instead for the top level
255 // window's show state. 255 // window's show state.
256 if (show_state_in == ui::SHOW_STATE_DEFAULT) { 256 if (show_state_in == ui::SHOW_STATE_DEFAULT) {
257 *show_state_out = maximized ? ui::SHOW_STATE_MAXIMIZED : 257 *show_state_out =
258 ui::SHOW_STATE_DEFAULT; 258 maximized ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_DEFAULT;
259 } 259 }
260 260
261 if (maximized || top_window_state->IsFullscreen()) { 261 if (maximized || top_window_state->IsFullscreen()) {
262 bool has_restore_bounds = top_window_state->HasRestoreBounds(); 262 bool has_restore_bounds = top_window_state->HasRestoreBounds();
263 if (has_restore_bounds) { 263 if (has_restore_bounds) {
264 // For a maximized/fullscreen window ignore the real bounds of 264 // For a maximized/fullscreen window ignore the real bounds of
265 // the top level window and use its restore bounds 265 // the top level window and use its restore bounds
266 // instead. Offset the bounds to prevent the windows from 266 // instead. Offset the bounds to prevent the windows from
267 // overlapping exactly when restored. 267 // overlapping exactly when restored.
268 *bounds_in_out = top_window_state->GetRestoreBoundsInScreen() + 268 *bounds_in_out =
269 top_window_state->GetRestoreBoundsInScreen() +
269 gfx::Vector2d(kMinimumWindowOffset, kMinimumWindowOffset); 270 gfx::Vector2d(kMinimumWindowOffset, kMinimumWindowOffset);
270 } 271 }
271 if (is_saved_bounds || has_restore_bounds) { 272 if (is_saved_bounds || has_restore_bounds) {
272 gfx::Rect work_area = target->GetDisplayNearestWindow().work_area(); 273 gfx::Rect work_area = target->GetDisplayNearestWindow().work_area();
273 bounds_in_out->AdjustToFit(work_area); 274 bounds_in_out->AdjustToFit(work_area);
274 // Use adjusted saved bounds or restore bounds, if there is one. 275 // Use adjusted saved bounds or restore bounds, if there is one.
275 return; 276 return;
276 } 277 }
277 } 278 }
278 279
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 376
376 WindowPositioner::WindowPositioner(wm::WmGlobals* globals) 377 WindowPositioner::WindowPositioner(wm::WmGlobals* globals)
377 : globals_(globals), 378 : globals_(globals),
378 pop_position_offset_increment_x(0), 379 pop_position_offset_increment_x(0),
379 pop_position_offset_increment_y(0), 380 pop_position_offset_increment_y(0),
380 popup_position_offset_from_screen_corner_x(0), 381 popup_position_offset_from_screen_corner_x(0),
381 popup_position_offset_from_screen_corner_y(0), 382 popup_position_offset_from_screen_corner_y(0),
382 last_popup_position_x_(0), 383 last_popup_position_x_(0),
383 last_popup_position_y_(0) {} 384 last_popup_position_y_(0) {}
384 385
385 WindowPositioner::~WindowPositioner() { 386 WindowPositioner::~WindowPositioner() {}
386 }
387 387
388 gfx::Rect WindowPositioner::GetDefaultWindowBounds( 388 gfx::Rect WindowPositioner::GetDefaultWindowBounds(
389 const display::Display& display) { 389 const display::Display& display) {
390 const gfx::Rect work_area = display.work_area(); 390 const gfx::Rect work_area = display.work_area();
391 // There should be a 'desktop' border around the window at the left and right 391 // There should be a 'desktop' border around the window at the left and right
392 // side. 392 // side.
393 int default_width = work_area.width() - 2 * kDesktopBorderSize; 393 int default_width = work_area.width() - 2 * kDesktopBorderSize;
394 // There should also be a 'desktop' border around the window at the top. 394 // There should also be a 'desktop' border around the window at the top.
395 // Since the workspace excludes the tray area we only need one border size. 395 // Since the workspace excludes the tray area we only need one border size.
396 int default_height = work_area.height() - kDesktopBorderSize; 396 int default_height = work_area.height() - kDesktopBorderSize;
397 int offset_x = kDesktopBorderSize; 397 int offset_x = kDesktopBorderSize;
398 if (default_width > kMaximumWindowWidth) { 398 if (default_width > kMaximumWindowWidth) {
399 // The window should get centered on the screen and not follow the grid. 399 // The window should get centered on the screen and not follow the grid.
400 offset_x = (work_area.width() - kMaximumWindowWidth) / 2; 400 offset_x = (work_area.width() - kMaximumWindowWidth) / 2;
401 default_width = kMaximumWindowWidth; 401 default_width = kMaximumWindowWidth;
402 } 402 }
403 return gfx::Rect(work_area.x() + offset_x, 403 return gfx::Rect(work_area.x() + offset_x, work_area.y() + kDesktopBorderSize,
404 work_area.y() + kDesktopBorderSize, 404 default_width, default_height);
405 default_width,
406 default_height);
407 } 405 }
408 406
409 gfx::Rect WindowPositioner::GetPopupPosition(const gfx::Rect& old_pos) { 407 gfx::Rect WindowPositioner::GetPopupPosition(const gfx::Rect& old_pos) {
410 int grid = kMinimumWindowOffset; 408 int grid = kMinimumWindowOffset;
411 popup_position_offset_from_screen_corner_x = grid; 409 popup_position_offset_from_screen_corner_x = grid;
412 popup_position_offset_from_screen_corner_y = grid; 410 popup_position_offset_from_screen_corner_y = grid;
413 if (!pop_position_offset_increment_x) { 411 if (!pop_position_offset_increment_x) {
414 // When the popup position increment is 0, the last popup position 412 // When the popup position increment is 0, the last popup position
415 // was not yet initialized. 413 // was not yet initialized.
416 last_popup_position_x_ = popup_position_offset_from_screen_corner_x; 414 last_popup_position_x_ = popup_position_offset_from_screen_corner_x;
417 last_popup_position_y_ = popup_position_offset_from_screen_corner_y; 415 last_popup_position_y_ = popup_position_offset_from_screen_corner_y;
418 } 416 }
419 pop_position_offset_increment_x = grid; 417 pop_position_offset_increment_x = grid;
420 pop_position_offset_increment_y = grid; 418 pop_position_offset_increment_y = grid;
421 // We handle the Multi monitor support by retrieving the active window's 419 // We handle the Multi monitor support by retrieving the active window's
422 // work area. 420 // work area.
423 wm::WmWindow* window = globals_->GetActiveWindow(); 421 wm::WmWindow* window = globals_->GetActiveWindow();
424 const gfx::Rect work_area = 422 const gfx::Rect work_area =
425 window && window->IsVisible() 423 window && window->IsVisible()
426 ? window->GetDisplayNearestWindow().work_area() 424 ? window->GetDisplayNearestWindow().work_area()
427 : display::Screen::GetScreen()->GetPrimaryDisplay().work_area(); 425 : display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
428 // Only try to reposition the popup when it is not spanning the entire 426 // Only try to reposition the popup when it is not spanning the entire
429 // screen. 427 // screen.
430 if ((old_pos.width() + popup_position_offset_from_screen_corner_x >= 428 if ((old_pos.width() + popup_position_offset_from_screen_corner_x >=
431 work_area.width()) || 429 work_area.width()) ||
432 (old_pos.height() + popup_position_offset_from_screen_corner_y >= 430 (old_pos.height() + popup_position_offset_from_screen_corner_y >=
433 work_area.height())) 431 work_area.height()))
434 return AlignPopupPosition(old_pos, work_area, grid); 432 return AlignPopupPosition(old_pos, work_area, grid);
435 const gfx::Rect result = SmartPopupPosition(old_pos, work_area, grid); 433 const gfx::Rect result = SmartPopupPosition(old_pos, work_area, grid);
436 if (!result.IsEmpty()) 434 if (!result.IsEmpty())
437 return AlignPopupPosition(result, work_area, grid); 435 return AlignPopupPosition(result, work_area, grid);
438 return NormalPopupPosition(old_pos, work_area); 436 return NormalPopupPosition(old_pos, work_area);
439 } 437 }
440 438
441 // static 439 // static
442 void WindowPositioner::SetMaximizeFirstWindow(bool maximize) { 440 void WindowPositioner::SetMaximizeFirstWindow(bool maximize) {
443 maximize_first_window = maximize; 441 maximize_first_window = maximize;
444 } 442 }
445 443
446 gfx::Rect WindowPositioner::NormalPopupPosition( 444 gfx::Rect WindowPositioner::NormalPopupPosition(const gfx::Rect& old_pos,
447 const gfx::Rect& old_pos, 445 const gfx::Rect& work_area) {
448 const gfx::Rect& work_area) {
449 int w = old_pos.width(); 446 int w = old_pos.width();
450 int h = old_pos.height(); 447 int h = old_pos.height();
451 // Note: The 'last_popup_position' is checked and kept relative to the 448 // Note: The 'last_popup_position' is checked and kept relative to the
452 // screen size. The offsetting will be done in the last step when the 449 // screen size. The offsetting will be done in the last step when the
453 // target rectangle gets returned. 450 // target rectangle gets returned.
454 bool reset = false; 451 bool reset = false;
455 if (last_popup_position_y_ + h > work_area.height() || 452 if (last_popup_position_y_ + h > work_area.height() ||
456 last_popup_position_x_ + w > work_area.width()) { 453 last_popup_position_x_ + w > work_area.width()) {
457 // Popup does not fit on screen. Reset to next diagonal row. 454 // Popup does not fit on screen. Reset to next diagonal row.
458 last_popup_position_x_ -= last_popup_position_y_ - 455 last_popup_position_x_ -= last_popup_position_y_ -
(...skipping 10 matching lines...) Expand all
469 } 466 }
470 int x = last_popup_position_x_; 467 int x = last_popup_position_x_;
471 int y = last_popup_position_y_; 468 int y = last_popup_position_y_;
472 if (!reset) { 469 if (!reset) {
473 last_popup_position_x_ += pop_position_offset_increment_x; 470 last_popup_position_x_ += pop_position_offset_increment_x;
474 last_popup_position_y_ += pop_position_offset_increment_y; 471 last_popup_position_y_ += pop_position_offset_increment_y;
475 } 472 }
476 return gfx::Rect(x + work_area.x(), y + work_area.y(), w, h); 473 return gfx::Rect(x + work_area.x(), y + work_area.y(), w, h);
477 } 474 }
478 475
479 gfx::Rect WindowPositioner::SmartPopupPosition( 476 gfx::Rect WindowPositioner::SmartPopupPosition(const gfx::Rect& old_pos,
480 const gfx::Rect& old_pos, 477 const gfx::Rect& work_area,
481 const gfx::Rect& work_area, 478 int grid) {
482 int grid) {
483 const std::vector<wm::WmWindow*> windows = 479 const std::vector<wm::WmWindow*> windows =
484 globals_->GetMruWindowListIgnoreModals(); 480 globals_->GetMruWindowListIgnoreModals();
485 481
486 std::vector<const gfx::Rect*> regions; 482 std::vector<const gfx::Rect*> regions;
487 // Process the window list and check if we can bail immediately. 483 // Process the window list and check if we can bail immediately.
488 for (size_t i = 0; i < windows.size(); i++) { 484 for (size_t i = 0; i < windows.size(); i++) {
489 // We only include opaque and visible windows. 485 // We only include opaque and visible windows.
490 if (windows[i] && windows[i]->IsVisible() && windows[i]->GetLayer() && 486 if (windows[i] && windows[i]->IsVisible() && windows[i]->GetLayer() &&
491 (windows[i]->GetLayer()->fills_bounds_opaquely() || 487 (windows[i]->GetLayer()->fills_bounds_opaquely() ||
492 windows[i]->GetLayer()->GetTargetOpacity() == 1.0)) { 488 windows[i]->GetLayer()->GetTargetOpacity() == 1.0)) {
(...skipping 16 matching lines...) Expand all
509 // We parse for a proper location on the screen. We do this in two runs: 505 // We parse for a proper location on the screen. We do this in two runs:
510 // The first run will start from the left, parsing down, skipping any 506 // The first run will start from the left, parsing down, skipping any
511 // overlapping windows it will encounter until the popup's height can not 507 // overlapping windows it will encounter until the popup's height can not
512 // be served anymore. Then the next grid position to the right will be 508 // be served anymore. Then the next grid position to the right will be
513 // taken, and the same cycle starts again. This will be repeated until we 509 // taken, and the same cycle starts again. This will be repeated until we
514 // hit the middle of the screen (or we find a suitable location). 510 // hit the middle of the screen (or we find a suitable location).
515 // In the second run we parse beginning from the right corner downwards and 511 // In the second run we parse beginning from the right corner downwards and
516 // then to the left. 512 // then to the left.
517 // When no location was found, an empty rectangle will be returned. 513 // When no location was found, an empty rectangle will be returned.
518 for (int run = 0; run < 2; run++) { 514 for (int run = 0; run < 2; run++) {
519 if (run == 0) { // First run: Start left, parse right till mid screen. 515 if (run == 0) { // First run: Start left, parse right till mid screen.
520 x = 0; 516 x = 0;
521 x_increment = pop_position_offset_increment_x; 517 x_increment = pop_position_offset_increment_x;
522 } else { // Second run: Start right, parse left till mid screen. 518 } else { // Second run: Start right, parse left till mid screen.
523 x = work_area.width() - w; 519 x = work_area.width() - w;
524 x_increment = -pop_position_offset_increment_x; 520 x_increment = -pop_position_offset_increment_x;
525 } 521 }
526 // Note: The passing (x,y,w,h) window is always relative to the work area's 522 // Note: The passing (x,y,w,h) window is always relative to the work area's
527 // origin. 523 // origin.
528 for (; x_increment > 0 ? (x < x_end) : (x > x_end); x += x_increment) { 524 for (; x_increment > 0 ? (x < x_end) : (x > x_end); x += x_increment) {
529 int y = 0; 525 int y = 0;
530 while (y + h <= work_area.height()) { 526 while (y + h <= work_area.height()) {
531 size_t i; 527 size_t i;
532 for (i = 0; i < regions.size(); i++) { 528 for (i = 0; i < regions.size(); i++) {
533 if (regions[i]->Intersects(gfx::Rect(x + work_area.x(), 529 if (regions[i]->Intersects(
534 y + work_area.y(), w, h))) { 530 gfx::Rect(x + work_area.x(), y + work_area.y(), w, h))) {
535 y = regions[i]->bottom() - work_area.y(); 531 y = regions[i]->bottom() - work_area.y();
536 break; 532 break;
537 } 533 }
538 } 534 }
539 if (i >= regions.size()) 535 if (i >= regions.size())
540 return gfx::Rect(x + work_area.x(), y + work_area.y(), w, h); 536 return gfx::Rect(x + work_area.x(), y + work_area.y(), w, h);
541 } 537 }
542 } 538 }
543 } 539 }
544 return gfx::Rect(0, 0, 0, 0); 540 return gfx::Rect(0, 0, 0, 0);
545 } 541 }
546 542
547 gfx::Rect WindowPositioner::AlignPopupPosition( 543 gfx::Rect WindowPositioner::AlignPopupPosition(const gfx::Rect& pos,
548 const gfx::Rect& pos, 544 const gfx::Rect& work_area,
549 const gfx::Rect& work_area, 545 int grid) {
550 int grid) {
551 if (grid <= 1) 546 if (grid <= 1)
552 return pos; 547 return pos;
553 548
554 int x = pos.x() - (pos.x() - work_area.x()) % grid; 549 int x = pos.x() - (pos.x() - work_area.x()) % grid;
555 int y = pos.y() - (pos.y() - work_area.y()) % grid; 550 int y = pos.y() - (pos.y() - work_area.y()) % grid;
556 int w = pos.width(); 551 int w = pos.width();
557 int h = pos.height(); 552 int h = pos.height();
558 553
559 // If the alignment was pushing the window out of the screen, we ignore the 554 // If the alignment was pushing the window out of the screen, we ignore the
560 // alignment for that call. 555 // alignment for that call.
561 if (abs(pos.right() - work_area.right()) < grid) 556 if (abs(pos.right() - work_area.right()) < grid)
562 x = work_area.right() - w; 557 x = work_area.right() - w;
563 if (abs(pos.bottom() - work_area.bottom()) < grid) 558 if (abs(pos.bottom() - work_area.bottom()) < grid)
564 y = work_area.bottom() - h; 559 y = work_area.bottom() - h;
565 return gfx::Rect(x, y, w, h); 560 return gfx::Rect(x, y, w, h);
566 } 561 }
567 562
568 } // namespace ash 563 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/common/window_positioner.h ('k') | ash/wm/common/workspace/workspace_layout_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698