OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ui/views/widget/desktop_aura/x11_window_event_filter.h" | 5 #include "ui/views/widget/desktop_aura/x11_window_event_filter.h" |
6 | 6 |
7 #include <X11/extensions/XInput.h> | 7 #include <X11/extensions/XInput.h> |
8 #include <X11/extensions/XInput2.h> | 8 #include <X11/extensions/XInput2.h> |
9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
10 #include <X11/Xlib.h> | 10 #include <X11/Xlib.h> |
(...skipping 28 matching lines...) Expand all Loading... |
39 const int k_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT = 6; | 39 const int k_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT = 6; |
40 const int k_NET_WM_MOVERESIZE_SIZE_LEFT = 7; | 40 const int k_NET_WM_MOVERESIZE_SIZE_LEFT = 7; |
41 const int k_NET_WM_MOVERESIZE_MOVE = 8; | 41 const int k_NET_WM_MOVERESIZE_MOVE = 8; |
42 | 42 |
43 } // namespace | 43 } // namespace |
44 | 44 |
45 namespace views { | 45 namespace views { |
46 | 46 |
47 X11WindowEventFilter::X11WindowEventFilter( | 47 X11WindowEventFilter::X11WindowEventFilter( |
48 DesktopWindowTreeHost* window_tree_host) | 48 DesktopWindowTreeHost* window_tree_host) |
49 : xdisplay_(gfx::GetXDisplay()), | 49 : WindowEventFilter(window_tree_host), |
| 50 xdisplay_(gfx::GetXDisplay()), |
50 xwindow_(window_tree_host->AsWindowTreeHost()->GetAcceleratedWidget()), | 51 xwindow_(window_tree_host->AsWindowTreeHost()->GetAcceleratedWidget()), |
51 x_root_window_(DefaultRootWindow(xdisplay_)), | 52 x_root_window_(DefaultRootWindow(xdisplay_)) {} |
52 window_tree_host_(window_tree_host), | |
53 click_component_(HTNOWHERE) { | |
54 } | |
55 | 53 |
56 X11WindowEventFilter::~X11WindowEventFilter() { | 54 X11WindowEventFilter::~X11WindowEventFilter() { |
57 } | 55 } |
58 | 56 |
59 void X11WindowEventFilter::OnMouseEvent(ui::MouseEvent* event) { | 57 void X11WindowEventFilter::MaybeDispatchHostWindowDragMovement( |
60 if (event->type() != ui::ET_MOUSE_PRESSED) | 58 int hittest, |
61 return; | 59 ui::MouseEvent* event) { |
62 | 60 if (event->IsLeftMouseButton() && event->native_event()) { |
63 aura::Window* target = static_cast<aura::Window*>(event->target()); | |
64 if (!target->delegate()) | |
65 return; | |
66 | |
67 int previous_click_component = HTNOWHERE; | |
68 int component = | |
69 target->delegate()->GetNonClientComponent(event->location()); | |
70 if (event->IsLeftMouseButton()) { | |
71 previous_click_component = click_component_; | |
72 click_component_ = component; | |
73 } | |
74 | |
75 if (component == HTCAPTION) { | |
76 OnClickedCaption(event, previous_click_component); | |
77 } else if (component == HTMAXBUTTON) { | |
78 OnClickedMaximizeButton(event); | |
79 } else { | |
80 // Get the |x_root_window_| location out of the native event. | 61 // Get the |x_root_window_| location out of the native event. |
81 if (event->IsLeftMouseButton() && event->native_event()) { | |
82 const gfx::Point x_root_location = | |
83 ui::EventSystemLocationFromNative(event->native_event()); | |
84 if ((target->GetProperty(aura::client::kResizeBehaviorKey) & | |
85 ui::mojom::kResizeBehaviorCanResize) && | |
86 DispatchHostWindowDragMovement(component, x_root_location)) { | |
87 event->StopPropagation(); | |
88 } | |
89 } | |
90 } | |
91 } | |
92 | |
93 void X11WindowEventFilter::OnClickedCaption(ui::MouseEvent* event, | |
94 int previous_click_component) { | |
95 aura::Window* target = static_cast<aura::Window*>(event->target()); | |
96 | |
97 if (event->IsMiddleMouseButton()) { | |
98 LinuxUI::NonClientMiddleClickAction action = | |
99 LinuxUI::MIDDLE_CLICK_ACTION_LOWER; | |
100 LinuxUI* linux_ui = LinuxUI::instance(); | |
101 if (linux_ui) | |
102 action = linux_ui->GetNonClientMiddleClickAction(); | |
103 | |
104 switch (action) { | |
105 case LinuxUI::MIDDLE_CLICK_ACTION_NONE: | |
106 break; | |
107 case LinuxUI::MIDDLE_CLICK_ACTION_LOWER: | |
108 XLowerWindow(xdisplay_, xwindow_); | |
109 break; | |
110 case LinuxUI::MIDDLE_CLICK_ACTION_MINIMIZE: | |
111 window_tree_host_->Minimize(); | |
112 break; | |
113 case LinuxUI::MIDDLE_CLICK_ACTION_TOGGLE_MAXIMIZE: | |
114 if (target->GetProperty(aura::client::kResizeBehaviorKey) & | |
115 ui::mojom::kResizeBehaviorCanMaximize) | |
116 ToggleMaximizedState(); | |
117 break; | |
118 } | |
119 | |
120 event->SetHandled(); | |
121 return; | |
122 } | |
123 | |
124 if (event->IsLeftMouseButton() && event->flags() & ui::EF_IS_DOUBLE_CLICK) { | |
125 click_component_ = HTNOWHERE; | |
126 if ((target->GetProperty(aura::client::kResizeBehaviorKey) & | |
127 ui::mojom::kResizeBehaviorCanMaximize) && | |
128 previous_click_component == HTCAPTION) { | |
129 // Our event is a double click in the caption area in a window that can be | |
130 // maximized. We are responsible for dispatching this as a minimize/ | |
131 // maximize on X11 (Windows converts this to min/max events for us). | |
132 ToggleMaximizedState(); | |
133 event->SetHandled(); | |
134 return; | |
135 } | |
136 } | |
137 | |
138 // Get the |x_root_window_| location out of the native event. | |
139 if (event->IsLeftMouseButton() && event->native_event()) { | |
140 const gfx::Point x_root_location = | 62 const gfx::Point x_root_location = |
141 ui::EventSystemLocationFromNative(event->native_event()); | 63 ui::EventSystemLocationFromNative(event->native_event()); |
142 if (DispatchHostWindowDragMovement(HTCAPTION, x_root_location)) | 64 if (DispatchHostWindowDragMovement(hittest, x_root_location)) |
143 event->StopPropagation(); | 65 event->StopPropagation(); |
144 } | 66 } |
145 } | 67 } |
146 | 68 |
147 void X11WindowEventFilter::OnClickedMaximizeButton(ui::MouseEvent* event) { | 69 void X11WindowEventFilter::LowerWindow() { |
148 aura::Window* target = static_cast<aura::Window*>(event->target()); | 70 XLowerWindow(xdisplay_, xwindow_); |
149 views::Widget* widget = views::Widget::GetWidgetForNativeView(target); | |
150 if (!widget) | |
151 return; | |
152 | |
153 gfx::Rect display_work_area = | |
154 display::Screen::GetScreen()->GetDisplayNearestWindow(target).work_area(); | |
155 gfx::Rect bounds = widget->GetWindowBoundsInScreen(); | |
156 if (event->IsMiddleMouseButton()) { | |
157 bounds.set_y(display_work_area.y()); | |
158 bounds.set_height(display_work_area.height()); | |
159 widget->SetBounds(bounds); | |
160 event->StopPropagation(); | |
161 } else if (event->IsRightMouseButton()) { | |
162 bounds.set_x(display_work_area.x()); | |
163 bounds.set_width(display_work_area.width()); | |
164 widget->SetBounds(bounds); | |
165 event->StopPropagation(); | |
166 } | |
167 } | |
168 | |
169 void X11WindowEventFilter::ToggleMaximizedState() { | |
170 if (window_tree_host_->IsMaximized()) | |
171 window_tree_host_->Restore(); | |
172 else | |
173 window_tree_host_->Maximize(); | |
174 } | 71 } |
175 | 72 |
176 bool X11WindowEventFilter::DispatchHostWindowDragMovement( | 73 bool X11WindowEventFilter::DispatchHostWindowDragMovement( |
177 int hittest, | 74 int hittest, |
178 const gfx::Point& screen_location) { | 75 const gfx::Point& screen_location) { |
179 int direction = -1; | 76 int direction = -1; |
180 switch (hittest) { | 77 switch (hittest) { |
181 case HTBOTTOM: | 78 case HTBOTTOM: |
182 direction = k_NET_WM_MOVERESIZE_SIZE_BOTTOM; | 79 direction = k_NET_WM_MOVERESIZE_SIZE_BOTTOM; |
183 break; | 80 break; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 event.xclient.data.l[4] = 0; | 126 event.xclient.data.l[4] = 0; |
230 | 127 |
231 XSendEvent(xdisplay_, x_root_window_, False, | 128 XSendEvent(xdisplay_, x_root_window_, False, |
232 SubstructureRedirectMask | SubstructureNotifyMask, | 129 SubstructureRedirectMask | SubstructureNotifyMask, |
233 &event); | 130 &event); |
234 | 131 |
235 return true; | 132 return true; |
236 } | 133 } |
237 | 134 |
238 } // namespace views | 135 } // namespace views |
OLD | NEW |