OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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 "ui/views/widget/desktop_aura/window_event_filter.h" |
| 6 |
| 7 #include "services/ui/public/interfaces/window_manager_constants.mojom.h" |
| 8 #include "ui/aura/client/aura_constants.h" |
| 9 #include "ui/aura/window.h" |
| 10 #include "ui/aura/window_delegate.h" |
| 11 #include "ui/aura/window_tree_host.h" |
| 12 #include "ui/base/hit_test.h" |
| 13 #include "ui/display/display.h" |
| 14 #include "ui/display/screen.h" |
| 15 #include "ui/events/event.h" |
| 16 #include "ui/events/event_utils.h" |
| 17 #include "ui/views/linux_ui/linux_ui.h" |
| 18 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h" |
| 19 #include "ui/views/widget/native_widget_aura.h" |
| 20 #include "ui/views/widget/widget.h" |
| 21 |
| 22 namespace views { |
| 23 |
| 24 WindowEventFilter::WindowEventFilter(DesktopWindowTreeHost* window_tree_host) |
| 25 : window_tree_host_(window_tree_host), click_component_(HTNOWHERE) {} |
| 26 |
| 27 WindowEventFilter::~WindowEventFilter() {} |
| 28 |
| 29 void WindowEventFilter::OnMouseEvent(ui::MouseEvent* event) { |
| 30 if (event->type() != ui::ET_MOUSE_PRESSED) |
| 31 return; |
| 32 |
| 33 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 34 if (!target->delegate()) |
| 35 return; |
| 36 |
| 37 int previous_click_component = HTNOWHERE; |
| 38 int component = target->delegate()->GetNonClientComponent(event->location()); |
| 39 if (event->IsLeftMouseButton()) { |
| 40 previous_click_component = click_component_; |
| 41 click_component_ = component; |
| 42 } |
| 43 |
| 44 if (component == HTCAPTION) { |
| 45 OnClickedCaption(event, previous_click_component); |
| 46 } else if (component == HTMAXBUTTON) { |
| 47 OnClickedMaximizeButton(event); |
| 48 } else { |
| 49 if (target->GetProperty(aura::client::kResizeBehaviorKey) & |
| 50 ui::mojom::kResizeBehaviorCanResize) { |
| 51 MaybeDispatchHostWindowDragMovement(component, event); |
| 52 } |
| 53 } |
| 54 } |
| 55 |
| 56 void WindowEventFilter::OnClickedCaption(ui::MouseEvent* event, |
| 57 int previous_click_component) { |
| 58 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 59 |
| 60 if (event->IsMiddleMouseButton()) { |
| 61 LinuxUI::NonClientMiddleClickAction action = |
| 62 LinuxUI::MIDDLE_CLICK_ACTION_LOWER; |
| 63 LinuxUI* linux_ui = LinuxUI::instance(); |
| 64 if (linux_ui) |
| 65 action = linux_ui->GetNonClientMiddleClickAction(); |
| 66 |
| 67 switch (action) { |
| 68 case LinuxUI::MIDDLE_CLICK_ACTION_NONE: |
| 69 break; |
| 70 case LinuxUI::MIDDLE_CLICK_ACTION_LOWER: |
| 71 LowerWindow(); |
| 72 break; |
| 73 case LinuxUI::MIDDLE_CLICK_ACTION_MINIMIZE: |
| 74 window_tree_host_->Minimize(); |
| 75 break; |
| 76 case LinuxUI::MIDDLE_CLICK_ACTION_TOGGLE_MAXIMIZE: |
| 77 if (target->GetProperty(aura::client::kResizeBehaviorKey) & |
| 78 ui::mojom::kResizeBehaviorCanMaximize) |
| 79 ToggleMaximizedState(); |
| 80 break; |
| 81 } |
| 82 |
| 83 event->SetHandled(); |
| 84 return; |
| 85 } |
| 86 |
| 87 if (event->IsLeftMouseButton() && event->flags() & ui::EF_IS_DOUBLE_CLICK) { |
| 88 click_component_ = HTNOWHERE; |
| 89 if ((target->GetProperty(aura::client::kResizeBehaviorKey) & |
| 90 ui::mojom::kResizeBehaviorCanMaximize) && |
| 91 previous_click_component == HTCAPTION) { |
| 92 // Our event is a double click in the caption area in a window that can be |
| 93 // maximized. We are responsible for dispatching this as a minimize/ |
| 94 // maximize on X11 (Windows converts this to min/max events for us). |
| 95 ToggleMaximizedState(); |
| 96 event->SetHandled(); |
| 97 return; |
| 98 } |
| 99 } |
| 100 |
| 101 MaybeDispatchHostWindowDragMovement(HTCAPTION, event); |
| 102 } |
| 103 |
| 104 void WindowEventFilter::OnClickedMaximizeButton(ui::MouseEvent* event) { |
| 105 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 106 views::Widget* widget = views::Widget::GetWidgetForNativeView(target); |
| 107 if (!widget) |
| 108 return; |
| 109 |
| 110 gfx::Rect display_work_area = |
| 111 display::Screen::GetScreen()->GetDisplayNearestWindow(target).work_area(); |
| 112 gfx::Rect bounds = widget->GetWindowBoundsInScreen(); |
| 113 if (event->IsMiddleMouseButton()) { |
| 114 bounds.set_y(display_work_area.y()); |
| 115 bounds.set_height(display_work_area.height()); |
| 116 widget->SetBounds(bounds); |
| 117 event->StopPropagation(); |
| 118 } else if (event->IsRightMouseButton()) { |
| 119 bounds.set_x(display_work_area.x()); |
| 120 bounds.set_width(display_work_area.width()); |
| 121 widget->SetBounds(bounds); |
| 122 event->StopPropagation(); |
| 123 } |
| 124 } |
| 125 |
| 126 void WindowEventFilter::ToggleMaximizedState() { |
| 127 if (window_tree_host_->IsMaximized()) |
| 128 window_tree_host_->Restore(); |
| 129 else |
| 130 window_tree_host_->Maximize(); |
| 131 } |
| 132 |
| 133 void WindowEventFilter::LowerWindow() {} |
| 134 |
| 135 void WindowEventFilter::MaybeDispatchHostWindowDragMovement( |
| 136 int hittest, |
| 137 ui::MouseEvent* event) {} |
| 138 |
| 139 } // namespace views |
OLD | NEW |