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/desktop_window_tree_host_x11.h" | 5 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" |
6 | 6 |
7 #include <X11/extensions/shape.h> | 7 #include <X11/extensions/shape.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/Xregion.h> | 10 #include <X11/Xregion.h> |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 const int k_NET_WM_STATE_REMOVE = 0; | 84 const int k_NET_WM_STATE_REMOVE = 0; |
85 | 85 |
86 // Special value of the _NET_WM_DESKTOP property which indicates that the window | 86 // Special value of the _NET_WM_DESKTOP property which indicates that the window |
87 // should appear on all desktops. | 87 // should appear on all desktops. |
88 const int kAllDesktops = 0xFFFFFFFF; | 88 const int kAllDesktops = 0xFFFFFFFF; |
89 | 89 |
90 const char* kAtomsToCache[] = { | 90 const char* kAtomsToCache[] = { |
91 "UTF8_STRING", | 91 "UTF8_STRING", |
92 "WM_DELETE_WINDOW", | 92 "WM_DELETE_WINDOW", |
93 "WM_PROTOCOLS", | 93 "WM_PROTOCOLS", |
| 94 "_NET_ACTIVE_WINDOW", |
94 "_NET_FRAME_EXTENTS", | 95 "_NET_FRAME_EXTENTS", |
95 "_NET_WM_CM_S0", | 96 "_NET_WM_CM_S0", |
96 "_NET_WM_DESKTOP", | 97 "_NET_WM_DESKTOP", |
97 "_NET_WM_ICON", | 98 "_NET_WM_ICON", |
98 "_NET_WM_NAME", | 99 "_NET_WM_NAME", |
99 "_NET_WM_PID", | 100 "_NET_WM_PID", |
100 "_NET_WM_PING", | 101 "_NET_WM_PING", |
101 "_NET_WM_STATE", | 102 "_NET_WM_STATE", |
102 "_NET_WM_STATE_ABOVE", | 103 "_NET_WM_STATE_ABOVE", |
103 "_NET_WM_STATE_FULLSCREEN", | 104 "_NET_WM_STATE_FULLSCREEN", |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 if (!XQueryTree(xdisplay, window, | 149 if (!XQueryTree(xdisplay, window, |
149 &root_win, &parent_win, &child_windows, &num_child_windows)) | 150 &root_win, &parent_win, &child_windows, &num_child_windows)) |
150 break; | 151 break; |
151 if (child_windows) | 152 if (child_windows) |
152 XFree(child_windows); | 153 XFree(child_windows); |
153 window = parent_win; | 154 window = parent_win; |
154 } | 155 } |
155 return result; | 156 return result; |
156 } | 157 } |
157 | 158 |
| 159 int XI2ModeToXMode(int xi2_mode) { |
| 160 switch (xi2_mode) { |
| 161 case XINotifyNormal: |
| 162 return NotifyNormal; |
| 163 case XINotifyGrab: |
| 164 case XINotifyPassiveGrab: |
| 165 return NotifyGrab; |
| 166 case XINotifyUngrab: |
| 167 case XINotifyPassiveUngrab: |
| 168 return NotifyUngrab; |
| 169 case XINotifyWhileGrabbed: |
| 170 return NotifyWhileGrabbed; |
| 171 default: |
| 172 NOTREACHED(); |
| 173 return NotifyNormal; |
| 174 } |
| 175 } |
| 176 |
158 } // namespace | 177 } // namespace |
159 | 178 |
160 //////////////////////////////////////////////////////////////////////////////// | 179 //////////////////////////////////////////////////////////////////////////////// |
161 // DesktopWindowTreeHostX11, public: | 180 // DesktopWindowTreeHostX11, public: |
162 | 181 |
163 DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( | 182 DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( |
164 internal::NativeWidgetDelegate* native_widget_delegate, | 183 internal::NativeWidgetDelegate* native_widget_delegate, |
165 DesktopNativeWidgetAura* desktop_native_widget_aura) | 184 DesktopNativeWidgetAura* desktop_native_widget_aura) |
166 : xdisplay_(gfx::GetXDisplay()), | 185 : xdisplay_(gfx::GetXDisplay()), |
167 xwindow_(0), | 186 xwindow_(0), |
168 x_root_window_(DefaultRootWindow(xdisplay_)), | 187 x_root_window_(DefaultRootWindow(xdisplay_)), |
169 atom_cache_(xdisplay_, kAtomsToCache), | 188 atom_cache_(xdisplay_, kAtomsToCache), |
170 window_mapped_(false), | 189 window_mapped_(false), |
171 wait_for_unmap_(false), | 190 wait_for_unmap_(false), |
172 is_fullscreen_(false), | 191 is_fullscreen_(false), |
173 is_always_on_top_(false), | 192 is_always_on_top_(false), |
174 use_native_frame_(false), | 193 use_native_frame_(false), |
175 should_maximize_after_map_(false), | 194 should_maximize_after_map_(false), |
176 use_argb_visual_(false), | 195 use_argb_visual_(false), |
177 drag_drop_client_(NULL), | 196 drag_drop_client_(NULL), |
178 native_widget_delegate_(native_widget_delegate), | 197 native_widget_delegate_(native_widget_delegate), |
179 desktop_native_widget_aura_(desktop_native_widget_aura), | 198 desktop_native_widget_aura_(desktop_native_widget_aura), |
180 content_window_(NULL), | 199 content_window_(NULL), |
181 window_parent_(NULL), | 200 window_parent_(NULL), |
182 custom_window_shape_(false), | 201 custom_window_shape_(false), |
183 urgency_hint_set_(false), | 202 urgency_hint_set_(false), |
| 203 has_pointer_grab_(false), |
184 activatable_(true), | 204 activatable_(true), |
185 close_widget_factory_(this) { | 205 has_pointer_(false), |
186 } | 206 has_window_focus_(false), |
| 207 has_pointer_focus_(false), |
| 208 close_widget_factory_(this) {} |
187 | 209 |
188 DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() { | 210 DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() { |
189 window()->ClearProperty(kHostForRootWindow); | 211 window()->ClearProperty(kHostForRootWindow); |
190 aura::client::SetWindowMoveClient(window(), NULL); | 212 aura::client::SetWindowMoveClient(window(), NULL); |
191 desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this); | 213 desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this); |
192 DestroyDispatcher(); | 214 DestroyDispatcher(); |
193 } | 215 } |
194 | 216 |
195 // static | 217 // static |
196 aura::Window* DesktopWindowTreeHostX11::GetContentWindowForXID(XID xid) { | 218 aura::Window* DesktopWindowTreeHostX11::GetContentWindowForXID(XID xid) { |
(...skipping 26 matching lines...) Expand all Loading... |
223 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const { | 245 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const { |
224 gfx::Rect outer_bounds(bounds_in_pixels_); | 246 gfx::Rect outer_bounds(bounds_in_pixels_); |
225 outer_bounds.Inset(-native_window_frame_borders_in_pixels_); | 247 outer_bounds.Inset(-native_window_frame_borders_in_pixels_); |
226 return outer_bounds; | 248 return outer_bounds; |
227 } | 249 } |
228 | 250 |
229 ::Region DesktopWindowTreeHostX11::GetWindowShape() const { | 251 ::Region DesktopWindowTreeHostX11::GetWindowShape() const { |
230 return window_shape_.get(); | 252 return window_shape_.get(); |
231 } | 253 } |
232 | 254 |
233 void DesktopWindowTreeHostX11::HandleNativeWidgetActivationChanged( | 255 void DesktopWindowTreeHostX11::BeforeActivationStateChanged() { |
234 bool active) { | 256 was_active_ = IsActive(); |
235 if (active) { | 257 had_pointer_ = has_pointer_; |
| 258 had_pointer_grab_ = has_pointer_grab_; |
| 259 had_window_focus_ = has_window_focus_; |
| 260 } |
| 261 |
| 262 void DesktopWindowTreeHostX11::AfterActivationStateChanged() { |
| 263 if (had_pointer_grab_ && !has_pointer_grab_) |
| 264 dispatcher()->OnHostLostMouseGrab(); |
| 265 |
| 266 bool had_pointer_capture = had_pointer_ || had_pointer_grab_; |
| 267 bool has_pointer_capture = has_pointer_ || has_pointer_grab_; |
| 268 if (had_pointer_capture && !has_pointer_capture) |
| 269 OnHostLostWindowCapture(); |
| 270 |
| 271 if (!was_active_ && IsActive()) { |
236 FlashFrame(false); | 272 FlashFrame(false); |
237 OnHostActivated(); | 273 OnHostActivated(); |
| 274 // TODO(thomasanderson): Remove this window shuffling and use XWindowCache |
| 275 // instead. |
238 open_windows().remove(xwindow_); | 276 open_windows().remove(xwindow_); |
239 open_windows().insert(open_windows().begin(), xwindow_); | 277 open_windows().insert(open_windows().begin(), xwindow_); |
240 } else { | |
241 ReleaseCapture(); | |
242 } | 278 } |
243 | 279 |
244 desktop_native_widget_aura_->HandleActivationChanged(active); | 280 if (was_active_ != IsActive()) { |
| 281 desktop_native_widget_aura_->HandleActivationChanged(IsActive()); |
| 282 native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint(); |
| 283 } |
| 284 } |
245 | 285 |
246 native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint(); | 286 void DesktopWindowTreeHostX11::OnCrossingEvent(bool enter, |
| 287 bool focus_in_window_or_ancestor, |
| 288 int mode, |
| 289 int detail) { |
| 290 // NotifyInferior on a crossing event means the pointer moved into or out of a |
| 291 // child window, but the pointer is still within |xwindow_|. |
| 292 if (detail == NotifyInferior) |
| 293 return; |
| 294 |
| 295 BeforeActivationStateChanged(); |
| 296 |
| 297 if (mode == NotifyGrab) |
| 298 has_pointer_grab_ = enter; |
| 299 else if (mode == NotifyUngrab) |
| 300 has_pointer_grab_ = false; |
| 301 |
| 302 has_pointer_ = enter; |
| 303 if (focus_in_window_or_ancestor && !has_window_focus_) { |
| 304 // If we reach this point, we know the focus is in an ancestor or the |
| 305 // pointer root. The definition of |has_pointer_focus_| is (An ancestor |
| 306 // window or the PointerRoot is focused) && |has_pointer_|. Therefore, we |
| 307 // can just use |has_pointer_| in the assignment. The transitions for when |
| 308 // the focus changes are handled in OnFocusEvent(). |
| 309 has_pointer_focus_ = has_pointer_; |
| 310 } |
| 311 |
| 312 AfterActivationStateChanged(); |
| 313 } |
| 314 |
| 315 void DesktopWindowTreeHostX11::OnFocusEvent(bool focus_in, |
| 316 int mode, |
| 317 int detail) { |
| 318 // NotifyInferior on a focus event means the focus moved into or out of a |
| 319 // child window, but the focus is still within |xwindow_|. |
| 320 if (detail == NotifyInferior) |
| 321 return; |
| 322 |
| 323 bool notify_grab = mode == NotifyGrab || mode == NotifyUngrab; |
| 324 |
| 325 BeforeActivationStateChanged(); |
| 326 |
| 327 // For every focus change, the X server sends normal focus events which are |
| 328 // useful for tracking |has_window_focus_|, but supplements these events with |
| 329 // NotifyPointer events which are only useful for tracking pointer focus. |
| 330 |
| 331 // For |has_pointer_focus_| and |has_window_focus_|, we continue tracking |
| 332 // state during a grab, but ignore grab/ungrab events themselves. |
| 333 if (!notify_grab && detail != NotifyPointer) |
| 334 has_window_focus_ = focus_in; |
| 335 |
| 336 if (!notify_grab && has_pointer_) { |
| 337 switch (detail) { |
| 338 case NotifyAncestor: |
| 339 case NotifyVirtual: |
| 340 // If we reach this point, we know |has_pointer_| was true before and |
| 341 // after this event. Since the definition of |has_pointer_focus_| is |
| 342 // (An ancestor window or the PointerRoot is focused) && |has_pointer_|, |
| 343 // we only need to worry about transitions on the first conjunct. |
| 344 // Therefore, |has_pointer_focus_| will become true when: |
| 345 // 1. Focus moves from |xwindow_| to an ancestor |
| 346 // (FocusOut with NotifyAncestor) |
| 347 // 2. Focus moves from a decendant of |xwindow_| to an ancestor |
| 348 // (FocusOut with NotifyVirtual) |
| 349 // |has_pointer_focus_| will become false when: |
| 350 // 1. Focus moves from an ancestor to |xwindow_| |
| 351 // (FocusIn with NotifyAncestor) |
| 352 // 2. Focus moves from an ancestor to a child of |xwindow_| |
| 353 // (FocusIn with NotifyVirtual) |
| 354 has_pointer_focus_ = !focus_in; |
| 355 break; |
| 356 case NotifyPointer: |
| 357 // The remaining cases for |has_pointer_focus_| becoming true are: |
| 358 // 3. Focus moves from |xwindow_| to the PointerRoot |
| 359 // 4. Focus moves from a decendant of |xwindow_| to the PointerRoot |
| 360 // 5. Focus moves from None to the PointerRoot |
| 361 // 6. Focus moves from Other to the PointerRoot |
| 362 // 7. Focus moves from None to an ancestor of |xwindow_| |
| 363 // 8. Focus moves from Other to an ancestor fo |xwindow_| |
| 364 // In each case, we will get a FocusIn with a detail of NotifyPointer. |
| 365 // The remaining cases for |has_pointer_focus_| becoming false are: |
| 366 // 3. Focus moves from the PointerRoot to |xwindow_| |
| 367 // 4. Focus moves from the PointerRoot to a decendant of |xwindow| |
| 368 // 5. Focus moves from the PointerRoot to None |
| 369 // 6. Focus moves from an ancestor of |xwindow_| to None |
| 370 // 7. Focus moves from the PointerRoot to Other |
| 371 // 8. Focus moves from an ancestor of |xwindow_| to Other |
| 372 // In each case, we will get a FocusOut with a detail of NotifyPointer. |
| 373 has_pointer_focus_ = focus_in; |
| 374 break; |
| 375 case NotifyNonlinear: |
| 376 case NotifyNonlinearVirtual: |
| 377 // We get Nonlinear(Virtual) events when |
| 378 // 1. Focus moves from Other to |xwindow_| |
| 379 // (FocusIn with NotifyNonlinear) |
| 380 // 2. Focus moves from Other to a decendant of |xwindow_| |
| 381 // (FocusIn with NotifyNonlinearVirtual) |
| 382 // 3. Focus moves from |xwindow_| to Other |
| 383 // (FocusOut with NotifyNonlinear) |
| 384 // 4. Focus moves from a decendant of |xwindow_| to Other |
| 385 // (FocusOut with NotifyNonlinearVirtual) |
| 386 // |has_pointer_focus_| should be false before and after this event. |
| 387 has_pointer_focus_ = false; |
| 388 default: |
| 389 break; |
| 390 } |
| 391 } |
| 392 |
| 393 ignore_keyboard_input_ = false; |
| 394 |
| 395 AfterActivationStateChanged(); |
247 } | 396 } |
248 | 397 |
249 void DesktopWindowTreeHostX11::AddObserver( | 398 void DesktopWindowTreeHostX11::AddObserver( |
250 DesktopWindowTreeHostObserverX11* observer) { | 399 DesktopWindowTreeHostObserverX11* observer) { |
251 observer_list_.AddObserver(observer); | 400 observer_list_.AddObserver(observer); |
252 } | 401 } |
253 | 402 |
254 void DesktopWindowTreeHostX11::RemoveObserver( | 403 void DesktopWindowTreeHostX11::RemoveObserver( |
255 DesktopWindowTreeHostObserverX11* observer) { | 404 DesktopWindowTreeHostObserverX11* observer) { |
256 observer_list_.RemoveObserver(observer); | 405 observer_list_.RemoveObserver(observer); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 sanitized_params.bounds.set_height(100); | 450 sanitized_params.bounds.set_height(100); |
302 | 451 |
303 InitX11Window(sanitized_params); | 452 InitX11Window(sanitized_params); |
304 } | 453 } |
305 | 454 |
306 void DesktopWindowTreeHostX11::OnNativeWidgetCreated( | 455 void DesktopWindowTreeHostX11::OnNativeWidgetCreated( |
307 const Widget::InitParams& params) { | 456 const Widget::InitParams& params) { |
308 window()->SetProperty(kViewsWindowForRootWindow, content_window_); | 457 window()->SetProperty(kViewsWindowForRootWindow, content_window_); |
309 window()->SetProperty(kHostForRootWindow, this); | 458 window()->SetProperty(kHostForRootWindow, this); |
310 | 459 |
311 // Ensure that the X11DesktopHandler exists so that it dispatches activation | 460 // Ensure that the X11DesktopHandler exists so that it tracks create/destroy |
312 // messages to us. | 461 // notify events. |
313 X11DesktopHandler::get(); | 462 X11DesktopHandler::get(); |
314 | 463 |
315 // TODO(erg): Unify this code once the other consumer goes away. | 464 // TODO(erg): Unify this code once the other consumer goes away. |
316 SwapNonClientEventHandler( | 465 SwapNonClientEventHandler( |
317 std::unique_ptr<ui::EventHandler>(new X11WindowEventFilter(this))); | 466 std::unique_ptr<ui::EventHandler>(new X11WindowEventFilter(this))); |
318 SetUseNativeFrame(params.type == Widget::InitParams::TYPE_WINDOW && | 467 SetUseNativeFrame(params.type == Widget::InitParams::TYPE_WINDOW && |
319 !params.remove_standard_frame); | 468 !params.remove_standard_frame); |
320 | 469 |
321 x11_window_move_client_.reset(new X11DesktopWindowMoveClient); | 470 x11_window_move_client_.reset(new X11DesktopWindowMoveClient); |
322 aura::client::SetWindowMoveClient(window(), x11_window_move_client_.get()); | 471 aura::client::SetWindowMoveClient(window(), x11_window_move_client_.get()); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 } | 548 } |
400 | 549 |
401 aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() { | 550 aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() { |
402 return this; | 551 return this; |
403 } | 552 } |
404 | 553 |
405 void DesktopWindowTreeHostX11::ShowWindowWithState( | 554 void DesktopWindowTreeHostX11::ShowWindowWithState( |
406 ui::WindowShowState show_state) { | 555 ui::WindowShowState show_state) { |
407 if (compositor()) | 556 if (compositor()) |
408 compositor()->SetVisible(true); | 557 compositor()->SetVisible(true); |
409 if (!window_mapped_) | 558 if (!IsVisible()) |
410 MapWindow(show_state); | 559 MapWindow(show_state); |
411 | 560 |
412 switch (show_state) { | 561 switch (show_state) { |
413 case ui::SHOW_STATE_MAXIMIZED: | 562 case ui::SHOW_STATE_MAXIMIZED: |
414 Maximize(); | 563 Maximize(); |
415 break; | 564 break; |
416 case ui::SHOW_STATE_MINIMIZED: | 565 case ui::SHOW_STATE_MINIMIZED: |
417 Minimize(); | 566 Minimize(); |
418 break; | 567 break; |
419 case ui::SHOW_STATE_FULLSCREEN: | 568 case ui::SHOW_STATE_FULLSCREEN: |
420 SetFullscreen(true); | 569 SetFullscreen(true); |
421 break; | 570 break; |
422 default: | 571 default: |
423 break; | 572 break; |
424 } | 573 } |
425 | 574 |
426 // Makes the window activated by default if the state is not INACTIVE or | 575 // Makes the window activated by default if the state is not INACTIVE or |
427 // MINIMIZED. | 576 // MINIMIZED. |
428 if (show_state != ui::SHOW_STATE_INACTIVE && | 577 if (show_state != ui::SHOW_STATE_INACTIVE && |
429 show_state != ui::SHOW_STATE_MINIMIZED && | 578 show_state != ui::SHOW_STATE_MINIMIZED) { |
430 activatable_) { | |
431 Activate(); | 579 Activate(); |
432 } | 580 } |
433 | 581 |
434 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state); | 582 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state); |
435 } | 583 } |
436 | 584 |
437 void DesktopWindowTreeHostX11::ShowMaximizedWithBounds( | 585 void DesktopWindowTreeHostX11::ShowMaximizedWithBounds( |
438 const gfx::Rect& restored_bounds) { | 586 const gfx::Rect& restored_bounds) { |
439 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); | 587 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); |
440 // Enforce |restored_bounds_in_pixels_| since calling Maximize() could have | 588 // Enforce |restored_bounds_in_pixels_| since calling Maximize() could have |
441 // reset it. | 589 // reset it. |
442 restored_bounds_in_pixels_ = ToPixelRect(restored_bounds); | 590 restored_bounds_in_pixels_ = ToPixelRect(restored_bounds); |
443 } | 591 } |
444 | 592 |
445 bool DesktopWindowTreeHostX11::IsVisible() const { | 593 bool DesktopWindowTreeHostX11::IsVisible() const { |
446 return window_mapped_; | 594 return window_mapped_ && !wait_for_unmap_; |
447 } | 595 } |
448 | 596 |
449 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { | 597 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { |
450 gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(requested_size)).size(); | 598 gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(requested_size)).size(); |
451 size_in_pixels = AdjustSize(size_in_pixels); | 599 size_in_pixels = AdjustSize(size_in_pixels); |
452 bool size_changed = bounds_in_pixels_.size() != size_in_pixels; | 600 bool size_changed = bounds_in_pixels_.size() != size_in_pixels; |
453 XResizeWindow(xdisplay_, xwindow_, size_in_pixels.width(), | 601 XResizeWindow(xdisplay_, xwindow_, size_in_pixels.width(), |
454 size_in_pixels.height()); | 602 size_in_pixels.height()); |
455 bounds_in_pixels_.set_size(size_in_pixels); | 603 bounds_in_pixels_.set_size(size_in_pixels); |
456 if (size_changed) { | 604 if (size_changed) { |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 } else { | 755 } else { |
608 window_shape_.reset(gfx::CreateRegionFromSkRegion(*native_region)); | 756 window_shape_.reset(gfx::CreateRegionFromSkRegion(*native_region)); |
609 } | 757 } |
610 | 758 |
611 custom_window_shape_ = true; | 759 custom_window_shape_ = true; |
612 } | 760 } |
613 ResetWindowRegion(); | 761 ResetWindowRegion(); |
614 } | 762 } |
615 | 763 |
616 void DesktopWindowTreeHostX11::Activate() { | 764 void DesktopWindowTreeHostX11::Activate() { |
617 if (!window_mapped_) | 765 if (!IsVisible() || !activatable_) |
618 return; | 766 return; |
619 | 767 |
620 X11DesktopHandler::get()->ActivateWindow(xwindow_); | 768 BeforeActivationStateChanged(); |
| 769 |
| 770 ignore_keyboard_input_ = false; |
| 771 |
| 772 // wmii says that it supports _NET_ACTIVE_WINDOW but does not. |
| 773 // https://code.google.com/p/wmii/issues/detail?id=266 |
| 774 static bool wm_supports_active_window = |
| 775 ui::GuessWindowManager() != ui::WM_WMII && |
| 776 ui::WmSupportsHint(atom_cache_.GetAtom("_NET_ACTIVE_WINDOW")); |
| 777 |
| 778 Time timestamp = ui::X11EventSource::GetInstance()->GetTimestamp(); |
| 779 |
| 780 if (wm_supports_active_window) { |
| 781 XEvent xclient; |
| 782 memset(&xclient, 0, sizeof(xclient)); |
| 783 xclient.type = ClientMessage; |
| 784 xclient.xclient.window = xwindow_; |
| 785 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW"); |
| 786 xclient.xclient.format = 32; |
| 787 xclient.xclient.data.l[0] = 1; // Specified we are an app. |
| 788 xclient.xclient.data.l[1] = timestamp; |
| 789 // TODO(thomasanderson): if another chrome window is active, specify that in |
| 790 // data.l[2]. The EWMH spec claims this may make the WM more likely to |
| 791 // service our _NET_ACTIVE_WINDOW request. |
| 792 xclient.xclient.data.l[2] = None; |
| 793 xclient.xclient.data.l[3] = 0; |
| 794 xclient.xclient.data.l[4] = 0; |
| 795 |
| 796 XSendEvent(xdisplay_, x_root_window_, False, |
| 797 SubstructureRedirectMask | SubstructureNotifyMask, &xclient); |
| 798 } else { |
| 799 XRaiseWindow(xdisplay_, xwindow_); |
| 800 // Directly ask the X server to give focus to the window. Note that the call |
| 801 // will raise an X error if the window is not mapped. |
| 802 XSetInputFocus(xdisplay_, xwindow_, RevertToParent, timestamp); |
| 803 // At this point, we know we will receive focus, and some tests depend on a |
| 804 // window being IsActive() immediately after an Activate(), so just set this |
| 805 // state now. |
| 806 has_pointer_focus_ = false; |
| 807 has_window_focus_ = true; |
| 808 } |
| 809 AfterActivationStateChanged(); |
621 } | 810 } |
622 | 811 |
623 void DesktopWindowTreeHostX11::Deactivate() { | 812 void DesktopWindowTreeHostX11::Deactivate() { |
624 if (!IsActive()) | 813 BeforeActivationStateChanged(); |
625 return; | 814 |
| 815 // Ignore future input events. |
| 816 ignore_keyboard_input_ = true; |
626 | 817 |
627 ReleaseCapture(); | 818 ReleaseCapture(); |
628 X11DesktopHandler::get()->DeactivateWindow(xwindow_); | 819 XLowerWindow(xdisplay_, xwindow_); |
| 820 |
| 821 AfterActivationStateChanged(); |
629 } | 822 } |
630 | 823 |
631 bool DesktopWindowTreeHostX11::IsActive() const { | 824 bool DesktopWindowTreeHostX11::IsActive() const { |
632 return X11DesktopHandler::get()->IsActiveWindow(xwindow_); | 825 // Focus and stacking order are independent in X11. Since we cannot guarantee |
| 826 // a window is topmost iff it has focus, just use the focus state to determine |
| 827 // if a window is active. Note that Activate() and Deactivate() change the |
| 828 // stacking order in addition to changing the focus state. |
| 829 bool is_active = |
| 830 (has_window_focus_ || has_pointer_focus_) && !ignore_keyboard_input_; |
| 831 |
| 832 // is_active => window_mapped_ |
| 833 // !window_mapped_ => !is_active |
| 834 DCHECK(!is_active || window_mapped_); |
| 835 |
| 836 // |has_window_focus_| and |has_pointer_focus_| are mutually exclusive. |
| 837 DCHECK(!has_window_focus_ || !has_pointer_focus_); |
| 838 |
| 839 return is_active; |
633 } | 840 } |
634 | 841 |
635 void DesktopWindowTreeHostX11::Maximize() { | 842 void DesktopWindowTreeHostX11::Maximize() { |
636 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { | 843 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { |
637 // Unfullscreen the window if it is fullscreen. | 844 // Unfullscreen the window if it is fullscreen. |
638 SetWMSpecState(false, | 845 SetWMSpecState(false, |
639 atom_cache_.GetAtom("_NET_WM_STATE_FULLSCREEN"), | 846 atom_cache_.GetAtom("_NET_WM_STATE_FULLSCREEN"), |
640 None); | 847 None); |
641 | 848 |
642 // Resize the window so that it does not have the same size as a monitor. | 849 // Resize the window so that it does not have the same size as a monitor. |
643 // (Otherwise, some window managers immediately put the window back in | 850 // (Otherwise, some window managers immediately put the window back in |
644 // fullscreen mode). | 851 // fullscreen mode). |
645 gfx::Rect adjusted_bounds_in_pixels(bounds_in_pixels_.origin(), | 852 gfx::Rect adjusted_bounds_in_pixels(bounds_in_pixels_.origin(), |
646 AdjustSize(bounds_in_pixels_.size())); | 853 AdjustSize(bounds_in_pixels_.size())); |
647 if (adjusted_bounds_in_pixels != bounds_in_pixels_) | 854 if (adjusted_bounds_in_pixels != bounds_in_pixels_) |
648 SetBounds(adjusted_bounds_in_pixels); | 855 SetBounds(adjusted_bounds_in_pixels); |
649 } | 856 } |
650 | 857 |
651 // Some WMs do not respect maximization hints on unmapped windows, so we | 858 // Some WMs do not respect maximization hints on unmapped windows, so we |
652 // save this one for later too. | 859 // save this one for later too. |
653 should_maximize_after_map_ = !window_mapped_; | 860 should_maximize_after_map_ = !IsVisible(); |
654 | 861 |
655 // When we are in the process of requesting to maximize a window, we can | 862 // When we are in the process of requesting to maximize a window, we can |
656 // accurately keep track of our restored bounds instead of relying on the | 863 // accurately keep track of our restored bounds instead of relying on the |
657 // heuristics that are in the PropertyNotify and ConfigureNotify handlers. | 864 // heuristics that are in the PropertyNotify and ConfigureNotify handlers. |
658 restored_bounds_in_pixels_ = bounds_in_pixels_; | 865 restored_bounds_in_pixels_ = bounds_in_pixels_; |
659 | 866 |
660 SetWMSpecState(true, | 867 SetWMSpecState(true, |
661 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), | 868 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), |
662 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); | 869 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); |
663 if (IsMinimized()) | 870 if (IsMinimized()) |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
964 | 1171 |
965 void DesktopWindowTreeHostX11::SizeConstraintsChanged() { | 1172 void DesktopWindowTreeHostX11::SizeConstraintsChanged() { |
966 UpdateMinAndMaxSize(); | 1173 UpdateMinAndMaxSize(); |
967 } | 1174 } |
968 | 1175 |
969 //////////////////////////////////////////////////////////////////////////////// | 1176 //////////////////////////////////////////////////////////////////////////////// |
970 // DesktopWindowTreeHostX11, aura::WindowTreeHost implementation: | 1177 // DesktopWindowTreeHostX11, aura::WindowTreeHost implementation: |
971 | 1178 |
972 gfx::Transform DesktopWindowTreeHostX11::GetRootTransform() const { | 1179 gfx::Transform DesktopWindowTreeHostX11::GetRootTransform() const { |
973 display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay(); | 1180 display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay(); |
974 if (window_mapped_) { | 1181 if (IsVisible()) { |
975 aura::Window* win = const_cast<aura::Window*>(window()); | 1182 aura::Window* win = const_cast<aura::Window*>(window()); |
976 display = display::Screen::GetScreen()->GetDisplayNearestWindow(win); | 1183 display = display::Screen::GetScreen()->GetDisplayNearestWindow(win); |
977 } | 1184 } |
978 | 1185 |
979 float scale = display.device_scale_factor(); | 1186 float scale = display.device_scale_factor(); |
980 gfx::Transform transform; | 1187 gfx::Transform transform; |
981 transform.Scale(scale, scale); | 1188 transform.Scale(scale, scale); |
982 return transform; | 1189 return transform; |
983 } | 1190 } |
984 | 1191 |
985 ui::EventSource* DesktopWindowTreeHostX11::GetEventSource() { | 1192 ui::EventSource* DesktopWindowTreeHostX11::GetEventSource() { |
986 return this; | 1193 return this; |
987 } | 1194 } |
988 | 1195 |
989 gfx::AcceleratedWidget DesktopWindowTreeHostX11::GetAcceleratedWidget() { | 1196 gfx::AcceleratedWidget DesktopWindowTreeHostX11::GetAcceleratedWidget() { |
990 return xwindow_; | 1197 return xwindow_; |
991 } | 1198 } |
992 | 1199 |
993 void DesktopWindowTreeHostX11::ShowImpl() { | 1200 void DesktopWindowTreeHostX11::ShowImpl() { |
994 ShowWindowWithState(ui::SHOW_STATE_NORMAL); | 1201 ShowWindowWithState(ui::SHOW_STATE_NORMAL); |
995 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); | 1202 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); |
996 } | 1203 } |
997 | 1204 |
998 void DesktopWindowTreeHostX11::HideImpl() { | 1205 void DesktopWindowTreeHostX11::HideImpl() { |
999 if (window_mapped_) { | 1206 if (IsVisible()) { |
1000 XWithdrawWindow(xdisplay_, xwindow_, 0); | 1207 XWithdrawWindow(xdisplay_, xwindow_, 0); |
1001 window_mapped_ = false; | |
1002 wait_for_unmap_ = true; | 1208 wait_for_unmap_ = true; |
1003 } | 1209 } |
1004 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); | 1210 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); |
1005 } | 1211 } |
1006 | 1212 |
1007 gfx::Rect DesktopWindowTreeHostX11::GetBounds() const { | 1213 gfx::Rect DesktopWindowTreeHostX11::GetBounds() const { |
1008 return bounds_in_pixels_; | 1214 return bounds_in_pixels_; |
1009 } | 1215 } |
1010 | 1216 |
1011 void DesktopWindowTreeHostX11::SetBounds( | 1217 void DesktopWindowTreeHostX11::SetBounds( |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 // OR | 1285 // OR |
1080 // - The topmost window underneath the mouse is managed by Chrome. | 1286 // - The topmost window underneath the mouse is managed by Chrome. |
1081 DesktopWindowTreeHostX11* old_capturer = g_current_capture; | 1287 DesktopWindowTreeHostX11* old_capturer = g_current_capture; |
1082 | 1288 |
1083 // Update |g_current_capture| prior to calling OnHostLostWindowCapture() to | 1289 // Update |g_current_capture| prior to calling OnHostLostWindowCapture() to |
1084 // avoid releasing pointer grab. | 1290 // avoid releasing pointer grab. |
1085 g_current_capture = this; | 1291 g_current_capture = this; |
1086 if (old_capturer) | 1292 if (old_capturer) |
1087 old_capturer->OnHostLostWindowCapture(); | 1293 old_capturer->OnHostLostWindowCapture(); |
1088 | 1294 |
1089 GrabPointer(xwindow_, true, None); | 1295 // If the pointer is already in |xwindow_|, we will not get a crossing event |
| 1296 // with a mode of NotifyGrab, so we must record the grab state manually. |
| 1297 has_pointer_grab_ |= !GrabPointer(xwindow_, true, None); |
1090 } | 1298 } |
1091 | 1299 |
1092 void DesktopWindowTreeHostX11::ReleaseCapture() { | 1300 void DesktopWindowTreeHostX11::ReleaseCapture() { |
1093 if (g_current_capture == this) { | 1301 if (g_current_capture == this) { |
1094 // Release mouse grab asynchronously. A window managed by Chrome is likely | 1302 // Release mouse grab asynchronously. A window managed by Chrome is likely |
1095 // the topmost window underneath the mouse so the capture release being | 1303 // the topmost window underneath the mouse so the capture release being |
1096 // asynchronous is likely inconsequential. | 1304 // asynchronous is likely inconsequential. |
1097 g_current_capture = NULL; | 1305 g_current_capture = NULL; |
1098 UngrabPointer(); | 1306 UngrabPointer(); |
| 1307 has_pointer_grab_ = false; |
1099 | 1308 |
1100 OnHostLostWindowCapture(); | 1309 OnHostLostWindowCapture(); |
1101 } | 1310 } |
1102 } | 1311 } |
1103 | 1312 |
1104 void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) { | 1313 void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) { |
1105 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); | 1314 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); |
1106 } | 1315 } |
1107 | 1316 |
1108 void DesktopWindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) { | 1317 void DesktopWindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) { |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1417 insets.size() == 4) { | 1626 insets.size() == 4) { |
1418 // |insets| are returned in the order: [left, right, top, bottom]. | 1627 // |insets| are returned in the order: [left, right, top, bottom]. |
1419 native_window_frame_borders_in_pixels_ = | 1628 native_window_frame_borders_in_pixels_ = |
1420 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); | 1629 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); |
1421 } else { | 1630 } else { |
1422 native_window_frame_borders_in_pixels_ = gfx::Insets(); | 1631 native_window_frame_borders_in_pixels_ = gfx::Insets(); |
1423 } | 1632 } |
1424 } | 1633 } |
1425 | 1634 |
1426 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { | 1635 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { |
1427 if (!window_mapped_) | 1636 if (!IsVisible()) |
1428 return; | 1637 return; |
1429 | 1638 |
1430 gfx::Size minimum_in_pixels = | 1639 gfx::Size minimum_in_pixels = |
1431 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); | 1640 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); |
1432 gfx::Size maximum_in_pixels = | 1641 gfx::Size maximum_in_pixels = |
1433 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); | 1642 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); |
1434 if (min_size_in_pixels_ == minimum_in_pixels && | 1643 if (min_size_in_pixels_ == minimum_in_pixels && |
1435 max_size_in_pixels_ == maximum_in_pixels) | 1644 max_size_in_pixels_ == maximum_in_pixels) |
1436 return; | 1645 return; |
1437 | 1646 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1473 unsigned long wm_user_time_ms = static_cast<unsigned long>( | 1682 unsigned long wm_user_time_ms = static_cast<unsigned long>( |
1474 (ui::EventTimeFromNative(event) - base::TimeTicks()).InMilliseconds()); | 1683 (ui::EventTimeFromNative(event) - base::TimeTicks()).InMilliseconds()); |
1475 XChangeProperty(xdisplay_, | 1684 XChangeProperty(xdisplay_, |
1476 xwindow_, | 1685 xwindow_, |
1477 atom_cache_.GetAtom("_NET_WM_USER_TIME"), | 1686 atom_cache_.GetAtom("_NET_WM_USER_TIME"), |
1478 XA_CARDINAL, | 1687 XA_CARDINAL, |
1479 32, | 1688 32, |
1480 PropModeReplace, | 1689 PropModeReplace, |
1481 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), | 1690 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), |
1482 1); | 1691 1); |
1483 X11DesktopHandler::get()->set_wm_user_time_ms(wm_user_time_ms); | |
1484 } | 1692 } |
1485 } | 1693 } |
1486 | 1694 |
1487 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled, | 1695 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled, |
1488 ::Atom state1, | 1696 ::Atom state1, |
1489 ::Atom state2) { | 1697 ::Atom state2) { |
1490 XEvent xclient; | 1698 XEvent xclient; |
1491 memset(&xclient, 0, sizeof(xclient)); | 1699 memset(&xclient, 0, sizeof(xclient)); |
1492 xclient.type = ClientMessage; | 1700 xclient.type = ClientMessage; |
1493 xclient.xclient.window = xwindow_; | 1701 xclient.xclient.window = xwindow_; |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1674 // will ignore toplevel XMoveWindow commands. | 1882 // will ignore toplevel XMoveWindow commands. |
1675 XSizeHints size_hints; | 1883 XSizeHints size_hints; |
1676 size_hints.flags = PPosition; | 1884 size_hints.flags = PPosition; |
1677 size_hints.x = bounds_in_pixels_.x(); | 1885 size_hints.x = bounds_in_pixels_.x(); |
1678 size_hints.y = bounds_in_pixels_.y(); | 1886 size_hints.y = bounds_in_pixels_.y(); |
1679 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); | 1887 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); |
1680 | 1888 |
1681 // If SHOW_STATE_INACTIVE, tell the window manager not to focus the window | 1889 // If SHOW_STATE_INACTIVE, tell the window manager not to focus the window |
1682 // when mapping. This is done by setting the _NET_WM_USER_TIME to 0. See e.g. | 1890 // when mapping. This is done by setting the _NET_WM_USER_TIME to 0. See e.g. |
1683 // http://standards.freedesktop.org/wm-spec/latest/ar01s05.html | 1891 // http://standards.freedesktop.org/wm-spec/latest/ar01s05.html |
1684 unsigned long wm_user_time_ms = (show_state == ui::SHOW_STATE_INACTIVE) ? | 1892 ignore_keyboard_input_ = show_state == ui::SHOW_STATE_INACTIVE; |
1685 0 : X11DesktopHandler::get()->wm_user_time_ms(); | 1893 unsigned long wm_user_time_ms = |
| 1894 ignore_keyboard_input_ |
| 1895 ? 0 |
| 1896 : ui::X11EventSource::GetInstance()->GetTimestamp(); |
1686 if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) { | 1897 if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) { |
1687 XChangeProperty(xdisplay_, | 1898 XChangeProperty( |
1688 xwindow_, | 1899 xdisplay_, xwindow_, atom_cache_.GetAtom("_NET_WM_USER_TIME"), |
1689 atom_cache_.GetAtom("_NET_WM_USER_TIME"), | 1900 XA_CARDINAL, 32, PropModeReplace, |
1690 XA_CARDINAL, | 1901 reinterpret_cast<const unsigned char*>(&wm_user_time_ms), 1); |
1691 32, | |
1692 PropModeReplace, | |
1693 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), | |
1694 1); | |
1695 } | 1902 } |
1696 | 1903 |
1697 ui::X11EventSource* event_source = ui::X11EventSource::GetInstance(); | 1904 ui::X11EventSource* event_source = ui::X11EventSource::GetInstance(); |
1698 DCHECK(event_source); | 1905 DCHECK(event_source); |
1699 | 1906 |
1700 if (wait_for_unmap_) { | 1907 if (wait_for_unmap_) { |
1701 // Block until our window is unmapped. This avoids a race condition when | 1908 // Block until our window is unmapped. This avoids a race condition when |
1702 // remapping an unmapped window. | 1909 // remapping an unmapped window. |
1703 event_source->BlockUntilWindowUnmapped(xwindow_); | 1910 event_source->BlockUntilWindowUnmapped(xwindow_); |
1704 DCHECK(!wait_for_unmap_); | 1911 DCHECK(!wait_for_unmap_); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 TRACE_EVENT1("views", "DesktopWindowTreeHostX11::Dispatch", | 1953 TRACE_EVENT1("views", "DesktopWindowTreeHostX11::Dispatch", |
1747 "event->type", event->type); | 1954 "event->type", event->type); |
1748 | 1955 |
1749 UpdateWMUserTime(event); | 1956 UpdateWMUserTime(event); |
1750 | 1957 |
1751 // May want to factor CheckXEventForConsistency(xev); into a common location | 1958 // May want to factor CheckXEventForConsistency(xev); into a common location |
1752 // since it is called here. | 1959 // since it is called here. |
1753 switch (xev->type) { | 1960 switch (xev->type) { |
1754 case EnterNotify: | 1961 case EnterNotify: |
1755 case LeaveNotify: { | 1962 case LeaveNotify: { |
| 1963 OnCrossingEvent(xev->type == EnterNotify, xev->xcrossing.focus, |
| 1964 xev->xcrossing.mode, xev->xcrossing.detail); |
| 1965 |
1756 // Ignore EventNotify and LeaveNotify events from children of |xwindow_|. | 1966 // Ignore EventNotify and LeaveNotify events from children of |xwindow_|. |
1757 // NativeViewGLSurfaceGLX adds a child to |xwindow_|. | 1967 // NativeViewGLSurfaceGLX adds a child to |xwindow_|. |
1758 // TODO(pkotwicz|tdanderson): Figure out whether the suppression is | 1968 if (xev->xcrossing.detail != NotifyInferior) { |
1759 // necessary. crbug.com/385716 | 1969 ui::MouseEvent mouse_event(xev); |
1760 if (xev->xcrossing.detail == NotifyInferior) | 1970 DispatchMouseEvent(&mouse_event); |
1761 break; | 1971 } |
1762 | |
1763 ui::MouseEvent mouse_event(xev); | |
1764 DispatchMouseEvent(&mouse_event); | |
1765 break; | 1972 break; |
1766 } | 1973 } |
1767 case Expose: { | 1974 case Expose: { |
1768 gfx::Rect damage_rect_in_pixels(xev->xexpose.x, xev->xexpose.y, | 1975 gfx::Rect damage_rect_in_pixels(xev->xexpose.x, xev->xexpose.y, |
1769 xev->xexpose.width, xev->xexpose.height); | 1976 xev->xexpose.width, xev->xexpose.height); |
1770 compositor()->ScheduleRedrawRect(damage_rect_in_pixels); | 1977 compositor()->ScheduleRedrawRect(damage_rect_in_pixels); |
1771 break; | 1978 break; |
1772 } | 1979 } |
1773 case KeyPress: { | 1980 case KeyPress: { |
1774 ui::KeyEvent keydown_event(xev); | 1981 ui::KeyEvent keydown_event(xev); |
1775 DispatchKeyEvent(&keydown_event); | 1982 DispatchKeyEvent(&keydown_event); |
1776 break; | 1983 break; |
1777 } | 1984 } |
1778 case KeyRelease: { | 1985 case KeyRelease: { |
1779 // There is no way to deactivate a window in X11 so ignore input if | 1986 // There is no way to deactivate a window in X11 so ignore input if |
1780 // window is supposed to be 'inactive'. See comments in | 1987 // window is supposed to be 'inactive'. |
1781 // X11DesktopHandler::DeactivateWindow() for more details. | |
1782 if (!IsActive() && !HasCapture()) | 1988 if (!IsActive() && !HasCapture()) |
1783 break; | 1989 break; |
1784 | 1990 |
1785 ui::KeyEvent key_event(xev); | 1991 ui::KeyEvent key_event(xev); |
1786 DispatchKeyEvent(&key_event); | 1992 DispatchKeyEvent(&key_event); |
1787 break; | 1993 break; |
1788 } | 1994 } |
1789 case ButtonPress: | 1995 case ButtonPress: |
1790 case ButtonRelease: { | 1996 case ButtonRelease: { |
1791 ui::EventType event_type = ui::EventTypeFromNative(xev); | 1997 ui::EventType event_type = ui::EventTypeFromNative(xev); |
(...skipping 10 matching lines...) Expand all Loading... |
1802 break; | 2008 break; |
1803 } | 2009 } |
1804 case ui::ET_UNKNOWN: | 2010 case ui::ET_UNKNOWN: |
1805 // No event is created for X11-release events for mouse-wheel buttons. | 2011 // No event is created for X11-release events for mouse-wheel buttons. |
1806 break; | 2012 break; |
1807 default: | 2013 default: |
1808 NOTREACHED() << event_type; | 2014 NOTREACHED() << event_type; |
1809 } | 2015 } |
1810 break; | 2016 break; |
1811 } | 2017 } |
| 2018 case FocusIn: |
1812 case FocusOut: | 2019 case FocusOut: |
1813 if (xev->xfocus.mode != NotifyGrab) { | 2020 OnFocusEvent(xev->type == FocusIn, event->xfocus.mode, |
1814 ReleaseCapture(); | 2021 event->xfocus.detail); |
1815 OnHostLostWindowCapture(); | |
1816 X11DesktopHandler::get()->ProcessXEvent(xev); | |
1817 } else { | |
1818 dispatcher()->OnHostLostMouseGrab(); | |
1819 } | |
1820 break; | |
1821 case FocusIn: | |
1822 X11DesktopHandler::get()->ProcessXEvent(xev); | |
1823 break; | 2022 break; |
1824 case ConfigureNotify: { | 2023 case ConfigureNotify: { |
1825 DCHECK_EQ(xwindow_, xev->xconfigure.window); | 2024 DCHECK_EQ(xwindow_, xev->xconfigure.window); |
1826 DCHECK_EQ(xwindow_, xev->xconfigure.event); | 2025 DCHECK_EQ(xwindow_, xev->xconfigure.event); |
1827 // It's possible that the X window may be resized by some other means than | 2026 // It's possible that the X window may be resized by some other means than |
1828 // from within aura (e.g. the X window manager can change the size). Make | 2027 // from within aura (e.g. the X window manager can change the size). Make |
1829 // sure the root window size is maintained properly. | 2028 // sure the root window size is maintained properly. |
1830 int translated_x_in_pixels = xev->xconfigure.x; | 2029 int translated_x_in_pixels = xev->xconfigure.x; |
1831 int translated_y_in_pixels = xev->xconfigure.y; | 2030 int translated_y_in_pixels = xev->xconfigure.y; |
1832 if (!xev->xconfigure.send_event && !xev->xconfigure.override_redirect) { | 2031 if (!xev->xconfigure.send_event && !xev->xconfigure.override_redirect) { |
(...skipping 20 matching lines...) Expand all Loading... |
1853 base::ThreadTaskRunnerHandle::Get()->PostTask( | 2052 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1854 FROM_HERE, delayed_resize_task_.callback()); | 2053 FROM_HERE, delayed_resize_task_.callback()); |
1855 } | 2054 } |
1856 break; | 2055 break; |
1857 } | 2056 } |
1858 case GenericEvent: { | 2057 case GenericEvent: { |
1859 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | 2058 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); |
1860 if (!factory->ShouldProcessXI2Event(xev)) | 2059 if (!factory->ShouldProcessXI2Event(xev)) |
1861 break; | 2060 break; |
1862 | 2061 |
| 2062 XIEnterEvent* enter_event = static_cast<XIEnterEvent*>(xev->xcookie.data); |
| 2063 switch (static_cast<XIEvent*>(xev->xcookie.data)->evtype) { |
| 2064 case XI_Enter: |
| 2065 case XI_Leave: |
| 2066 OnCrossingEvent(enter_event->evtype == XI_Enter, enter_event->focus, |
| 2067 XI2ModeToXMode(enter_event->mode), |
| 2068 enter_event->detail); |
| 2069 break; |
| 2070 case XI_FocusIn: |
| 2071 case XI_FocusOut: |
| 2072 OnFocusEvent(enter_event->evtype == XI_FocusIn, |
| 2073 XI2ModeToXMode(enter_event->mode), enter_event->detail); |
| 2074 break; |
| 2075 default: |
| 2076 break; |
| 2077 } |
| 2078 |
1863 ui::EventType type = ui::EventTypeFromNative(xev); | 2079 ui::EventType type = ui::EventTypeFromNative(xev); |
1864 XEvent last_event; | 2080 XEvent last_event; |
1865 int num_coalesced = 0; | 2081 int num_coalesced = 0; |
1866 | 2082 |
1867 switch (type) { | 2083 switch (type) { |
1868 case ui::ET_TOUCH_MOVED: | 2084 case ui::ET_TOUCH_MOVED: |
1869 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); | 2085 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); |
1870 if (num_coalesced > 0) | 2086 if (num_coalesced > 0) |
1871 xev = &last_event; | 2087 xev = &last_event; |
1872 // fallthrough | 2088 // fallthrough |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1934 // Some WMs only respect maximize hints after the window has been mapped. | 2150 // Some WMs only respect maximize hints after the window has been mapped. |
1935 // Check whether we need to re-do a maximization. | 2151 // Check whether we need to re-do a maximization. |
1936 if (should_maximize_after_map_) { | 2152 if (should_maximize_after_map_) { |
1937 Maximize(); | 2153 Maximize(); |
1938 should_maximize_after_map_ = false; | 2154 should_maximize_after_map_ = false; |
1939 } | 2155 } |
1940 | 2156 |
1941 break; | 2157 break; |
1942 } | 2158 } |
1943 case UnmapNotify: { | 2159 case UnmapNotify: { |
| 2160 window_mapped_ = false; |
1944 wait_for_unmap_ = false; | 2161 wait_for_unmap_ = false; |
| 2162 has_pointer_ = false; |
| 2163 has_pointer_grab_ = false; |
| 2164 has_pointer_focus_ = false; |
| 2165 has_window_focus_ = false; |
1945 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11, | 2166 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11, |
1946 observer_list_, | 2167 observer_list_, |
1947 OnWindowUnmapped(xwindow_)); | 2168 OnWindowUnmapped(xwindow_)); |
1948 break; | 2169 break; |
1949 } | 2170 } |
1950 case ClientMessage: { | 2171 case ClientMessage: { |
1951 Atom message_type = xev->xclient.message_type; | 2172 Atom message_type = xev->xclient.message_type; |
1952 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { | 2173 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { |
1953 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); | 2174 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); |
1954 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { | 2175 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2094 if (linux_ui) { | 2315 if (linux_ui) { |
2095 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); | 2316 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); |
2096 if (native_theme) | 2317 if (native_theme) |
2097 return native_theme; | 2318 return native_theme; |
2098 } | 2319 } |
2099 | 2320 |
2100 return ui::NativeThemeAura::instance(); | 2321 return ui::NativeThemeAura::instance(); |
2101 } | 2322 } |
2102 | 2323 |
2103 } // namespace views | 2324 } // namespace views |
OLD | NEW |