| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS 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 "window_manager/layout/layout_manager.h" | 5 #include "window_manager/layout/layout_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <cstdio> | 9 #include <cstdio> |
| 10 #include <tr1/memory> | 10 #include <tr1/memory> |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 overview_drag_last_x_(-1), | 123 overview_drag_last_x_(-1), |
| 124 saw_map_request_(false), | 124 saw_map_request_(false), |
| 125 first_toplevel_chrome_window_mapped_(false), | 125 first_toplevel_chrome_window_mapped_(false), |
| 126 event_consumer_registrar_(new EventConsumerRegistrar(wm, this)), | 126 event_consumer_registrar_(new EventConsumerRegistrar(wm, this)), |
| 127 key_bindings_actions_(new KeyBindingsActionRegistrar(wm->key_bindings())), | 127 key_bindings_actions_(new KeyBindingsActionRegistrar(wm->key_bindings())), |
| 128 active_mode_key_bindings_group_(new KeyBindingsGroup(wm->key_bindings())), | 128 active_mode_key_bindings_group_(new KeyBindingsGroup(wm->key_bindings())), |
| 129 overview_mode_key_bindings_group_( | 129 overview_mode_key_bindings_group_( |
| 130 new KeyBindingsGroup(wm->key_bindings())), | 130 new KeyBindingsGroup(wm->key_bindings())), |
| 131 post_toplevel_key_bindings_group_( | 131 post_toplevel_key_bindings_group_( |
| 132 new KeyBindingsGroup(wm->key_bindings())), | 132 new KeyBindingsGroup(wm->key_bindings())), |
| 133 background_xid_(wm_->CreateInputWindow(wm_->bounds(), 0)), | 133 background_xid_(wm_->CreateInputWindow(wm_->root_bounds(), 0)), |
| 134 should_layout_windows_after_initial_pixmap_(false), | 134 should_layout_windows_after_initial_pixmap_(false), |
| 135 should_animate_after_initial_pixmap_(false) { | 135 should_animate_after_initial_pixmap_(false) { |
| 136 wm_->focus_manager()->RegisterFocusChangeListener(this); | 136 wm_->focus_manager()->RegisterFocusChangeListener(this); |
| 137 panel_manager_->RegisterAreaChangeListener(this); | 137 panel_manager_->RegisterAreaChangeListener(this); |
| 138 panel_manager_->GetArea(&panel_manager_left_width_, | 138 panel_manager_->GetArea(&panel_manager_left_width_, |
| 139 &panel_manager_right_width_); | 139 &panel_manager_right_width_); |
| 140 | 140 |
| 141 // Disable the overview key bindings, since we start in active mode. | 141 // Disable the overview key bindings, since we start in active mode. |
| 142 overview_mode_key_bindings_group_->Disable(); | 142 overview_mode_key_bindings_group_->Disable(); |
| 143 post_toplevel_key_bindings_group_->Disable(); | 143 post_toplevel_key_bindings_group_->Disable(); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 } | 335 } |
| 336 | 336 |
| 337 bool LayoutManager::IsInputWindow(XWindow xid) { | 337 bool LayoutManager::IsInputWindow(XWindow xid) { |
| 338 return (GetSnapshotWindowByInputXid(xid) != NULL); | 338 return (GetSnapshotWindowByInputXid(xid) != NULL); |
| 339 } | 339 } |
| 340 | 340 |
| 341 void LayoutManager::HandleScreenResize() { | 341 void LayoutManager::HandleScreenResize() { |
| 342 MoveAndResizeForAvailableArea(); | 342 MoveAndResizeForAvailableArea(); |
| 343 ConfigureBackground(wm_->width(), wm_->height()); | 343 ConfigureBackground(wm_->width(), wm_->height()); |
| 344 if (background_xid_) | 344 if (background_xid_) |
| 345 wm_->xconn()->ResizeWindow(background_xid_, | 345 wm_->xconn()->ResizeWindow(background_xid_, wm_->root_size()); |
| 346 Size(wm_->width(), wm_->height())); | |
| 347 } | 346 } |
| 348 | 347 |
| 349 bool LayoutManager::HandleWindowMapRequest(Window* win) { | 348 bool LayoutManager::HandleWindowMapRequest(Window* win) { |
| 350 DCHECK(win); | 349 DCHECK(win); |
| 351 saw_map_request_ = true; | 350 saw_map_request_ = true; |
| 352 | 351 |
| 353 if (!IsHandledWindowType(win->type())) | 352 if (!IsHandledWindowType(win->type())) |
| 354 return false; | 353 return false; |
| 355 | 354 |
| 356 if (win->type() == chromeos::WM_IPC_WINDOW_CHROME_TAB_FAV_ICON || | 355 if (win->type() == chromeos::WM_IPC_WINDOW_CHROME_TAB_FAV_ICON || |
| 357 win->type() == chromeos::WM_IPC_WINDOW_CHROME_TAB_SNAPSHOT || | 356 win->type() == chromeos::WM_IPC_WINDOW_CHROME_TAB_SNAPSHOT || |
| 358 win->type() == chromeos::WM_IPC_WINDOW_CHROME_TAB_TITLE) { | 357 win->type() == chromeos::WM_IPC_WINDOW_CHROME_TAB_TITLE) { |
| 359 wm_->stacking_manager()->StackWindowAtTopOfLayer( | 358 wm_->stacking_manager()->StackWindowAtTopOfLayer( |
| 360 win, | 359 win, |
| 361 StackingManager::LAYER_SNAPSHOT_WINDOW, | 360 StackingManager::LAYER_SNAPSHOT_WINDOW, |
| 362 StackingManager::SHADOW_AT_BOTTOM_OF_LAYER); | 361 StackingManager::SHADOW_AT_BOTTOM_OF_LAYER); |
| 363 } else { | 362 } else { |
| 364 wm_->stacking_manager()->StackWindowAtTopOfLayer( | 363 wm_->stacking_manager()->StackWindowAtTopOfLayer( |
| 365 win, | 364 win, |
| 366 StackingManager::LAYER_TOPLEVEL_WINDOW, | 365 StackingManager::LAYER_TOPLEVEL_WINDOW, |
| 367 StackingManager::SHADOW_AT_BOTTOM_OF_LAYER); | 366 StackingManager::SHADOW_AT_BOTTOM_OF_LAYER); |
| 368 | 367 |
| 369 // Resize windows to their final size before mapping them to give them | 368 // Resize windows to their final size before mapping them to give them |
| 370 // more time to draw their contents. | 369 // more time to draw their contents. |
| 371 if ((win->type() == chromeos::WM_IPC_WINDOW_CHROME_TOPLEVEL || | 370 if ((win->type() == chromeos::WM_IPC_WINDOW_CHROME_TOPLEVEL || |
| 372 win->type() == chromeos::WM_IPC_WINDOW_UNKNOWN) && | 371 win->type() == chromeos::WM_IPC_WINDOW_UNKNOWN) && |
| 373 !win->transient_for_xid()) { | 372 !win->transient_for_xid()) { |
| 374 win->ResizeClient(width_, height_, GRAVITY_NORTHWEST); | 373 win->Resize(Size(width_, height_), GRAVITY_NORTHWEST); |
| 375 } | 374 } |
| 376 } | 375 } |
| 377 return true; | 376 return true; |
| 378 } | 377 } |
| 379 | 378 |
| 380 void LayoutManager::HandleWindowMap(Window* win) { | 379 void LayoutManager::HandleWindowMap(Window* win) { |
| 381 DCHECK(win); | 380 DCHECK(win); |
| 382 if (win->override_redirect() || !IsHandledWindowType(win->type())) | 381 if (win->override_redirect() || !IsHandledWindowType(win->type())) |
| 383 return; | 382 return; |
| 384 | 383 |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 DCHECK(win); | 591 DCHECK(win); |
| 593 | 592 |
| 594 if (should_layout_windows_after_initial_pixmap_ && | 593 if (should_layout_windows_after_initial_pixmap_ && |
| 595 current_toplevel_ && current_toplevel_->win() == win) { | 594 current_toplevel_ && current_toplevel_->win() == win) { |
| 596 should_layout_windows_after_initial_pixmap_ = false; | 595 should_layout_windows_after_initial_pixmap_ = false; |
| 597 LayoutWindows(should_animate_after_initial_pixmap_); | 596 LayoutWindows(should_animate_after_initial_pixmap_); |
| 598 } | 597 } |
| 599 } | 598 } |
| 600 | 599 |
| 601 void LayoutManager::HandleWindowConfigureRequest( | 600 void LayoutManager::HandleWindowConfigureRequest( |
| 602 Window* win, int req_x, int req_y, int req_width, int req_height) { | 601 Window* win, const Rect& requested_bounds) { |
| 603 if (win->type() == chromeos::WM_IPC_WINDOW_CHROME_TAB_SNAPSHOT) { | 602 if (win->type() == chromeos::WM_IPC_WINDOW_CHROME_TAB_SNAPSHOT) { |
| 604 SnapshotWindow* snapshot = GetSnapshotWindowByWindow(*win); | 603 SnapshotWindow* snapshot = GetSnapshotWindowByWindow(*win); |
| 605 if (snapshot) { | 604 if (snapshot) { |
| 606 if (req_width != win->client_width() || | 605 if (requested_bounds.size() != win->client_size()) { |
| 607 req_height != win->client_height()) { | 606 win->Resize(requested_bounds.size(), GRAVITY_NORTHWEST); |
| 608 win->ResizeClient(req_width, req_height, GRAVITY_NORTHWEST); | |
| 609 LayoutWindows(false); | 607 LayoutWindows(false); |
| 610 } else { | 608 } else { |
| 611 win->SendSyntheticConfigureNotify(); | 609 win->SendSyntheticConfigureNotify(); |
| 612 } | 610 } |
| 613 } | 611 } |
| 614 return; | 612 return; |
| 615 } | 613 } |
| 616 | 614 |
| 617 ToplevelWindow* toplevel_owner = GetToplevelWindowOwningTransientWindow(*win); | 615 ToplevelWindow* toplevel_owner = GetToplevelWindowOwningTransientWindow(*win); |
| 618 if (toplevel_owner) { | 616 if (toplevel_owner) { |
| 619 toplevel_owner->HandleTransientWindowConfigureRequest( | 617 toplevel_owner->HandleTransientWindowConfigureRequest( |
| 620 win, req_x, req_y, req_width, req_height); | 618 win, requested_bounds); |
| 621 return; | 619 return; |
| 622 } | 620 } |
| 623 | 621 |
| 624 // Ignore requests to resize toplevel windows, but send them fake | 622 // Ignore requests to resize toplevel windows, but send them fake |
| 625 // ConfigureNotify events to let them know that we saw the requests. | 623 // ConfigureNotify events to let them know that we saw the requests. |
| 626 ToplevelWindow* toplevel = GetToplevelWindowByWindow(*win); | 624 ToplevelWindow* toplevel = GetToplevelWindowByWindow(*win); |
| 627 if (toplevel) { | 625 if (toplevel) { |
| 628 win->SendSyntheticConfigureNotify(); | 626 win->SendSyntheticConfigureNotify(); |
| 629 return; | 627 return; |
| 630 } | 628 } |
| 631 } | 629 } |
| 632 | 630 |
| 633 void LayoutManager::HandleButtonPress(XWindow xid, | 631 void LayoutManager::HandleButtonPress(XWindow xid, |
| 634 int x, int y, | 632 const Point& relative_pos, |
| 635 int x_root, int y_root, | 633 const Point& absolute_pos, |
| 636 int button, | 634 int button, |
| 637 XTime timestamp) { | 635 XTime timestamp) { |
| 638 if (xid == background_xid_ && button == 1) { | 636 if (xid == background_xid_ && button == 1) { |
| 639 overview_drag_last_x_ = x; | 637 overview_drag_last_x_ = relative_pos.x; |
| 640 overview_background_event_coalescer_->Start(); | 638 overview_background_event_coalescer_->Start(); |
| 641 return; | 639 return; |
| 642 } | 640 } |
| 643 | 641 |
| 644 Window* win = wm_->GetWindow(xid); | 642 Window* win = wm_->GetWindow(xid); |
| 645 if (!win) | 643 if (!win) |
| 646 return; | 644 return; |
| 647 | 645 |
| 648 // Otherwise, it probably means that the user previously focused a panel | 646 // Otherwise, it probably means that the user previously focused a panel |
| 649 // and then clicked back on a toplevel or transient window. | 647 // and then clicked back on a toplevel or transient window. |
| 650 ToplevelWindow* toplevel = GetToplevelWindowOwningTransientWindow(*win); | 648 ToplevelWindow* toplevel = GetToplevelWindowOwningTransientWindow(*win); |
| 651 if (!toplevel) | 649 if (!toplevel) |
| 652 toplevel = GetToplevelWindowByWindow(*win); | 650 toplevel = GetToplevelWindowByWindow(*win); |
| 653 if (toplevel) | 651 if (toplevel) |
| 654 toplevel->HandleButtonPress(win, timestamp); | 652 toplevel->HandleButtonPress(win, timestamp); |
| 655 } | 653 } |
| 656 | 654 |
| 657 void LayoutManager::HandleButtonRelease(XWindow xid, | 655 void LayoutManager::HandleButtonRelease(XWindow xid, |
| 658 int x, int y, | 656 const Point& relative_pos, |
| 659 int x_root, int y_root, | 657 const Point& absolute_pos, |
| 660 int button, | 658 int button, |
| 661 XTime timestamp) { | 659 XTime timestamp) { |
| 662 SnapshotWindow* snapshot = GetSnapshotWindowByInputXid(xid); | 660 SnapshotWindow* snapshot = GetSnapshotWindowByInputXid(xid); |
| 663 if (snapshot) { | 661 if (snapshot) { |
| 664 if (button == 1) { // Ignore buttons other than 1. | 662 if (button == 1) { // Ignore buttons other than 1. |
| 665 LOG_IF(WARNING, mode_ != MODE_OVERVIEW) | 663 LOG_IF(WARNING, mode_ != MODE_OVERVIEW) |
| 666 << "Got a click in input window " << XidStr(xid) | 664 << "Got a click in input window " << XidStr(xid) |
| 667 << " for snapshot window " << snapshot->win()->xid_str() | 665 << " for snapshot window " << snapshot->win()->xid_str() |
| 668 << " while not in overview mode"; | 666 << " while not in overview mode"; |
| 669 snapshot->HandleButtonRelease(timestamp, x_root - x_, y_root - y_); | 667 snapshot->HandleButtonRelease( |
| 668 timestamp, absolute_pos.x - x_, absolute_pos.y - y_); |
| 670 } | 669 } |
| 671 return; | 670 return; |
| 672 } | 671 } |
| 673 | 672 |
| 674 if (xid != background_xid_ || button != 1) | 673 if (xid != background_xid_ || button != 1) |
| 675 return; | 674 return; |
| 676 | 675 |
| 677 // The X server automatically removes our asynchronous pointer grab when | 676 // The X server automatically removes our asynchronous pointer grab when |
| 678 // the mouse buttons are released. | 677 // the mouse buttons are released. |
| 679 overview_background_event_coalescer_->Stop(); | 678 overview_background_event_coalescer_->Stop(); |
| 680 | 679 |
| 681 // We need to do one last configure to update the input windows' | 680 // We need to do one last configure to update the input windows' |
| 682 // positions, which we didn't bother doing while panning. | 681 // positions, which we didn't bother doing while panning. |
| 683 LayoutWindows(true); | 682 LayoutWindows(true); |
| 684 | 683 |
| 685 return; | 684 return; |
| 686 } | 685 } |
| 687 | 686 |
| 688 void LayoutManager::HandlePointerMotion(XWindow xid, | 687 void LayoutManager::HandlePointerMotion(XWindow xid, |
| 689 int x, int y, | 688 const Point& relative_pos, |
| 690 int x_root, int y_root, | 689 const Point& absolute_pos, |
| 691 XTime timestamp) { | 690 XTime timestamp) { |
| 692 if (xid == background_xid_) | 691 if (xid == background_xid_) |
| 693 overview_background_event_coalescer_->StorePosition(x, y); | 692 overview_background_event_coalescer_->StorePosition(relative_pos); |
| 694 } | 693 } |
| 695 | 694 |
| 696 void LayoutManager::HandleChromeMessage(const WmIpc::Message& message) { | 695 void LayoutManager::HandleChromeMessage(const WmIpc::Message& message) { |
| 697 if (message.type() == chromeos::WM_IPC_MESSAGE_WM_CYCLE_WINDOWS) | 696 if (message.type() == chromeos::WM_IPC_MESSAGE_WM_CYCLE_WINDOWS) |
| 698 CycleCurrentToplevelWindow(message.param(0) != 0); | 697 CycleCurrentToplevelWindow(message.param(0) != 0); |
| 699 } | 698 } |
| 700 | 699 |
| 701 void LayoutManager::HandleClientMessage(XWindow xid, | 700 void LayoutManager::HandleClientMessage(XWindow xid, |
| 702 XAtom message_type, | 701 XAtom message_type, |
| 703 const long data[5]) { | 702 const long data[5]) { |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1150 // between the new and old right edge, then we keep the right sides of the | 1149 // between the new and old right edge, then we keep the right sides of the |
| 1151 // windows fixed while resizing. | 1150 // windows fixed while resizing. |
| 1152 Gravity resize_gravity = | 1151 Gravity resize_gravity = |
| 1153 abs(x_ - old_x) > abs(x_ + width_ - (old_x + old_width)) ? | 1152 abs(x_ - old_x) > abs(x_ + width_ - (old_x + old_width)) ? |
| 1154 GRAVITY_NORTHEAST : | 1153 GRAVITY_NORTHEAST : |
| 1155 GRAVITY_NORTHWEST; | 1154 GRAVITY_NORTHWEST; |
| 1156 | 1155 |
| 1157 for (ToplevelWindows::iterator it = toplevels_.begin(); | 1156 for (ToplevelWindows::iterator it = toplevels_.begin(); |
| 1158 it != toplevels_.end(); ++it) { | 1157 it != toplevels_.end(); ++it) { |
| 1159 if (it->get() == fullscreen_toplevel_) { | 1158 if (it->get() == fullscreen_toplevel_) { |
| 1160 (*it)->win()->ResizeClient(wm_->width(), wm_->height(), | 1159 (*it)->win()->Resize(wm_->root_size(), GRAVITY_NORTHWEST); |
| 1161 GRAVITY_NORTHWEST); | |
| 1162 } else { | 1160 } else { |
| 1163 (*it)->win()->ResizeClient(width_, height_, resize_gravity); | 1161 (*it)->win()->Resize(Size(width_, height_), resize_gravity); |
| 1164 } | 1162 } |
| 1165 } | 1163 } |
| 1166 | 1164 |
| 1167 LayoutWindows(true); | 1165 LayoutWindows(true); |
| 1168 } | 1166 } |
| 1169 | 1167 |
| 1170 void LayoutManager::SetCurrentToplevel(ToplevelWindow* toplevel) { | 1168 void LayoutManager::SetCurrentToplevel(ToplevelWindow* toplevel) { |
| 1171 CHECK(toplevel); | 1169 CHECK(toplevel); |
| 1172 | 1170 |
| 1173 // If we're not in active mode, nothing changes in the layout. | 1171 // If we're not in active mode, nothing changes in the layout. |
| (...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 } | 1946 } |
| 1949 } | 1947 } |
| 1950 | 1948 |
| 1951 if (previously_had_modal_transients && modal_transients_.empty()) | 1949 if (previously_had_modal_transients && modal_transients_.empty()) |
| 1952 EnableKeyBindingsForMode(mode_); | 1950 EnableKeyBindingsForMode(mode_); |
| 1953 else if (!previously_had_modal_transients && !modal_transients_.empty()) | 1951 else if (!previously_had_modal_transients && !modal_transients_.empty()) |
| 1954 DisableKeyBindingsForMode(mode_); | 1952 DisableKeyBindingsForMode(mode_); |
| 1955 } | 1953 } |
| 1956 | 1954 |
| 1957 } // namespace window_manager | 1955 } // namespace window_manager |
| OLD | NEW |