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

Side by Side Diff: ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc

Issue 2165083002: Linux: Refactor X11DesktopHandler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add GetTimestamp() in libgtk2ui files Created 4 years, 4 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
OLDNEW
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
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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 should_maximize_after_map_(false), 176 should_maximize_after_map_(false),
176 use_argb_visual_(false), 177 use_argb_visual_(false),
177 drag_drop_client_(NULL), 178 drag_drop_client_(NULL),
178 native_widget_delegate_(native_widget_delegate), 179 native_widget_delegate_(native_widget_delegate),
179 desktop_native_widget_aura_(desktop_native_widget_aura), 180 desktop_native_widget_aura_(desktop_native_widget_aura),
180 content_window_(NULL), 181 content_window_(NULL),
181 window_parent_(NULL), 182 window_parent_(NULL),
182 custom_window_shape_(false), 183 custom_window_shape_(false),
183 urgency_hint_set_(false), 184 urgency_hint_set_(false),
184 activatable_(true), 185 activatable_(true),
186 has_pointer_(false),
187 has_pointer_grab_(false),
188 has_pointer_focus_(false),
189 has_window_focus_(false),
190 has_focus_(false),
185 close_widget_factory_(this) { 191 close_widget_factory_(this) {
186 } 192 }
187 193
188 DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() { 194 DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() {
189 window()->ClearProperty(kHostForRootWindow); 195 window()->ClearProperty(kHostForRootWindow);
190 aura::client::SetWindowMoveClient(window(), NULL); 196 aura::client::SetWindowMoveClient(window(), NULL);
191 desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this); 197 desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this);
192 DestroyDispatcher(); 198 DestroyDispatcher();
193 } 199 }
194 200
(...skipping 28 matching lines...) Expand all
223 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const { 229 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const {
224 gfx::Rect outer_bounds(bounds_in_pixels_); 230 gfx::Rect outer_bounds(bounds_in_pixels_);
225 outer_bounds.Inset(-native_window_frame_borders_in_pixels_); 231 outer_bounds.Inset(-native_window_frame_borders_in_pixels_);
226 return outer_bounds; 232 return outer_bounds;
227 } 233 }
228 234
229 ::Region DesktopWindowTreeHostX11::GetWindowShape() const { 235 ::Region DesktopWindowTreeHostX11::GetWindowShape() const {
230 return window_shape_.get(); 236 return window_shape_.get();
231 } 237 }
232 238
233 void DesktopWindowTreeHostX11::HandleNativeWidgetActivationChanged( 239 void DesktopWindowTreeHostX11::BeforeActivationStateChanged() {
234 bool active) { 240 was_active_ = IsActive();
235 if (active) { 241 had_pointer_grab_ = has_pointer_grab_;
242 had_window_focus_ = has_window_focus_;
243 }
244
245 void DesktopWindowTreeHostX11::AfterActivationStateChanged() {
246 if (had_pointer_grab_ && !has_pointer_grab_)
247 dispatcher()->OnHostLostMouseGrab();
248 if (had_window_focus_ && !has_window_focus_)
249 OnHostLostWindowCapture();
danakj 2016/08/19 21:43:45 Why do we not do this if we had pointer focus but
Tom (Use chromium acct) 2016/08/22 20:27:07 You're right, I was unclear about the definition o
danakj 2016/08/26 19:58:43 Agree, thanks for figuring out what it means
250
251 if (!was_active_ && IsActive()) {
236 FlashFrame(false); 252 FlashFrame(false);
237 OnHostActivated(); 253 OnHostActivated();
254 // TODO(thomasanderson): Remove this window shuffling and use XWindowCache
255 // instead.
238 open_windows().remove(xwindow_); 256 open_windows().remove(xwindow_);
239 open_windows().insert(open_windows().begin(), xwindow_); 257 open_windows().insert(open_windows().begin(), xwindow_);
240 } else {
241 ReleaseCapture();
242 } 258 }
259 if (was_active_ != IsActive()) {
260 desktop_native_widget_aura_->HandleActivationChanged(IsActive());
261 native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint();
262 }
263 }
243 264
244 desktop_native_widget_aura_->HandleActivationChanged(active); 265 void DesktopWindowTreeHostX11::OnCrossingEvent(bool enter,
266 bool focus,
danakj 2016/08/19 21:43:45 focus_in_window_or_ancestor?
Tom (Use chromium acct) 2016/08/22 20:27:07 Done.
267 int detail) {
268 if (detail == NotifyInferior)
danakj 2016/08/19 21:43:45 When the mouse moves from the root into |xwindow_|
danakj 2016/08/19 23:17:32 Oh I see. EnterNotify with Inferior means we're c
Tom (Use chromium acct) 2016/08/22 20:27:07 Done.
269 return;
245 270
246 native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint(); 271 BeforeActivationStateChanged();
272
273 has_pointer_ = enter;
274 if (focus && !has_window_focus_)
danakj 2016/08/19 21:43:45 // If focus is not in an ancestor then this crossi
Tom (Use chromium acct) 2016/08/22 20:27:07 Done. I wrote something different though.
275 has_pointer_focus_ = has_pointer_;
276
277 AfterActivationStateChanged();
278 }
279
280 void DesktopWindowTreeHostX11::OnFocusEvent(bool focus_in,
281 int mode,
282 int detail) {
283 if (detail == NotifyInferior)
danakj 2016/08/19 23:29:58 Can you say the same thing here moreorless?
Tom (Use chromium acct) 2016/08/22 20:27:07 Done.
284 return;
285 BeforeActivationStateChanged();
286 if (mode != NotifyWhileGrabbed && detail != NotifyPointer)
danakj 2016/08/19 23:29:58 Can you throw some comments here kinda like the he
danakj 2016/08/19 23:59:30 Also can you explain by ignore Pointer here in a c
danakj 2016/08/19 23:59:30 Maybe better would be to say that while grabbed we
Tom (Use chromium acct) 2016/08/22 20:27:07 Done.
Tom (Use chromium acct) 2016/08/22 20:27:07 Done.
287 has_focus_ = focus_in;
288 if (mode != NotifyGrab && mode != NotifyUngrab &&
289 mode != XINotifyPassiveGrab && mode != XINotifyPassiveUngrab) {
290 if (detail != NotifyPointer)
291 has_window_focus_ = focus_in;
292 if (has_pointer_) {
293 switch (detail) {
294 case NotifyAncestor:
295 case NotifyVirtual:
danakj 2016/08/19 23:59:30 Can you leave a comment why NonLinear(Virtual) are
Tom (Use chromium acct) 2016/08/22 20:27:07 Done.
296 has_pointer_focus_ = !focus_in;
297 break;
298 case NotifyPointer:
299 has_pointer_focus_ = focus_in;
300 break;
301 default:
302 break;
303 }
304 }
305 }
306 ignore_input_ = false;
307 AfterActivationStateChanged();
247 } 308 }
248 309
249 void DesktopWindowTreeHostX11::AddObserver( 310 void DesktopWindowTreeHostX11::AddObserver(
250 views::DesktopWindowTreeHostObserverX11* observer) { 311 views::DesktopWindowTreeHostObserverX11* observer) {
251 observer_list_.AddObserver(observer); 312 observer_list_.AddObserver(observer);
252 } 313 }
253 314
254 void DesktopWindowTreeHostX11::RemoveObserver( 315 void DesktopWindowTreeHostX11::RemoveObserver(
255 views::DesktopWindowTreeHostObserverX11* observer) { 316 views::DesktopWindowTreeHostObserverX11* observer) {
256 observer_list_.RemoveObserver(observer); 317 observer_list_.RemoveObserver(observer);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 sanitized_params.bounds.set_height(100); 362 sanitized_params.bounds.set_height(100);
302 363
303 InitX11Window(sanitized_params); 364 InitX11Window(sanitized_params);
304 } 365 }
305 366
306 void DesktopWindowTreeHostX11::OnNativeWidgetCreated( 367 void DesktopWindowTreeHostX11::OnNativeWidgetCreated(
307 const Widget::InitParams& params) { 368 const Widget::InitParams& params) {
308 window()->SetProperty(kViewsWindowForRootWindow, content_window_); 369 window()->SetProperty(kViewsWindowForRootWindow, content_window_);
309 window()->SetProperty(kHostForRootWindow, this); 370 window()->SetProperty(kHostForRootWindow, this);
310 371
311 // Ensure that the X11DesktopHandler exists so that it dispatches activation 372 // Ensure that the X11DesktopHandler exists so that it tracks create/destroy
312 // messages to us. 373 // notify events.
313 X11DesktopHandler::get(); 374 X11DesktopHandler::get();
314 375
315 // TODO(erg): Unify this code once the other consumer goes away. 376 // TODO(erg): Unify this code once the other consumer goes away.
316 SwapNonClientEventHandler( 377 SwapNonClientEventHandler(
317 std::unique_ptr<ui::EventHandler>(new X11WindowEventFilter(this))); 378 std::unique_ptr<ui::EventHandler>(new X11WindowEventFilter(this)));
318 SetUseNativeFrame(params.type == Widget::InitParams::TYPE_WINDOW && 379 SetUseNativeFrame(params.type == Widget::InitParams::TYPE_WINDOW &&
319 !params.remove_standard_frame); 380 !params.remove_standard_frame);
320 381
321 x11_window_move_client_.reset(new X11DesktopWindowMoveClient); 382 x11_window_move_client_.reset(new X11DesktopWindowMoveClient);
322 aura::client::SetWindowMoveClient(window(), x11_window_move_client_.get()); 383 aura::client::SetWindowMoveClient(window(), x11_window_move_client_.get());
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 } 460 }
400 461
401 aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() { 462 aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() {
402 return this; 463 return this;
403 } 464 }
404 465
405 void DesktopWindowTreeHostX11::ShowWindowWithState( 466 void DesktopWindowTreeHostX11::ShowWindowWithState(
406 ui::WindowShowState show_state) { 467 ui::WindowShowState show_state) {
407 if (compositor()) 468 if (compositor())
408 compositor()->SetVisible(true); 469 compositor()->SetVisible(true);
409 if (!window_mapped_) 470 if (!IsVisible())
410 MapWindow(show_state); 471 MapWindow(show_state);
411 472
412 switch (show_state) { 473 switch (show_state) {
413 case ui::SHOW_STATE_MAXIMIZED: 474 case ui::SHOW_STATE_MAXIMIZED:
414 Maximize(); 475 Maximize();
415 break; 476 break;
416 case ui::SHOW_STATE_MINIMIZED: 477 case ui::SHOW_STATE_MINIMIZED:
417 Minimize(); 478 Minimize();
418 break; 479 break;
419 case ui::SHOW_STATE_FULLSCREEN: 480 case ui::SHOW_STATE_FULLSCREEN:
420 SetFullscreen(true); 481 SetFullscreen(true);
421 break; 482 break;
422 default: 483 default:
423 break; 484 break;
424 } 485 }
425 486
426 // Makes the window activated by default if the state is not INACTIVE or 487 // Makes the window activated by default if the state is not INACTIVE or
427 // MINIMIZED. 488 // MINIMIZED.
428 if (show_state != ui::SHOW_STATE_INACTIVE && 489 if (show_state != ui::SHOW_STATE_INACTIVE &&
429 show_state != ui::SHOW_STATE_MINIMIZED && 490 show_state != ui::SHOW_STATE_MINIMIZED) {
430 activatable_) {
431 Activate(); 491 Activate();
432 } 492 }
433 493
434 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state); 494 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state);
435 } 495 }
436 496
437 void DesktopWindowTreeHostX11::ShowMaximizedWithBounds( 497 void DesktopWindowTreeHostX11::ShowMaximizedWithBounds(
438 const gfx::Rect& restored_bounds) { 498 const gfx::Rect& restored_bounds) {
439 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); 499 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED);
440 // Enforce |restored_bounds_in_pixels_| since calling Maximize() could have 500 // Enforce |restored_bounds_in_pixels_| since calling Maximize() could have
441 // reset it. 501 // reset it.
442 restored_bounds_in_pixels_ = ToPixelRect(restored_bounds); 502 restored_bounds_in_pixels_ = ToPixelRect(restored_bounds);
443 } 503 }
444 504
445 bool DesktopWindowTreeHostX11::IsVisible() const { 505 bool DesktopWindowTreeHostX11::IsVisible() const {
446 return window_mapped_; 506 return window_mapped_ && !wait_for_unmap_;
447 } 507 }
448 508
449 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { 509 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) {
450 gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(requested_size)).size(); 510 gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(requested_size)).size();
451 size_in_pixels = AdjustSize(size_in_pixels); 511 size_in_pixels = AdjustSize(size_in_pixels);
452 bool size_changed = bounds_in_pixels_.size() != size_in_pixels; 512 bool size_changed = bounds_in_pixels_.size() != size_in_pixels;
453 XResizeWindow(xdisplay_, xwindow_, size_in_pixels.width(), 513 XResizeWindow(xdisplay_, xwindow_, size_in_pixels.width(),
454 size_in_pixels.height()); 514 size_in_pixels.height());
455 bounds_in_pixels_.set_size(size_in_pixels); 515 bounds_in_pixels_.set_size(size_in_pixels);
456 if (size_changed) { 516 if (size_changed) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 } else { 667 } else {
608 window_shape_.reset(gfx::CreateRegionFromSkRegion(*native_region)); 668 window_shape_.reset(gfx::CreateRegionFromSkRegion(*native_region));
609 } 669 }
610 670
611 custom_window_shape_ = true; 671 custom_window_shape_ = true;
612 } 672 }
613 ResetWindowRegion(); 673 ResetWindowRegion();
614 } 674 }
615 675
616 void DesktopWindowTreeHostX11::Activate() { 676 void DesktopWindowTreeHostX11::Activate() {
617 if (!window_mapped_) 677 if (!IsVisible() || !activatable_)
618 return; 678 return;
619 679
620 X11DesktopHandler::get()->ActivateWindow(xwindow_); 680 BeforeActivationStateChanged();
681
682 ignore_input_ = false;
683
684 // wmii says that it supports _NET_ACTIVE_WINDOW but does not.
685 // https://code.google.com/p/wmii/issues/detail?id=266
686 static bool wm_supports_active_window =
687 ui::GuessWindowManager() != ui::WM_WMII &&
688 ui::WmSupportsHint(atom_cache_.GetAtom("_NET_ACTIVE_WINDOW"));
689
690 Time timestamp = ui::X11EventSource::GetInstance()->GetTimestamp();
691
692 if (wm_supports_active_window) {
693 XEvent xclient;
694 memset(&xclient, 0, sizeof(xclient));
695 xclient.type = ClientMessage;
696 xclient.xclient.window = xwindow_;
697 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW");
698 xclient.xclient.format = 32;
699 xclient.xclient.data.l[0] = 1; // Specified we are an app.
700 xclient.xclient.data.l[1] = timestamp;
701 // TODO(thomasanderson): if another chrome window is active, specify that in
702 // data.l[2]. The EWMH spec claims this may make the WM more likely to
703 // service our _NET_ACTIVE_WINDOW request.
704 xclient.xclient.data.l[2] = None;
705 xclient.xclient.data.l[3] = 0;
706 xclient.xclient.data.l[4] = 0;
707
708 XSendEvent(xdisplay_, x_root_window_, False,
709 SubstructureRedirectMask | SubstructureNotifyMask, &xclient);
710 } else {
711 XRaiseWindow(xdisplay_, xwindow_);
712 // Directly ask the X server to give focus to the window. Note that the call
713 // will raise an X error if the window is not mapped.
714 XSetInputFocus(xdisplay_, xwindow_, RevertToParent, timestamp);
715 // At this point, we know we will receive focus, and some tests depend on a
716 // window being IsActive() immediately after an Activate(), so just set this
717 // state now.
718 has_pointer_focus_ = false;
719 has_window_focus_ = true;
720 }
721 AfterActivationStateChanged();
621 } 722 }
622 723
623 void DesktopWindowTreeHostX11::Deactivate() { 724 void DesktopWindowTreeHostX11::Deactivate() {
624 if (!IsActive()) 725 BeforeActivationStateChanged();
625 return; 726
727 // Ignore future input events.
728 ignore_input_ = true;
626 729
627 ReleaseCapture(); 730 ReleaseCapture();
628 X11DesktopHandler::get()->DeactivateWindow(xwindow_); 731 XLowerWindow(xdisplay_, xwindow_);
732
733 AfterActivationStateChanged();
629 } 734 }
630 735
631 bool DesktopWindowTreeHostX11::IsActive() const { 736 bool DesktopWindowTreeHostX11::IsActive() const {
632 return X11DesktopHandler::get()->IsActiveWindow(xwindow_); 737 // Focus and stacking order are independent in X11. Since we cannot guarantee
738 // a window is topmost iff it has focus, just use the focus state to determine
739 // if a window is active. Note that Activate() and Deactivate() change the
740 // stacking order in addition to changing the focus state.
741 bool is_active = (has_focus_ || has_pointer_focus_) && !ignore_input_;
danakj 2016/08/19 23:29:58 FWIW normally an X window will show itself as visi
Tom (Use chromium acct) 2016/08/22 20:27:07 The cross-platform code seems to want a window to
danakj 2016/08/22 20:32:42 OK just to be clear then, when alt-tabbing does th
742
743 // is_active => window_mapped_
744 // !window_mapped_ => !is_active
745 DCHECK(!is_active || window_mapped_);
746
747 return is_active;
633 } 748 }
634 749
635 void DesktopWindowTreeHostX11::Maximize() { 750 void DesktopWindowTreeHostX11::Maximize() {
636 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { 751 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) {
637 // Unfullscreen the window if it is fullscreen. 752 // Unfullscreen the window if it is fullscreen.
638 SetWMSpecState(false, 753 SetWMSpecState(false,
639 atom_cache_.GetAtom("_NET_WM_STATE_FULLSCREEN"), 754 atom_cache_.GetAtom("_NET_WM_STATE_FULLSCREEN"),
640 None); 755 None);
641 756
642 // Resize the window so that it does not have the same size as a monitor. 757 // 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 758 // (Otherwise, some window managers immediately put the window back in
644 // fullscreen mode). 759 // fullscreen mode).
645 gfx::Rect adjusted_bounds_in_pixels(bounds_in_pixels_.origin(), 760 gfx::Rect adjusted_bounds_in_pixels(bounds_in_pixels_.origin(),
646 AdjustSize(bounds_in_pixels_.size())); 761 AdjustSize(bounds_in_pixels_.size()));
647 if (adjusted_bounds_in_pixels != bounds_in_pixels_) 762 if (adjusted_bounds_in_pixels != bounds_in_pixels_)
648 SetBounds(adjusted_bounds_in_pixels); 763 SetBounds(adjusted_bounds_in_pixels);
649 } 764 }
650 765
651 // Some WMs do not respect maximization hints on unmapped windows, so we 766 // Some WMs do not respect maximization hints on unmapped windows, so we
652 // save this one for later too. 767 // save this one for later too.
653 should_maximize_after_map_ = !window_mapped_; 768 should_maximize_after_map_ = !IsVisible();
654 769
655 // When we are in the process of requesting to maximize a window, we can 770 // 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 771 // accurately keep track of our restored bounds instead of relying on the
657 // heuristics that are in the PropertyNotify and ConfigureNotify handlers. 772 // heuristics that are in the PropertyNotify and ConfigureNotify handlers.
658 restored_bounds_in_pixels_ = bounds_in_pixels_; 773 restored_bounds_in_pixels_ = bounds_in_pixels_;
659 774
660 SetWMSpecState(true, 775 SetWMSpecState(true,
661 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), 776 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
662 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); 777 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
663 if (IsMinimized()) 778 if (IsMinimized())
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 1079
965 void DesktopWindowTreeHostX11::SizeConstraintsChanged() { 1080 void DesktopWindowTreeHostX11::SizeConstraintsChanged() {
966 UpdateMinAndMaxSize(); 1081 UpdateMinAndMaxSize();
967 } 1082 }
968 1083
969 //////////////////////////////////////////////////////////////////////////////// 1084 ////////////////////////////////////////////////////////////////////////////////
970 // DesktopWindowTreeHostX11, aura::WindowTreeHost implementation: 1085 // DesktopWindowTreeHostX11, aura::WindowTreeHost implementation:
971 1086
972 gfx::Transform DesktopWindowTreeHostX11::GetRootTransform() const { 1087 gfx::Transform DesktopWindowTreeHostX11::GetRootTransform() const {
973 display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay(); 1088 display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
974 if (window_mapped_) { 1089 if (IsVisible()) {
975 aura::Window* win = const_cast<aura::Window*>(window()); 1090 aura::Window* win = const_cast<aura::Window*>(window());
976 display = display::Screen::GetScreen()->GetDisplayNearestWindow(win); 1091 display = display::Screen::GetScreen()->GetDisplayNearestWindow(win);
977 } 1092 }
978 1093
979 float scale = display.device_scale_factor(); 1094 float scale = display.device_scale_factor();
980 gfx::Transform transform; 1095 gfx::Transform transform;
981 transform.Scale(scale, scale); 1096 transform.Scale(scale, scale);
982 return transform; 1097 return transform;
983 } 1098 }
984 1099
985 ui::EventSource* DesktopWindowTreeHostX11::GetEventSource() { 1100 ui::EventSource* DesktopWindowTreeHostX11::GetEventSource() {
986 return this; 1101 return this;
987 } 1102 }
988 1103
989 gfx::AcceleratedWidget DesktopWindowTreeHostX11::GetAcceleratedWidget() { 1104 gfx::AcceleratedWidget DesktopWindowTreeHostX11::GetAcceleratedWidget() {
990 return xwindow_; 1105 return xwindow_;
991 } 1106 }
992 1107
993 void DesktopWindowTreeHostX11::ShowImpl() { 1108 void DesktopWindowTreeHostX11::ShowImpl() {
994 ShowWindowWithState(ui::SHOW_STATE_NORMAL); 1109 ShowWindowWithState(ui::SHOW_STATE_NORMAL);
995 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); 1110 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true);
996 } 1111 }
997 1112
998 void DesktopWindowTreeHostX11::HideImpl() { 1113 void DesktopWindowTreeHostX11::HideImpl() {
999 if (window_mapped_) { 1114 if (IsVisible()) {
1000 XWithdrawWindow(xdisplay_, xwindow_, 0); 1115 XWithdrawWindow(xdisplay_, xwindow_, 0);
1001 window_mapped_ = false;
1002 wait_for_unmap_ = true; 1116 wait_for_unmap_ = true;
1003 } 1117 }
1004 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); 1118 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false);
1005 } 1119 }
1006 1120
1007 gfx::Rect DesktopWindowTreeHostX11::GetBounds() const { 1121 gfx::Rect DesktopWindowTreeHostX11::GetBounds() const {
1008 return bounds_in_pixels_; 1122 return bounds_in_pixels_;
1009 } 1123 }
1010 1124
1011 void DesktopWindowTreeHostX11::SetBounds( 1125 void DesktopWindowTreeHostX11::SetBounds(
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 insets.size() == 4) { 1531 insets.size() == 4) {
1418 // |insets| are returned in the order: [left, right, top, bottom]. 1532 // |insets| are returned in the order: [left, right, top, bottom].
1419 native_window_frame_borders_in_pixels_ = 1533 native_window_frame_borders_in_pixels_ =
1420 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); 1534 gfx::Insets(insets[2], insets[0], insets[3], insets[1]);
1421 } else { 1535 } else {
1422 native_window_frame_borders_in_pixels_ = gfx::Insets(); 1536 native_window_frame_borders_in_pixels_ = gfx::Insets();
1423 } 1537 }
1424 } 1538 }
1425 1539
1426 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { 1540 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() {
1427 if (!window_mapped_) 1541 if (!IsVisible())
1428 return; 1542 return;
1429 1543
1430 gfx::Size minimum_in_pixels = 1544 gfx::Size minimum_in_pixels =
1431 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); 1545 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size();
1432 gfx::Size maximum_in_pixels = 1546 gfx::Size maximum_in_pixels =
1433 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); 1547 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size();
1434 if (min_size_in_pixels_ == minimum_in_pixels && 1548 if (min_size_in_pixels_ == minimum_in_pixels &&
1435 max_size_in_pixels_ == maximum_in_pixels) 1549 max_size_in_pixels_ == maximum_in_pixels)
1436 return; 1550 return;
1437 1551
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 unsigned long wm_user_time_ms = static_cast<unsigned long>( 1587 unsigned long wm_user_time_ms = static_cast<unsigned long>(
1474 (ui::EventTimeFromNative(event) - base::TimeTicks()).InMilliseconds()); 1588 (ui::EventTimeFromNative(event) - base::TimeTicks()).InMilliseconds());
1475 XChangeProperty(xdisplay_, 1589 XChangeProperty(xdisplay_,
1476 xwindow_, 1590 xwindow_,
1477 atom_cache_.GetAtom("_NET_WM_USER_TIME"), 1591 atom_cache_.GetAtom("_NET_WM_USER_TIME"),
1478 XA_CARDINAL, 1592 XA_CARDINAL,
1479 32, 1593 32,
1480 PropModeReplace, 1594 PropModeReplace,
1481 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), 1595 reinterpret_cast<const unsigned char *>(&wm_user_time_ms),
1482 1); 1596 1);
1483 X11DesktopHandler::get()->set_wm_user_time_ms(wm_user_time_ms);
1484 } 1597 }
1485 } 1598 }
1486 1599
1487 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled, 1600 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled,
1488 ::Atom state1, 1601 ::Atom state1,
1489 ::Atom state2) { 1602 ::Atom state2) {
1490 XEvent xclient; 1603 XEvent xclient;
1491 memset(&xclient, 0, sizeof(xclient)); 1604 memset(&xclient, 0, sizeof(xclient));
1492 xclient.type = ClientMessage; 1605 xclient.type = ClientMessage;
1493 xclient.xclient.window = xwindow_; 1606 xclient.xclient.window = xwindow_;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 // will ignore toplevel XMoveWindow commands. 1787 // will ignore toplevel XMoveWindow commands.
1675 XSizeHints size_hints; 1788 XSizeHints size_hints;
1676 size_hints.flags = PPosition; 1789 size_hints.flags = PPosition;
1677 size_hints.x = bounds_in_pixels_.x(); 1790 size_hints.x = bounds_in_pixels_.x();
1678 size_hints.y = bounds_in_pixels_.y(); 1791 size_hints.y = bounds_in_pixels_.y();
1679 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); 1792 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
1680 1793
1681 // If SHOW_STATE_INACTIVE, tell the window manager not to focus the window 1794 // 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. 1795 // 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 1796 // http://standards.freedesktop.org/wm-spec/latest/ar01s05.html
1684 unsigned long wm_user_time_ms = (show_state == ui::SHOW_STATE_INACTIVE) ? 1797 ignore_input_ = show_state == ui::SHOW_STATE_INACTIVE;
1685 0 : X11DesktopHandler::get()->wm_user_time_ms(); 1798 unsigned long wm_user_time_ms =
1799 ignore_input_ ? 0 : ui::X11EventSource::GetInstance()->GetTimestamp();
1686 if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) { 1800 if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) {
1687 XChangeProperty(xdisplay_, 1801 XChangeProperty(
1688 xwindow_, 1802 xdisplay_, xwindow_, atom_cache_.GetAtom("_NET_WM_USER_TIME"),
1689 atom_cache_.GetAtom("_NET_WM_USER_TIME"), 1803 XA_CARDINAL, 32, PropModeReplace,
1690 XA_CARDINAL, 1804 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 } 1805 }
1696 1806
1697 ui::X11EventSource* event_source = ui::X11EventSource::GetInstance(); 1807 ui::X11EventSource* event_source = ui::X11EventSource::GetInstance();
1698 DCHECK(event_source); 1808 DCHECK(event_source);
1699 1809
1700 if (wait_for_unmap_) { 1810 if (wait_for_unmap_) {
1701 // Block until our window is unmapped. This avoids a race condition when 1811 // Block until our window is unmapped. This avoids a race condition when
1702 // remapping an unmapped window. 1812 // remapping an unmapped window.
1703 event_source->BlockUntilWindowUnmapped(xwindow_); 1813 event_source->BlockUntilWindowUnmapped(xwindow_);
1704 DCHECK(!wait_for_unmap_); 1814 DCHECK(!wait_for_unmap_);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1746 TRACE_EVENT1("views", "DesktopWindowTreeHostX11::Dispatch", 1856 TRACE_EVENT1("views", "DesktopWindowTreeHostX11::Dispatch",
1747 "event->type", event->type); 1857 "event->type", event->type);
1748 1858
1749 UpdateWMUserTime(event); 1859 UpdateWMUserTime(event);
1750 1860
1751 // May want to factor CheckXEventForConsistency(xev); into a common location 1861 // May want to factor CheckXEventForConsistency(xev); into a common location
1752 // since it is called here. 1862 // since it is called here.
1753 switch (xev->type) { 1863 switch (xev->type) {
1754 case EnterNotify: 1864 case EnterNotify:
1755 case LeaveNotify: { 1865 case LeaveNotify: {
1866 OnCrossingEvent(xev->type == EnterNotify, xev->xcrossing.focus,
1867 xev->xcrossing.detail);
1868
1756 // Ignore EventNotify and LeaveNotify events from children of |xwindow_|. 1869 // Ignore EventNotify and LeaveNotify events from children of |xwindow_|.
1757 // NativeViewGLSurfaceGLX adds a child to |xwindow_|. 1870 // NativeViewGLSurfaceGLX adds a child to |xwindow_|.
1758 // TODO(pkotwicz|tdanderson): Figure out whether the suppression is 1871 if (xev->xcrossing.detail != NotifyInferior) {
1759 // necessary. crbug.com/385716 1872 ui::MouseEvent mouse_event(xev);
1760 if (xev->xcrossing.detail == NotifyInferior) 1873 DispatchMouseEvent(&mouse_event);
1761 break; 1874 }
1762
1763 ui::MouseEvent mouse_event(xev);
1764 DispatchMouseEvent(&mouse_event);
1765 break; 1875 break;
1766 } 1876 }
1767 case Expose: { 1877 case Expose: {
1768 gfx::Rect damage_rect_in_pixels(xev->xexpose.x, xev->xexpose.y, 1878 gfx::Rect damage_rect_in_pixels(xev->xexpose.x, xev->xexpose.y,
1769 xev->xexpose.width, xev->xexpose.height); 1879 xev->xexpose.width, xev->xexpose.height);
1770 compositor()->ScheduleRedrawRect(damage_rect_in_pixels); 1880 compositor()->ScheduleRedrawRect(damage_rect_in_pixels);
1771 break; 1881 break;
1772 } 1882 }
1773 case KeyPress: { 1883 case KeyPress: {
1774 ui::KeyEvent keydown_event(xev); 1884 ui::KeyEvent keydown_event(xev);
1775 DispatchKeyEvent(&keydown_event); 1885 DispatchKeyEvent(&keydown_event);
1776 break; 1886 break;
1777 } 1887 }
1778 case KeyRelease: { 1888 case KeyRelease: {
1779 // There is no way to deactivate a window in X11 so ignore input if 1889 // There is no way to deactivate a window in X11 so ignore input if
1780 // window is supposed to be 'inactive'. See comments in 1890 // window is supposed to be 'inactive'.
1781 // X11DesktopHandler::DeactivateWindow() for more details.
1782 if (!IsActive() && !HasCapture()) 1891 if (!IsActive() && !HasCapture())
1783 break; 1892 break;
1784 1893
1785 ui::KeyEvent key_event(xev); 1894 ui::KeyEvent key_event(xev);
1786 DispatchKeyEvent(&key_event); 1895 DispatchKeyEvent(&key_event);
1787 break; 1896 break;
1788 } 1897 }
1789 case ButtonPress: 1898 case ButtonPress:
1790 case ButtonRelease: { 1899 case ButtonRelease: {
1791 ui::EventType event_type = ui::EventTypeFromNative(xev); 1900 ui::EventType event_type = ui::EventTypeFromNative(xev);
(...skipping 10 matching lines...) Expand all
1802 break; 1911 break;
1803 } 1912 }
1804 case ui::ET_UNKNOWN: 1913 case ui::ET_UNKNOWN:
1805 // No event is created for X11-release events for mouse-wheel buttons. 1914 // No event is created for X11-release events for mouse-wheel buttons.
1806 break; 1915 break;
1807 default: 1916 default:
1808 NOTREACHED() << event_type; 1917 NOTREACHED() << event_type;
1809 } 1918 }
1810 break; 1919 break;
1811 } 1920 }
1812 case FocusOut: 1921 case FocusIn:
1813 if (xev->xfocus.mode != NotifyGrab) { 1922 case FocusOut: {
danakj 2016/08/19 21:43:45 nit: {} are not needed since there's no vars decla
Tom (Use chromium acct) 2016/08/22 20:27:07 Done.
1814 ReleaseCapture(); 1923 OnFocusEvent(xev->type == FocusIn, event->xfocus.mode,
1815 OnHostLostWindowCapture(); 1924 event->xfocus.detail);
1816 X11DesktopHandler::get()->ProcessXEvent(xev);
1817 } else {
1818 dispatcher()->OnHostLostMouseGrab();
1819 }
1820 break; 1925 break;
1821 case FocusIn: 1926 }
1822 X11DesktopHandler::get()->ProcessXEvent(xev);
1823 break;
1824 case ConfigureNotify: { 1927 case ConfigureNotify: {
1825 DCHECK_EQ(xwindow_, xev->xconfigure.window); 1928 DCHECK_EQ(xwindow_, xev->xconfigure.window);
1826 DCHECK_EQ(xwindow_, xev->xconfigure.event); 1929 DCHECK_EQ(xwindow_, xev->xconfigure.event);
1827 // It's possible that the X window may be resized by some other means than 1930 // 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 1931 // from within aura (e.g. the X window manager can change the size). Make
1829 // sure the root window size is maintained properly. 1932 // sure the root window size is maintained properly.
1830 int translated_x_in_pixels = xev->xconfigure.x; 1933 int translated_x_in_pixels = xev->xconfigure.x;
1831 int translated_y_in_pixels = xev->xconfigure.y; 1934 int translated_y_in_pixels = xev->xconfigure.y;
1832 if (!xev->xconfigure.send_event && !xev->xconfigure.override_redirect) { 1935 if (!xev->xconfigure.send_event && !xev->xconfigure.override_redirect) {
1833 Window unused; 1936 Window unused;
(...skipping 19 matching lines...) Expand all
1853 base::ThreadTaskRunnerHandle::Get()->PostTask( 1956 base::ThreadTaskRunnerHandle::Get()->PostTask(
1854 FROM_HERE, delayed_resize_task_.callback()); 1957 FROM_HERE, delayed_resize_task_.callback());
1855 } 1958 }
1856 break; 1959 break;
1857 } 1960 }
1858 case GenericEvent: { 1961 case GenericEvent: {
1859 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); 1962 ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
1860 if (!factory->ShouldProcessXI2Event(xev)) 1963 if (!factory->ShouldProcessXI2Event(xev))
1861 break; 1964 break;
1862 1965
1966 XIEnterEvent* enter_event = static_cast<XIEnterEvent*>(xev->xcookie.data);
1967 switch (static_cast<XIEvent*>(xev->xcookie.data)->evtype) {
1968 case XI_Enter:
1969 case XI_Leave:
1970 OnCrossingEvent(enter_event->evtype == XI_Enter, enter_event->focus,
1971 enter_event->detail);
1972 break;
1973 case XI_FocusIn:
1974 case XI_FocusOut:
1975 OnFocusEvent(enter_event->evtype == XI_FocusIn, enter_event->mode,
danakj 2016/08/19 23:59:30 Would you consider rewriting the mode to non-XI co
Tom (Use chromium acct) 2016/08/22 20:27:07 Done.
1976 enter_event->detail);
1977 break;
1978 default:
1979 break;
1980 }
1981
1863 ui::EventType type = ui::EventTypeFromNative(xev); 1982 ui::EventType type = ui::EventTypeFromNative(xev);
1864 XEvent last_event; 1983 XEvent last_event;
1865 int num_coalesced = 0; 1984 int num_coalesced = 0;
1866 1985
1867 switch (type) { 1986 switch (type) {
1868 case ui::ET_TOUCH_MOVED: 1987 case ui::ET_TOUCH_MOVED:
1869 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); 1988 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
1870 if (num_coalesced > 0) 1989 if (num_coalesced > 0)
1871 xev = &last_event; 1990 xev = &last_event;
1872 // fallthrough 1991 // fallthrough
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 2052
1934 // Some WMs only respect maximize hints after the window has been mapped. 2053 // Some WMs only respect maximize hints after the window has been mapped.
1935 // Check whether we need to re-do a maximization. 2054 // Check whether we need to re-do a maximization.
1936 if (should_maximize_after_map_) { 2055 if (should_maximize_after_map_) {
1937 Maximize(); 2056 Maximize();
1938 should_maximize_after_map_ = false; 2057 should_maximize_after_map_ = false;
1939 } 2058 }
1940 2059
1941 break; 2060 break;
1942 } 2061 }
1943 case UnmapNotify: { 2062 case UnmapNotify: {
danakj 2016/08/19 21:43:45 jw do we care about DestroyNotify? Presumably no..
Tom (Use chromium acct) 2016/08/22 20:27:07 no
2063 window_mapped_ = false;
1944 wait_for_unmap_ = false; 2064 wait_for_unmap_ = false;
2065 has_pointer_ = false;
2066 has_pointer_grab_ = false;
2067 has_pointer_focus_ = false;
2068 has_window_focus_ = false;
2069 has_focus_ = false;
1945 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11, 2070 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11,
1946 observer_list_, 2071 observer_list_,
1947 OnWindowUnmapped(xwindow_)); 2072 OnWindowUnmapped(xwindow_));
1948 break; 2073 break;
1949 } 2074 }
1950 case ClientMessage: { 2075 case ClientMessage: {
1951 Atom message_type = xev->xclient.message_type; 2076 Atom message_type = xev->xclient.message_type;
1952 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { 2077 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) {
1953 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); 2078 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]);
1954 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { 2079 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2094 if (linux_ui) { 2219 if (linux_ui) {
2095 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); 2220 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window);
2096 if (native_theme) 2221 if (native_theme)
2097 return native_theme; 2222 return native_theme;
2098 } 2223 }
2099 2224
2100 return ui::NativeThemeAura::instance(); 2225 return ui::NativeThemeAura::instance();
2101 } 2226 }
2102 2227
2103 } // namespace views 2228 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698