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 14 matching lines...) Expand all Loading... |
25 #include "ui/base/hit_test.h" | 25 #include "ui/base/hit_test.h" |
26 #include "ui/base/x/x11_util.h" | 26 #include "ui/base/x/x11_util.h" |
27 #include "ui/events/devices/x11/device_data_manager_x11.h" | 27 #include "ui/events/devices/x11/device_data_manager_x11.h" |
28 #include "ui/events/devices/x11/device_list_cache_x11.h" | 28 #include "ui/events/devices/x11/device_list_cache_x11.h" |
29 #include "ui/events/devices/x11/touch_factory_x11.h" | 29 #include "ui/events/devices/x11/touch_factory_x11.h" |
30 #include "ui/events/event_utils.h" | 30 #include "ui/events/event_utils.h" |
31 #include "ui/events/platform/platform_event_source.h" | 31 #include "ui/events/platform/platform_event_source.h" |
32 #include "ui/events/platform/x11/x11_event_source.h" | 32 #include "ui/events/platform/x11/x11_event_source.h" |
33 #include "ui/gfx/display.h" | 33 #include "ui/gfx/display.h" |
34 #include "ui/gfx/geometry/insets.h" | 34 #include "ui/gfx/geometry/insets.h" |
| 35 #include "ui/gfx/geometry/size_conversions.h" |
35 #include "ui/gfx/image/image_skia.h" | 36 #include "ui/gfx/image/image_skia.h" |
36 #include "ui/gfx/image/image_skia_rep.h" | 37 #include "ui/gfx/image/image_skia_rep.h" |
37 #include "ui/gfx/path.h" | 38 #include "ui/gfx/path.h" |
38 #include "ui/gfx/path_x11.h" | 39 #include "ui/gfx/path_x11.h" |
39 #include "ui/gfx/screen.h" | 40 #include "ui/gfx/screen.h" |
40 #include "ui/native_theme/native_theme.h" | 41 #include "ui/native_theme/native_theme.h" |
41 #include "ui/views/corewm/tooltip_aura.h" | 42 #include "ui/views/corewm/tooltip_aura.h" |
42 #include "ui/views/ime/input_method.h" | 43 #include "ui/views/ime/input_method.h" |
43 #include "ui/views/linux_ui/linux_ui.h" | 44 #include "ui/views/linux_ui/linux_ui.h" |
44 #include "ui/views/views_delegate.h" | 45 #include "ui/views/views_delegate.h" |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 std::vector<aura::Window*> DesktopWindowTreeHostX11::GetAllOpenWindows() { | 184 std::vector<aura::Window*> DesktopWindowTreeHostX11::GetAllOpenWindows() { |
184 std::vector<aura::Window*> windows(open_windows().size()); | 185 std::vector<aura::Window*> windows(open_windows().size()); |
185 std::transform(open_windows().begin(), | 186 std::transform(open_windows().begin(), |
186 open_windows().end(), | 187 open_windows().end(), |
187 windows.begin(), | 188 windows.begin(), |
188 GetContentWindowForXID); | 189 GetContentWindowForXID); |
189 return windows; | 190 return windows; |
190 } | 191 } |
191 | 192 |
192 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowBounds() const { | 193 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowBounds() const { |
193 return bounds_; | 194 return bounds_in_pixels_; |
194 } | 195 } |
195 | 196 |
196 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const { | 197 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const { |
197 gfx::Rect outer_bounds(bounds_); | 198 gfx::Rect outer_bounds(bounds_in_pixels_); |
198 outer_bounds.Inset(-native_window_frame_borders_); | 199 outer_bounds.Inset(-native_window_frame_borders_in_pixels_); |
199 return outer_bounds; | 200 return outer_bounds; |
200 } | 201 } |
201 | 202 |
202 ::Region DesktopWindowTreeHostX11::GetWindowShape() const { | 203 ::Region DesktopWindowTreeHostX11::GetWindowShape() const { |
203 return window_shape_; | 204 return window_shape_; |
204 } | 205 } |
205 | 206 |
206 void DesktopWindowTreeHostX11::HandleNativeWidgetActivationChanged( | 207 void DesktopWindowTreeHostX11::HandleNativeWidgetActivationChanged( |
207 bool active) { | 208 bool active) { |
208 if (active) { | 209 if (active) { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 show_state == ui::SHOW_STATE_MAXIMIZED) { | 375 show_state == ui::SHOW_STATE_MAXIMIZED) { |
375 Activate(); | 376 Activate(); |
376 } | 377 } |
377 | 378 |
378 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state); | 379 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state); |
379 } | 380 } |
380 | 381 |
381 void DesktopWindowTreeHostX11::ShowMaximizedWithBounds( | 382 void DesktopWindowTreeHostX11::ShowMaximizedWithBounds( |
382 const gfx::Rect& restored_bounds) { | 383 const gfx::Rect& restored_bounds) { |
383 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); | 384 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); |
384 // Enforce |restored_bounds_| since calling Maximize() could have reset it. | 385 // Enforce |restored_bounds_in_pixels_| since calling Maximize() could have |
385 restored_bounds_ = restored_bounds; | 386 // reset it. |
| 387 restored_bounds_in_pixels_ = ToPixelRect(restored_bounds); |
386 } | 388 } |
387 | 389 |
388 bool DesktopWindowTreeHostX11::IsVisible() const { | 390 bool DesktopWindowTreeHostX11::IsVisible() const { |
389 return window_mapped_; | 391 return window_mapped_; |
390 } | 392 } |
391 | 393 |
392 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { | 394 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { |
393 gfx::Size size = AdjustSize(requested_size); | 395 gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(requested_size)).size(); |
394 bool size_changed = bounds_.size() != size; | 396 size_in_pixels = AdjustSize(size_in_pixels); |
395 XResizeWindow(xdisplay_, xwindow_, size.width(), size.height()); | 397 bool size_changed = bounds_in_pixels_.size() != size_in_pixels; |
396 bounds_.set_size(size); | 398 XResizeWindow(xdisplay_, xwindow_, size_in_pixels.width(), |
| 399 size_in_pixels.height()); |
| 400 bounds_in_pixels_.set_size(size_in_pixels); |
397 if (size_changed) { | 401 if (size_changed) { |
398 OnHostResized(size); | 402 OnHostResized(size_in_pixels); |
399 ResetWindowRegion(); | 403 ResetWindowRegion(); |
400 } | 404 } |
401 } | 405 } |
402 | 406 |
403 void DesktopWindowTreeHostX11::StackAtTop() { | 407 void DesktopWindowTreeHostX11::StackAtTop() { |
404 XRaiseWindow(xdisplay_, xwindow_); | 408 XRaiseWindow(xdisplay_, xwindow_); |
405 } | 409 } |
406 | 410 |
407 void DesktopWindowTreeHostX11::CenterWindow(const gfx::Size& size) { | 411 void DesktopWindowTreeHostX11::CenterWindow(const gfx::Size& size) { |
408 gfx::Rect parent_bounds = GetWorkAreaBoundsInScreen(); | 412 gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(size)).size(); |
| 413 gfx::Rect parent_bounds_in_pixels = GetWorkAreaBoundsInPixels(); |
409 | 414 |
410 // If |window_|'s transient parent bounds are big enough to contain |size|, | 415 // If |window_|'s transient parent bounds are big enough to contain |size|, |
411 // use them instead. | 416 // use them instead. |
412 if (wm::GetTransientParent(content_window_)) { | 417 if (wm::GetTransientParent(content_window_)) { |
413 gfx::Rect transient_parent_rect = | 418 gfx::Rect transient_parent_rect = |
414 wm::GetTransientParent(content_window_)->GetBoundsInScreen(); | 419 wm::GetTransientParent(content_window_)->GetBoundsInScreen(); |
415 if (transient_parent_rect.height() >= size.height() && | 420 if (transient_parent_rect.height() >= size.height() && |
416 transient_parent_rect.width() >= size.width()) { | 421 transient_parent_rect.width() >= size.width()) { |
417 parent_bounds = transient_parent_rect; | 422 parent_bounds_in_pixels = ToPixelRect(transient_parent_rect); |
418 } | 423 } |
419 } | 424 } |
420 | 425 |
421 gfx::Rect window_bounds( | 426 gfx::Rect window_bounds_in_pixels( |
422 parent_bounds.x() + (parent_bounds.width() - size.width()) / 2, | 427 parent_bounds_in_pixels.x() + |
423 parent_bounds.y() + (parent_bounds.height() - size.height()) / 2, | 428 (parent_bounds_in_pixels.width() - size_in_pixels.width()) / 2, |
424 size.width(), | 429 parent_bounds_in_pixels.y() + |
425 size.height()); | 430 (parent_bounds_in_pixels.height() - size_in_pixels.height()) / 2, |
| 431 size_in_pixels.width(), size_in_pixels.height()); |
426 // Don't size the window bigger than the parent, otherwise the user may not be | 432 // Don't size the window bigger than the parent, otherwise the user may not be |
427 // able to close or move it. | 433 // able to close or move it. |
428 window_bounds.AdjustToFit(parent_bounds); | 434 window_bounds_in_pixels.AdjustToFit(parent_bounds_in_pixels); |
429 | 435 |
430 SetBounds(window_bounds); | 436 SetBounds(window_bounds_in_pixels); |
431 } | 437 } |
432 | 438 |
433 void DesktopWindowTreeHostX11::GetWindowPlacement( | 439 void DesktopWindowTreeHostX11::GetWindowPlacement( |
434 gfx::Rect* bounds, | 440 gfx::Rect* bounds, |
435 ui::WindowShowState* show_state) const { | 441 ui::WindowShowState* show_state) const { |
436 *bounds = GetRestoredBounds(); | 442 *bounds = GetRestoredBounds(); |
437 | 443 |
438 if (IsFullscreen()) { | 444 if (IsFullscreen()) { |
439 *show_state = ui::SHOW_STATE_FULLSCREEN; | 445 *show_state = ui::SHOW_STATE_FULLSCREEN; |
440 } else if (IsMinimized()) { | 446 } else if (IsMinimized()) { |
441 *show_state = ui::SHOW_STATE_MINIMIZED; | 447 *show_state = ui::SHOW_STATE_MINIMIZED; |
442 } else if (IsMaximized()) { | 448 } else if (IsMaximized()) { |
443 *show_state = ui::SHOW_STATE_MAXIMIZED; | 449 *show_state = ui::SHOW_STATE_MAXIMIZED; |
444 } else if (!IsActive()) { | 450 } else if (!IsActive()) { |
445 *show_state = ui::SHOW_STATE_INACTIVE; | 451 *show_state = ui::SHOW_STATE_INACTIVE; |
446 } else { | 452 } else { |
447 *show_state = ui::SHOW_STATE_NORMAL; | 453 *show_state = ui::SHOW_STATE_NORMAL; |
448 } | 454 } |
449 } | 455 } |
450 | 456 |
451 gfx::Rect DesktopWindowTreeHostX11::GetWindowBoundsInScreen() const { | 457 gfx::Rect DesktopWindowTreeHostX11::GetWindowBoundsInScreen() const { |
452 return bounds_; | 458 return ToDIPRect(bounds_in_pixels_); |
453 } | 459 } |
454 | 460 |
455 gfx::Rect DesktopWindowTreeHostX11::GetClientAreaBoundsInScreen() const { | 461 gfx::Rect DesktopWindowTreeHostX11::GetClientAreaBoundsInScreen() const { |
456 // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its | 462 // TODO(erg): The NativeWidgetAura version returns |bounds_in_pixels_|, |
457 // needed for View::ConvertPointToScreen() to work | 463 // claiming it's needed for View::ConvertPointToScreen() to work correctly. |
458 // correctly. DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just | 464 // DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just asks windows |
459 // asks windows what it thinks the client rect is. | 465 // what it thinks the client rect is. |
460 // | 466 // |
461 // Attempts to calculate the rect by asking the NonClientFrameView what it | 467 // Attempts to calculate the rect by asking the NonClientFrameView what it |
462 // thought its GetBoundsForClientView() were broke combobox drop down | 468 // thought its GetBoundsForClientView() were broke combobox drop down |
463 // placement. | 469 // placement. |
464 return bounds_; | 470 return GetWindowBoundsInScreen(); |
465 } | 471 } |
466 | 472 |
467 gfx::Rect DesktopWindowTreeHostX11::GetRestoredBounds() const { | 473 gfx::Rect DesktopWindowTreeHostX11::GetRestoredBounds() const { |
468 // We can't reliably track the restored bounds of a window, but we can get | 474 // We can't reliably track the restored bounds of a window, but we can get |
469 // the 90% case down. When *chrome* is the process that requests maximizing | 475 // the 90% case down. When *chrome* is the process that requests maximizing |
470 // or restoring bounds, we can record the current bounds before we request | 476 // or restoring bounds, we can record the current bounds before we request |
471 // maximization, and clear it when we detect a state change. | 477 // maximization, and clear it when we detect a state change. |
472 if (!restored_bounds_.IsEmpty()) | 478 if (!restored_bounds_in_pixels_.IsEmpty()) |
473 return restored_bounds_; | 479 return ToDIPRect(restored_bounds_in_pixels_); |
474 | 480 |
475 return GetWindowBoundsInScreen(); | 481 return GetWindowBoundsInScreen(); |
476 } | 482 } |
477 | 483 |
478 gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInScreen() const { | 484 gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInScreen() const { |
479 std::vector<int> value; | 485 return ToDIPRect(GetWorkAreaBoundsInPixels()); |
480 if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) && | |
481 value.size() >= 4) { | |
482 return gfx::Rect(value[0], value[1], value[2], value[3]); | |
483 } | |
484 | |
485 // Fetch the geometry of the root window. | |
486 Window root; | |
487 int x, y; | |
488 unsigned int width, height; | |
489 unsigned int border_width, depth; | |
490 if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y, | |
491 &width, &height, &border_width, &depth)) { | |
492 NOTIMPLEMENTED(); | |
493 return gfx::Rect(0, 0, 10, 10); | |
494 } | |
495 | |
496 return gfx::Rect(x, y, width, height); | |
497 } | 486 } |
498 | 487 |
499 void DesktopWindowTreeHostX11::SetShape(gfx::NativeRegion native_region) { | 488 void DesktopWindowTreeHostX11::SetShape(gfx::NativeRegion native_region) { |
500 if (window_shape_) | 489 if (window_shape_) |
501 XDestroyRegion(window_shape_); | 490 XDestroyRegion(window_shape_); |
502 custom_window_shape_ = false; | 491 custom_window_shape_ = false; |
503 window_shape_ = NULL; | 492 window_shape_ = NULL; |
504 | 493 |
505 if (native_region) { | 494 if (native_region) { |
506 custom_window_shape_ = true; | 495 custom_window_shape_ = true; |
(...skipping 25 matching lines...) Expand all Loading... |
532 void DesktopWindowTreeHostX11::Maximize() { | 521 void DesktopWindowTreeHostX11::Maximize() { |
533 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { | 522 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { |
534 // Unfullscreen the window if it is fullscreen. | 523 // Unfullscreen the window if it is fullscreen. |
535 SetWMSpecState(false, | 524 SetWMSpecState(false, |
536 atom_cache_.GetAtom("_NET_WM_STATE_FULLSCREEN"), | 525 atom_cache_.GetAtom("_NET_WM_STATE_FULLSCREEN"), |
537 None); | 526 None); |
538 | 527 |
539 // Resize the window so that it does not have the same size as a monitor. | 528 // Resize the window so that it does not have the same size as a monitor. |
540 // (Otherwise, some window managers immediately put the window back in | 529 // (Otherwise, some window managers immediately put the window back in |
541 // fullscreen mode). | 530 // fullscreen mode). |
542 gfx::Rect adjusted_bounds(bounds_.origin(), AdjustSize(bounds_.size())); | 531 gfx::Rect adjusted_bounds_in_pixels(bounds_in_pixels_.origin(), |
543 if (adjusted_bounds != bounds_) | 532 AdjustSize(bounds_in_pixels_.size())); |
544 SetBounds(adjusted_bounds); | 533 if (adjusted_bounds_in_pixels != bounds_in_pixels_) |
| 534 SetBounds(adjusted_bounds_in_pixels); |
545 } | 535 } |
546 | 536 |
547 // Some WMs do not respect maximization hints on unmapped windows, so we | 537 // Some WMs do not respect maximization hints on unmapped windows, so we |
548 // save this one for later too. | 538 // save this one for later too. |
549 should_maximize_after_map_ = !window_mapped_; | 539 should_maximize_after_map_ = !window_mapped_; |
550 | 540 |
551 // When we are in the process of requesting to maximize a window, we can | 541 // When we are in the process of requesting to maximize a window, we can |
552 // accurately keep track of our restored bounds instead of relying on the | 542 // accurately keep track of our restored bounds instead of relying on the |
553 // heuristics that are in the PropertyNotify and ConfigureNotify handlers. | 543 // heuristics that are in the PropertyNotify and ConfigureNotify handlers. |
554 restored_bounds_ = bounds_; | 544 restored_bounds_in_pixels_ = bounds_in_pixels_; |
555 | 545 |
556 SetWMSpecState(true, | 546 SetWMSpecState(true, |
557 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), | 547 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), |
558 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); | 548 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); |
559 if (IsMinimized()) | 549 if (IsMinimized()) |
560 ShowWindowWithState(ui::SHOW_STATE_NORMAL); | 550 ShowWindowWithState(ui::SHOW_STATE_NORMAL); |
561 } | 551 } |
562 | 552 |
563 void DesktopWindowTreeHostX11::Minimize() { | 553 void DesktopWindowTreeHostX11::Minimize() { |
564 ReleaseCapture(); | 554 ReleaseCapture(); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 None); | 720 None); |
731 if (unmaximize_and_remaximize) | 721 if (unmaximize_and_remaximize) |
732 Maximize(); | 722 Maximize(); |
733 | 723 |
734 // Try to guess the size we will have after the switch to/from fullscreen: | 724 // Try to guess the size we will have after the switch to/from fullscreen: |
735 // - (may) avoid transient states | 725 // - (may) avoid transient states |
736 // - works around Flash content which expects to have the size updated | 726 // - works around Flash content which expects to have the size updated |
737 // synchronously. | 727 // synchronously. |
738 // See https://crbug.com/361408 | 728 // See https://crbug.com/361408 |
739 if (fullscreen) { | 729 if (fullscreen) { |
740 restored_bounds_ = bounds_; | 730 restored_bounds_in_pixels_ = bounds_in_pixels_; |
741 const gfx::Display display = | 731 const gfx::Display display = |
742 gfx::Screen::GetScreenFor(NULL)->GetDisplayNearestWindow(window()); | 732 gfx::Screen::GetScreenFor(NULL)->GetDisplayNearestWindow(window()); |
743 bounds_ = display.bounds(); | 733 bounds_in_pixels_ = ToPixelRect(display.bounds()); |
744 } else { | 734 } else { |
745 bounds_ = restored_bounds_; | 735 bounds_in_pixels_ = restored_bounds_in_pixels_; |
746 } | 736 } |
747 OnHostMoved(bounds_.origin()); | 737 OnHostMoved(bounds_in_pixels_.origin()); |
748 OnHostResized(bounds_.size()); | 738 OnHostResized(bounds_in_pixels_.size()); |
749 | 739 |
750 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN") == fullscreen) { | 740 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN") == fullscreen) { |
751 Relayout(); | 741 Relayout(); |
752 ResetWindowRegion(); | 742 ResetWindowRegion(); |
753 } | 743 } |
754 // Else: the widget will be relaid out either when the window bounds change or | 744 // Else: the widget will be relaid out either when the window bounds change or |
755 // when |xwindow_|'s fullscreen state changes. | 745 // when |xwindow_|'s fullscreen state changes. |
756 } | 746 } |
757 | 747 |
758 bool DesktopWindowTreeHostX11::IsFullscreen() const { | 748 bool DesktopWindowTreeHostX11::IsFullscreen() const { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 return false; | 845 return false; |
856 } | 846 } |
857 | 847 |
858 void DesktopWindowTreeHostX11::SizeConstraintsChanged() { | 848 void DesktopWindowTreeHostX11::SizeConstraintsChanged() { |
859 UpdateMinAndMaxSize(); | 849 UpdateMinAndMaxSize(); |
860 } | 850 } |
861 | 851 |
862 //////////////////////////////////////////////////////////////////////////////// | 852 //////////////////////////////////////////////////////////////////////////////// |
863 // DesktopWindowTreeHostX11, aura::WindowTreeHost implementation: | 853 // DesktopWindowTreeHostX11, aura::WindowTreeHost implementation: |
864 | 854 |
| 855 gfx::Transform DesktopWindowTreeHostX11::GetRootTransform() const { |
| 856 gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); |
| 857 if (window_mapped_) { |
| 858 aura::Window* win = const_cast<aura::Window*>(window()); |
| 859 display = gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(win); |
| 860 } |
| 861 |
| 862 float scale = display.device_scale_factor(); |
| 863 gfx::Transform transform; |
| 864 transform.Scale(scale, scale); |
| 865 return transform; |
| 866 } |
| 867 |
865 ui::EventSource* DesktopWindowTreeHostX11::GetEventSource() { | 868 ui::EventSource* DesktopWindowTreeHostX11::GetEventSource() { |
866 return this; | 869 return this; |
867 } | 870 } |
868 | 871 |
869 gfx::AcceleratedWidget DesktopWindowTreeHostX11::GetAcceleratedWidget() { | 872 gfx::AcceleratedWidget DesktopWindowTreeHostX11::GetAcceleratedWidget() { |
870 return xwindow_; | 873 return xwindow_; |
871 } | 874 } |
872 | 875 |
873 void DesktopWindowTreeHostX11::Show() { | 876 void DesktopWindowTreeHostX11::Show() { |
874 ShowWindowWithState(ui::SHOW_STATE_NORMAL); | 877 ShowWindowWithState(ui::SHOW_STATE_NORMAL); |
875 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); | 878 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); |
876 } | 879 } |
877 | 880 |
878 void DesktopWindowTreeHostX11::Hide() { | 881 void DesktopWindowTreeHostX11::Hide() { |
879 if (window_mapped_) { | 882 if (window_mapped_) { |
880 XWithdrawWindow(xdisplay_, xwindow_, 0); | 883 XWithdrawWindow(xdisplay_, xwindow_, 0); |
881 window_mapped_ = false; | 884 window_mapped_ = false; |
882 } | 885 } |
883 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); | 886 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); |
884 } | 887 } |
885 | 888 |
886 gfx::Rect DesktopWindowTreeHostX11::GetBounds() const { | 889 gfx::Rect DesktopWindowTreeHostX11::GetBounds() const { |
887 return bounds_; | 890 return bounds_in_pixels_; |
888 } | 891 } |
889 | 892 |
890 void DesktopWindowTreeHostX11::SetBounds(const gfx::Rect& requested_bounds) { | 893 void DesktopWindowTreeHostX11::SetBounds( |
891 gfx::Rect bounds(requested_bounds.origin(), | 894 const gfx::Rect& requested_bounds_in_pixel) { |
892 AdjustSize(requested_bounds.size())); | 895 gfx::Rect bounds_in_pixels(requested_bounds_in_pixel.origin(), |
893 bool origin_changed = bounds_.origin() != bounds.origin(); | 896 AdjustSize(requested_bounds_in_pixel.size())); |
894 bool size_changed = bounds_.size() != bounds.size(); | 897 bool origin_changed = bounds_in_pixels_.origin() != bounds_in_pixels.origin(); |
| 898 bool size_changed = bounds_in_pixels_.size() != bounds_in_pixels.size(); |
895 XWindowChanges changes = {0}; | 899 XWindowChanges changes = {0}; |
896 unsigned value_mask = 0; | 900 unsigned value_mask = 0; |
897 | 901 |
898 if (size_changed) { | 902 if (size_changed) { |
899 if (bounds.width() < min_size_.width() || | 903 if (bounds_in_pixels.width() < min_size_in_pixels_.width() || |
900 bounds.height() < min_size_.height() || | 904 bounds_in_pixels.height() < min_size_in_pixels_.height() || |
901 (!max_size_.IsEmpty() && | 905 (!max_size_in_pixels_.IsEmpty() && |
902 (bounds.width() > max_size_.width() || | 906 (bounds_in_pixels.width() > max_size_in_pixels_.width() || |
903 bounds.height() > max_size_.height()))) { | 907 bounds_in_pixels.height() > max_size_in_pixels_.height()))) { |
904 // Update the minimum and maximum sizes in case they have changed. | 908 // Update the minimum and maximum sizes in case they have changed. |
905 UpdateMinAndMaxSize(); | 909 UpdateMinAndMaxSize(); |
906 | 910 |
907 gfx::Size size = bounds.size(); | 911 gfx::Size size_in_pixels = bounds_in_pixels.size(); |
908 size.SetToMin(max_size_); | 912 size_in_pixels.SetToMin(max_size_in_pixels_); |
909 size.SetToMax(min_size_); | 913 size_in_pixels.SetToMax(min_size_in_pixels_); |
910 bounds.set_size(size); | 914 bounds_in_pixels.set_size(size_in_pixels); |
911 } | 915 } |
912 | 916 |
913 changes.width = bounds.width(); | 917 changes.width = bounds_in_pixels.width(); |
914 changes.height = bounds.height(); | 918 changes.height = bounds_in_pixels.height(); |
915 value_mask |= CWHeight | CWWidth; | 919 value_mask |= CWHeight | CWWidth; |
916 } | 920 } |
917 | 921 |
918 if (origin_changed) { | 922 if (origin_changed) { |
919 changes.x = bounds.x(); | 923 changes.x = bounds_in_pixels.x(); |
920 changes.y = bounds.y(); | 924 changes.y = bounds_in_pixels.y(); |
921 value_mask |= CWX | CWY; | 925 value_mask |= CWX | CWY; |
922 } | 926 } |
923 if (value_mask) | 927 if (value_mask) |
924 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes); | 928 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes); |
925 | 929 |
926 // Assume that the resize will go through as requested, which should be the | 930 // Assume that the resize will go through as requested, which should be the |
927 // case if we're running without a window manager. If there's a window | 931 // case if we're running without a window manager. If there's a window |
928 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a | 932 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a |
929 // (possibly synthetic) ConfigureNotify about the actual size and correct | 933 // (possibly synthetic) ConfigureNotify about the actual size and correct |
930 // |bounds_| later. | 934 // |bounds_in_pixels_| later. |
931 bounds_ = bounds; | 935 bounds_in_pixels_ = bounds_in_pixels; |
932 | 936 |
933 if (origin_changed) | 937 if (origin_changed) |
934 native_widget_delegate_->AsWidget()->OnNativeWidgetMove(); | 938 native_widget_delegate_->AsWidget()->OnNativeWidgetMove(); |
935 if (size_changed) { | 939 if (size_changed) { |
936 OnHostResized(bounds.size()); | 940 OnHostResized(bounds_in_pixels.size()); |
937 ResetWindowRegion(); | 941 ResetWindowRegion(); |
938 } | 942 } |
939 } | 943 } |
940 | 944 |
941 gfx::Point DesktopWindowTreeHostX11::GetLocationOnNativeScreen() const { | 945 gfx::Point DesktopWindowTreeHostX11::GetLocationOnNativeScreen() const { |
942 return bounds_.origin(); | 946 return bounds_in_pixels_.origin(); |
943 } | 947 } |
944 | 948 |
945 void DesktopWindowTreeHostX11::SetCapture() { | 949 void DesktopWindowTreeHostX11::SetCapture() { |
946 if (HasCapture()) | 950 if (HasCapture()) |
947 return; | 951 return; |
948 | 952 |
949 // Grabbing the mouse is asynchronous. However, we synchronously start | 953 // Grabbing the mouse is asynchronous. However, we synchronously start |
950 // forwarding all mouse events received by Chrome to the | 954 // forwarding all mouse events received by Chrome to the |
951 // aura::WindowEventDispatcher which has capture. This makes capture | 955 // aura::WindowEventDispatcher which has capture. This makes capture |
952 // synchronous for all intents and purposes if either: | 956 // synchronous for all intents and purposes if either: |
(...skipping 22 matching lines...) Expand all Loading... |
975 OnHostLostWindowCapture(); | 979 OnHostLostWindowCapture(); |
976 } | 980 } |
977 } | 981 } |
978 | 982 |
979 void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) { | 983 void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) { |
980 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); | 984 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); |
981 } | 985 } |
982 | 986 |
983 void DesktopWindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) { | 987 void DesktopWindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) { |
984 XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0, | 988 XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0, |
985 bounds_.x() + location.x(), bounds_.y() + location.y()); | 989 bounds_in_pixels_.x() + location.x(), |
| 990 bounds_in_pixels_.y() + location.y()); |
986 } | 991 } |
987 | 992 |
988 void DesktopWindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { | 993 void DesktopWindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { |
989 // TODO(erg): Conditional on us enabling touch on desktop linux builds, do | 994 // TODO(erg): Conditional on us enabling touch on desktop linux builds, do |
990 // the same tap-to-click disabling here that chromeos does. | 995 // the same tap-to-click disabling here that chromeos does. |
991 } | 996 } |
992 | 997 |
993 //////////////////////////////////////////////////////////////////////////////// | 998 //////////////////////////////////////////////////////////////////////////////// |
994 // DesktopWindowTreeHostX11, ui::EventSource implementation: | 999 // DesktopWindowTreeHostX11, ui::EventSource implementation: |
995 | 1000 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1051 | 1056 |
1052 // x.org will BadMatch if we don't set a border when the depth isn't the | 1057 // x.org will BadMatch if we don't set a border when the depth isn't the |
1053 // same as the parent depth. | 1058 // same as the parent depth. |
1054 attribute_mask |= CWBorderPixel; | 1059 attribute_mask |= CWBorderPixel; |
1055 swa.border_pixel = 0; | 1060 swa.border_pixel = 0; |
1056 | 1061 |
1057 use_argb_visual_ = true; | 1062 use_argb_visual_ = true; |
1058 } | 1063 } |
1059 } | 1064 } |
1060 | 1065 |
1061 bounds_ = gfx::Rect(params.bounds.origin(), | 1066 bounds_in_pixels_ = ToPixelRect(params.bounds); |
1062 AdjustSize(params.bounds.size())); | 1067 bounds_in_pixels_.set_size(AdjustSize(bounds_in_pixels_.size())); |
1063 xwindow_ = XCreateWindow( | 1068 xwindow_ = XCreateWindow(xdisplay_, x_root_window_, bounds_in_pixels_.x(), |
1064 xdisplay_, x_root_window_, | 1069 bounds_in_pixels_.y(), bounds_in_pixels_.width(), |
1065 bounds_.x(), bounds_.y(), | 1070 bounds_in_pixels_.height(), |
1066 bounds_.width(), bounds_.height(), | 1071 0, // border width |
1067 0, // border width | 1072 depth, InputOutput, visual, attribute_mask, &swa); |
1068 depth, | |
1069 InputOutput, | |
1070 visual, | |
1071 attribute_mask, | |
1072 &swa); | |
1073 if (ui::PlatformEventSource::GetInstance()) | 1073 if (ui::PlatformEventSource::GetInstance()) |
1074 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); | 1074 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); |
1075 open_windows().push_back(xwindow_); | 1075 open_windows().push_back(xwindow_); |
1076 | 1076 |
1077 // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL(). | 1077 // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL(). |
1078 | 1078 |
1079 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | | 1079 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | |
1080 KeyPressMask | KeyReleaseMask | | 1080 KeyPressMask | KeyReleaseMask | |
1081 EnterWindowMask | LeaveWindowMask | | 1081 EnterWindowMask | LeaveWindowMask | |
1082 ExposureMask | VisibilityChangeMask | | 1082 ExposureMask | VisibilityChangeMask | |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 // icon. | 1201 // icon. |
1202 gfx::ImageSkia* window_icon = ViewsDelegate::views_delegate ? | 1202 gfx::ImageSkia* window_icon = ViewsDelegate::views_delegate ? |
1203 ViewsDelegate::views_delegate->GetDefaultWindowIcon() : NULL; | 1203 ViewsDelegate::views_delegate->GetDefaultWindowIcon() : NULL; |
1204 if (window_icon) { | 1204 if (window_icon) { |
1205 SetWindowIcons(gfx::ImageSkia(), *window_icon); | 1205 SetWindowIcons(gfx::ImageSkia(), *window_icon); |
1206 } | 1206 } |
1207 CreateCompositor(GetAcceleratedWidget()); | 1207 CreateCompositor(GetAcceleratedWidget()); |
1208 } | 1208 } |
1209 | 1209 |
1210 gfx::Size DesktopWindowTreeHostX11::AdjustSize( | 1210 gfx::Size DesktopWindowTreeHostX11::AdjustSize( |
1211 const gfx::Size& requested_size) { | 1211 const gfx::Size& requested_size_in_pixels) { |
1212 std::vector<gfx::Display> displays = | 1212 std::vector<gfx::Display> displays = |
1213 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)->GetAllDisplays(); | 1213 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)->GetAllDisplays(); |
1214 // Compare against all monitor sizes. The window manager can move the window | 1214 // Compare against all monitor sizes. The window manager can move the window |
1215 // to whichever monitor it wants. | 1215 // to whichever monitor it wants. |
1216 for (size_t i = 0; i < displays.size(); ++i) { | 1216 for (size_t i = 0; i < displays.size(); ++i) { |
1217 if (requested_size == displays[i].size()) { | 1217 if (requested_size_in_pixels == displays[i].GetSizeInPixel()) { |
1218 return gfx::Size(requested_size.width() - 1, | 1218 return gfx::Size(requested_size_in_pixels.width() - 1, |
1219 requested_size.height() - 1); | 1219 requested_size_in_pixels.height() - 1); |
1220 } | 1220 } |
1221 } | 1221 } |
1222 | 1222 |
1223 // Do not request a 0x0 window size. It causes an XError. | 1223 // Do not request a 0x0 window size. It causes an XError. |
1224 gfx::Size size = requested_size; | 1224 gfx::Size size_in_pixels = requested_size_in_pixels; |
1225 size.SetToMax(gfx::Size(1,1)); | 1225 size_in_pixels.SetToMax(gfx::Size(1, 1)); |
1226 return size; | 1226 return size_in_pixels; |
1227 } | 1227 } |
1228 | 1228 |
1229 void DesktopWindowTreeHostX11::OnWMStateUpdated() { | 1229 void DesktopWindowTreeHostX11::OnWMStateUpdated() { |
1230 std::vector< ::Atom> atom_list; | 1230 std::vector< ::Atom> atom_list; |
1231 // Ignore the return value of ui::GetAtomArrayProperty(). Fluxbox removes the | 1231 // Ignore the return value of ui::GetAtomArrayProperty(). Fluxbox removes the |
1232 // _NET_WM_STATE property when no _NET_WM_STATE atoms are set. | 1232 // _NET_WM_STATE property when no _NET_WM_STATE atoms are set. |
1233 ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list); | 1233 ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list); |
1234 | 1234 |
1235 bool was_minimized = IsMinimized(); | 1235 bool was_minimized = IsMinimized(); |
1236 | 1236 |
(...skipping 17 matching lines...) Expand all Loading... |
1254 if (is_minimized != was_minimized) { | 1254 if (is_minimized != was_minimized) { |
1255 if (is_minimized) { | 1255 if (is_minimized) { |
1256 compositor()->SetVisible(false); | 1256 compositor()->SetVisible(false); |
1257 content_window_->Hide(); | 1257 content_window_->Hide(); |
1258 } else { | 1258 } else { |
1259 content_window_->Show(); | 1259 content_window_->Show(); |
1260 compositor()->SetVisible(true); | 1260 compositor()->SetVisible(true); |
1261 } | 1261 } |
1262 } | 1262 } |
1263 | 1263 |
1264 if (restored_bounds_.IsEmpty()) { | 1264 if (restored_bounds_in_pixels_.IsEmpty()) { |
1265 DCHECK(!IsFullscreen()); | 1265 DCHECK(!IsFullscreen()); |
1266 if (IsMaximized()) { | 1266 if (IsMaximized()) { |
1267 // The request that we become maximized originated from a different | 1267 // The request that we become maximized originated from a different |
1268 // process. |bounds_| already contains our maximized bounds. Do a best | 1268 // process. |bounds_in_pixels_| already contains our maximized bounds. Do |
1269 // effort attempt to get restored bounds by setting it to our previously | 1269 // a best effort attempt to get restored bounds by setting it to our |
1270 // set bounds (and if we get this wrong, we aren't any worse off since | 1270 // previously set bounds (and if we get this wrong, we aren't any worse |
1271 // we'd otherwise be returning our maximized bounds). | 1271 // off since we'd otherwise be returning our maximized bounds). |
1272 restored_bounds_ = previous_bounds_; | 1272 restored_bounds_in_pixels_ = previous_bounds_in_pixels_; |
1273 } | 1273 } |
1274 } else if (!IsMaximized() && !IsFullscreen()) { | 1274 } else if (!IsMaximized() && !IsFullscreen()) { |
1275 // If we have restored bounds, but WM_STATE no longer claims to be | 1275 // If we have restored bounds, but WM_STATE no longer claims to be |
1276 // maximized or fullscreen, we should clear our restored bounds. | 1276 // maximized or fullscreen, we should clear our restored bounds. |
1277 restored_bounds_ = gfx::Rect(); | 1277 restored_bounds_in_pixels_ = gfx::Rect(); |
1278 } | 1278 } |
1279 | 1279 |
1280 // Ignore requests by the window manager to enter or exit fullscreen (e.g. as | 1280 // Ignore requests by the window manager to enter or exit fullscreen (e.g. as |
1281 // a result of pressing a window manager accelerator key). Chrome does not | 1281 // a result of pressing a window manager accelerator key). Chrome does not |
1282 // handle window manager initiated fullscreen. In particular, Chrome needs to | 1282 // handle window manager initiated fullscreen. In particular, Chrome needs to |
1283 // do preprocessing before the x window's fullscreen state is toggled. | 1283 // do preprocessing before the x window's fullscreen state is toggled. |
1284 | 1284 |
1285 is_always_on_top_ = HasWMSpecProperty("_NET_WM_STATE_ABOVE"); | 1285 is_always_on_top_ = HasWMSpecProperty("_NET_WM_STATE_ABOVE"); |
1286 | 1286 |
1287 // Now that we have different window properties, we may need to relayout the | 1287 // Now that we have different window properties, we may need to relayout the |
1288 // window. (The windows code doesn't need this because their window change is | 1288 // window. (The windows code doesn't need this because their window change is |
1289 // synchronous.) | 1289 // synchronous.) |
1290 Relayout(); | 1290 Relayout(); |
1291 ResetWindowRegion(); | 1291 ResetWindowRegion(); |
1292 } | 1292 } |
1293 | 1293 |
1294 void DesktopWindowTreeHostX11::OnFrameExtentsUpdated() { | 1294 void DesktopWindowTreeHostX11::OnFrameExtentsUpdated() { |
1295 std::vector<int> insets; | 1295 std::vector<int> insets; |
1296 if (ui::GetIntArrayProperty(xwindow_, "_NET_FRAME_EXTENTS", &insets) && | 1296 if (ui::GetIntArrayProperty(xwindow_, "_NET_FRAME_EXTENTS", &insets) && |
1297 insets.size() == 4) { | 1297 insets.size() == 4) { |
1298 // |insets| are returned in the order: [left, right, top, bottom]. | 1298 // |insets| are returned in the order: [left, right, top, bottom]. |
1299 native_window_frame_borders_ = gfx::Insets( | 1299 native_window_frame_borders_in_pixels_ = |
1300 insets[2], | 1300 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); |
1301 insets[0], | |
1302 insets[3], | |
1303 insets[1]); | |
1304 } else { | 1301 } else { |
1305 native_window_frame_borders_ = gfx::Insets(); | 1302 native_window_frame_borders_in_pixels_ = gfx::Insets(); |
1306 } | 1303 } |
1307 } | 1304 } |
1308 | 1305 |
1309 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { | 1306 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { |
1310 if (!window_mapped_) | 1307 if (!window_mapped_) |
1311 return; | 1308 return; |
1312 | 1309 |
1313 gfx::Size minimum = native_widget_delegate_->GetMinimumSize(); | 1310 gfx::Size minimum_in_pixels = |
1314 gfx::Size maximum = native_widget_delegate_->GetMaximumSize(); | 1311 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); |
1315 if (min_size_ == minimum && max_size_ == maximum) | 1312 gfx::Size maximum_in_pixels = |
| 1313 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); |
| 1314 if (min_size_in_pixels_ == minimum_in_pixels && |
| 1315 max_size_in_pixels_ == maximum_in_pixels) |
1316 return; | 1316 return; |
1317 | 1317 |
1318 min_size_ = minimum; | 1318 min_size_in_pixels_ = minimum_in_pixels; |
1319 max_size_ = maximum; | 1319 max_size_in_pixels_ = maximum_in_pixels; |
1320 | 1320 |
1321 XSizeHints hints; | 1321 XSizeHints hints; |
1322 long supplied_return; | 1322 long supplied_return; |
1323 XGetWMNormalHints(xdisplay_, xwindow_, &hints, &supplied_return); | 1323 XGetWMNormalHints(xdisplay_, xwindow_, &hints, &supplied_return); |
1324 | 1324 |
1325 if (minimum.IsEmpty()) { | 1325 if (minimum_in_pixels.IsEmpty()) { |
1326 hints.flags &= ~PMinSize; | 1326 hints.flags &= ~PMinSize; |
1327 } else { | 1327 } else { |
1328 hints.flags |= PMinSize; | 1328 hints.flags |= PMinSize; |
1329 hints.min_width = min_size_.width(); | 1329 hints.min_width = min_size_in_pixels_.width(); |
1330 hints.min_height = min_size_.height(); | 1330 hints.min_height = min_size_in_pixels_.height(); |
1331 } | 1331 } |
1332 | 1332 |
1333 if (maximum.IsEmpty()) { | 1333 if (maximum_in_pixels.IsEmpty()) { |
1334 hints.flags &= ~PMaxSize; | 1334 hints.flags &= ~PMaxSize; |
1335 } else { | 1335 } else { |
1336 hints.flags |= PMaxSize; | 1336 hints.flags |= PMaxSize; |
1337 hints.max_width = max_size_.width(); | 1337 hints.max_width = max_size_in_pixels_.width(); |
1338 hints.max_height = max_size_.height(); | 1338 hints.max_height = max_size_in_pixels_.height(); |
1339 } | 1339 } |
1340 | 1340 |
1341 XSetWMNormalHints(xdisplay_, xwindow_, &hints); | 1341 XSetWMNormalHints(xdisplay_, xwindow_, &hints); |
1342 } | 1342 } |
1343 | 1343 |
1344 void DesktopWindowTreeHostX11::UpdateWMUserTime( | 1344 void DesktopWindowTreeHostX11::UpdateWMUserTime( |
1345 const ui::PlatformEvent& event) { | 1345 const ui::PlatformEvent& event) { |
1346 if (!IsActive()) | 1346 if (!IsActive()) |
1347 return; | 1347 return; |
1348 | 1348 |
1349 ui::EventType type = ui::EventTypeFromNative(event); | 1349 ui::EventType type = ui::EventTypeFromNative(event); |
1350 if (type == ui::ET_MOUSE_PRESSED || | 1350 if (type == ui::ET_MOUSE_PRESSED || |
1351 type == ui::ET_KEY_PRESSED || | 1351 type == ui::ET_KEY_PRESSED || |
1352 type == ui::ET_TOUCH_PRESSED) { | 1352 type == ui::ET_TOUCH_PRESSED) { |
1353 unsigned long wm_user_time_ms = static_cast<unsigned long>( | 1353 unsigned long wm_user_time_ms = static_cast<unsigned long>( |
1354 ui::EventTimeFromNative(event).InMilliseconds()); | 1354 ui::EventTimeFromNative(event).InMilliseconds()); |
1355 XChangeProperty(xdisplay_, | 1355 XChangeProperty(xdisplay_, |
1356 xwindow_, | 1356 xwindow_, |
1357 atom_cache_.GetAtom("_NET_WM_USER_TIME"), | 1357 atom_cache_.GetAtom("_NET_WM_USER_TIME"), |
1358 XA_CARDINAL, | 1358 XA_CARDINAL, |
1359 32, | 1359 32, |
1360 PropModeReplace, | 1360 PropModeReplace, |
1361 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), | 1361 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), |
1362 1); | 1362 1); |
1363 X11DesktopHandler::get()->set_wm_user_time_ms(wm_user_time_ms); | 1363 X11DesktopHandler::get()->set_wm_user_time_ms(wm_user_time_ms); |
1364 } | 1364 } |
1365 } | 1365 } |
1366 | 1366 |
1367 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled, | 1367 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled, |
1368 ::Atom state1, | 1368 ::Atom state1, |
1369 ::Atom state2) { | 1369 ::Atom state2) { |
1370 XEvent xclient; | 1370 XEvent xclient; |
1371 memset(&xclient, 0, sizeof(xclient)); | 1371 memset(&xclient, 0, sizeof(xclient)); |
1372 xclient.type = ClientMessage; | 1372 xclient.type = ClientMessage; |
1373 xclient.xclient.window = xwindow_; | 1373 xclient.xclient.window = xwindow_; |
1374 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_WM_STATE"); | 1374 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_WM_STATE"); |
1375 xclient.xclient.format = 32; | 1375 xclient.xclient.format = 32; |
1376 xclient.xclient.data.l[0] = | 1376 xclient.xclient.data.l[0] = |
1377 enabled ? k_NET_WM_STATE_ADD : k_NET_WM_STATE_REMOVE; | 1377 enabled ? k_NET_WM_STATE_ADD : k_NET_WM_STATE_REMOVE; |
1378 xclient.xclient.data.l[1] = state1; | 1378 xclient.xclient.data.l[1] = state1; |
1379 xclient.xclient.data.l[2] = state2; | 1379 xclient.xclient.data.l[2] = state2; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1474 if (window_shape_) | 1474 if (window_shape_) |
1475 XDestroyRegion(window_shape_); | 1475 XDestroyRegion(window_shape_); |
1476 window_shape_ = NULL; | 1476 window_shape_ = NULL; |
1477 | 1477 |
1478 if (!IsMaximized() && !IsFullscreen()) { | 1478 if (!IsMaximized() && !IsFullscreen()) { |
1479 gfx::Path window_mask; | 1479 gfx::Path window_mask; |
1480 views::Widget* widget = native_widget_delegate_->AsWidget(); | 1480 views::Widget* widget = native_widget_delegate_->AsWidget(); |
1481 if (widget->non_client_view()) { | 1481 if (widget->non_client_view()) { |
1482 // Some frame views define a custom (non-rectangular) window mask. If | 1482 // Some frame views define a custom (non-rectangular) window mask. If |
1483 // so, use it to define the window shape. If not, fall through. | 1483 // so, use it to define the window shape. If not, fall through. |
1484 widget->non_client_view()->GetWindowMask(bounds_.size(), &window_mask); | 1484 widget->non_client_view()->GetWindowMask(bounds_in_pixels_.size(), |
| 1485 &window_mask); |
1485 if (window_mask.countPoints() > 0) { | 1486 if (window_mask.countPoints() > 0) { |
1486 window_shape_ = gfx::CreateRegionFromSkPath(window_mask); | 1487 window_shape_ = gfx::CreateRegionFromSkPath(window_mask); |
1487 XShapeCombineRegion(xdisplay_, xwindow_, ShapeBounding, | 1488 XShapeCombineRegion(xdisplay_, xwindow_, ShapeBounding, |
1488 0, 0, window_shape_, false); | 1489 0, 0, window_shape_, false); |
1489 return; | 1490 return; |
1490 } | 1491 } |
1491 } | 1492 } |
1492 } | 1493 } |
1493 | 1494 |
1494 // If we didn't set the shape for any reason, reset the shaping information. | 1495 // If we didn't set the shape for any reason, reset the shaping information. |
1495 // How this is done depends on the border style, due to quirks and bugs in | 1496 // How this is done depends on the border style, due to quirks and bugs in |
1496 // various window managers. | 1497 // various window managers. |
1497 if (ShouldUseNativeFrame()) { | 1498 if (ShouldUseNativeFrame()) { |
1498 // If the window has system borders, the mask must be set to null (not a | 1499 // If the window has system borders, the mask must be set to null (not a |
1499 // rectangle), because several window managers (eg, KDE, XFCE, XMonad) will | 1500 // rectangle), because several window managers (eg, KDE, XFCE, XMonad) will |
1500 // not put borders on a window with a custom shape. | 1501 // not put borders on a window with a custom shape. |
1501 XShapeCombineMask(xdisplay_, xwindow_, ShapeBounding, 0, 0, None, ShapeSet); | 1502 XShapeCombineMask(xdisplay_, xwindow_, ShapeBounding, 0, 0, None, ShapeSet); |
1502 } else { | 1503 } else { |
1503 // Conversely, if the window does not have system borders, the mask must be | 1504 // Conversely, if the window does not have system borders, the mask must be |
1504 // manually set to a rectangle that covers the whole window (not null). This | 1505 // manually set to a rectangle that covers the whole window (not null). This |
1505 // is due to a bug in KWin <= 4.11.5 (KDE bug #330573) where setting a null | 1506 // is due to a bug in KWin <= 4.11.5 (KDE bug #330573) where setting a null |
1506 // shape causes the hint to disable system borders to be ignored (resulting | 1507 // shape causes the hint to disable system borders to be ignored (resulting |
1507 // in a double border). | 1508 // in a double border). |
1508 XRectangle r = {0, 0, static_cast<unsigned short>(bounds_.width()), | 1509 XRectangle r = {0, |
1509 static_cast<unsigned short>(bounds_.height())}; | 1510 0, |
| 1511 static_cast<unsigned short>(bounds_in_pixels_.width()), |
| 1512 static_cast<unsigned short>(bounds_in_pixels_.height())}; |
1510 XShapeCombineRectangles( | 1513 XShapeCombineRectangles( |
1511 xdisplay_, xwindow_, ShapeBounding, 0, 0, &r, 1, ShapeSet, YXBanded); | 1514 xdisplay_, xwindow_, ShapeBounding, 0, 0, &r, 1, ShapeSet, YXBanded); |
1512 } | 1515 } |
1513 } | 1516 } |
1514 | 1517 |
1515 void DesktopWindowTreeHostX11::SerializeImageRepresentation( | 1518 void DesktopWindowTreeHostX11::SerializeImageRepresentation( |
1516 const gfx::ImageSkiaRep& rep, | 1519 const gfx::ImageSkiaRep& rep, |
1517 std::vector<unsigned long>* data) { | 1520 std::vector<unsigned long>* data) { |
1518 int width = rep.GetWidth(); | 1521 int width = rep.GetWidth(); |
1519 data->push_back(width); | 1522 data->push_back(width); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 show_state != ui::SHOW_STATE_INACTIVE && | 1577 show_state != ui::SHOW_STATE_INACTIVE && |
1575 show_state != ui::SHOW_STATE_MAXIMIZED) { | 1578 show_state != ui::SHOW_STATE_MAXIMIZED) { |
1576 // It will behave like SHOW_STATE_NORMAL. | 1579 // It will behave like SHOW_STATE_NORMAL. |
1577 NOTIMPLEMENTED(); | 1580 NOTIMPLEMENTED(); |
1578 } | 1581 } |
1579 | 1582 |
1580 // Before we map the window, set size hints. Otherwise, some window managers | 1583 // Before we map the window, set size hints. Otherwise, some window managers |
1581 // will ignore toplevel XMoveWindow commands. | 1584 // will ignore toplevel XMoveWindow commands. |
1582 XSizeHints size_hints; | 1585 XSizeHints size_hints; |
1583 size_hints.flags = PPosition; | 1586 size_hints.flags = PPosition; |
1584 size_hints.x = bounds_.x(); | 1587 size_hints.x = bounds_in_pixels_.x(); |
1585 size_hints.y = bounds_.y(); | 1588 size_hints.y = bounds_in_pixels_.y(); |
1586 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); | 1589 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); |
1587 | 1590 |
1588 // If SHOW_STATE_INACTIVE, tell the window manager not to focus the window | 1591 // If SHOW_STATE_INACTIVE, tell the window manager not to focus the window |
1589 // when mapping. This is done by setting the _NET_WM_USER_TIME to 0. See e.g. | 1592 // when mapping. This is done by setting the _NET_WM_USER_TIME to 0. See e.g. |
1590 // http://standards.freedesktop.org/wm-spec/latest/ar01s05.html | 1593 // http://standards.freedesktop.org/wm-spec/latest/ar01s05.html |
1591 unsigned long wm_user_time_ms = (show_state == ui::SHOW_STATE_INACTIVE) ? | 1594 unsigned long wm_user_time_ms = (show_state == ui::SHOW_STATE_INACTIVE) ? |
1592 0 : X11DesktopHandler::get()->wm_user_time_ms(); | 1595 0 : X11DesktopHandler::get()->wm_user_time_ms(); |
1593 if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) { | 1596 if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) { |
1594 XChangeProperty(xdisplay_, | 1597 XChangeProperty(xdisplay_, |
1595 xwindow_, | 1598 xwindow_, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1664 // TODO(pkotwicz|tdanderson): Figure out whether the suppression is | 1667 // TODO(pkotwicz|tdanderson): Figure out whether the suppression is |
1665 // necessary. crbug.com/385716 | 1668 // necessary. crbug.com/385716 |
1666 if (xev->xcrossing.detail == NotifyInferior) | 1669 if (xev->xcrossing.detail == NotifyInferior) |
1667 break; | 1670 break; |
1668 | 1671 |
1669 ui::MouseEvent mouse_event(xev); | 1672 ui::MouseEvent mouse_event(xev); |
1670 DispatchMouseEvent(&mouse_event); | 1673 DispatchMouseEvent(&mouse_event); |
1671 break; | 1674 break; |
1672 } | 1675 } |
1673 case Expose: { | 1676 case Expose: { |
1674 gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y, | 1677 gfx::Rect damage_rect_in_pixels(xev->xexpose.x, xev->xexpose.y, |
1675 xev->xexpose.width, xev->xexpose.height); | 1678 xev->xexpose.width, xev->xexpose.height); |
1676 compositor()->ScheduleRedrawRect(damage_rect); | 1679 compositor()->ScheduleRedrawRect(damage_rect_in_pixels); |
1677 break; | 1680 break; |
1678 } | 1681 } |
1679 case KeyPress: { | 1682 case KeyPress: { |
1680 ui::KeyEvent keydown_event(xev); | 1683 ui::KeyEvent keydown_event(xev); |
1681 SendEventToProcessor(&keydown_event); | 1684 SendEventToProcessor(&keydown_event); |
1682 break; | 1685 break; |
1683 } | 1686 } |
1684 case KeyRelease: { | 1687 case KeyRelease: { |
1685 // There is no way to deactivate a window in X11 so ignore input if | 1688 // There is no way to deactivate a window in X11 so ignore input if |
1686 // window is supposed to be 'inactive'. See comments in | 1689 // window is supposed to be 'inactive'. See comments in |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1726 break; | 1729 break; |
1727 case FocusIn: | 1730 case FocusIn: |
1728 X11DesktopHandler::get()->ProcessXEvent(xev); | 1731 X11DesktopHandler::get()->ProcessXEvent(xev); |
1729 break; | 1732 break; |
1730 case ConfigureNotify: { | 1733 case ConfigureNotify: { |
1731 DCHECK_EQ(xwindow_, xev->xconfigure.window); | 1734 DCHECK_EQ(xwindow_, xev->xconfigure.window); |
1732 DCHECK_EQ(xwindow_, xev->xconfigure.event); | 1735 DCHECK_EQ(xwindow_, xev->xconfigure.event); |
1733 // It's possible that the X window may be resized by some other means than | 1736 // It's possible that the X window may be resized by some other means than |
1734 // from within aura (e.g. the X window manager can change the size). Make | 1737 // from within aura (e.g. the X window manager can change the size). Make |
1735 // sure the root window size is maintained properly. | 1738 // sure the root window size is maintained properly. |
1736 int translated_x = xev->xconfigure.x; | 1739 int translated_x_in_pixels = xev->xconfigure.x; |
1737 int translated_y = xev->xconfigure.y; | 1740 int translated_y_in_pixels = xev->xconfigure.y; |
1738 if (!xev->xconfigure.send_event && !xev->xconfigure.override_redirect) { | 1741 if (!xev->xconfigure.send_event && !xev->xconfigure.override_redirect) { |
1739 Window unused; | 1742 Window unused; |
1740 XTranslateCoordinates(xdisplay_, xwindow_, x_root_window_, | 1743 XTranslateCoordinates(xdisplay_, xwindow_, x_root_window_, 0, 0, |
1741 0, 0, &translated_x, &translated_y, &unused); | 1744 &translated_x_in_pixels, &translated_y_in_pixels, |
| 1745 &unused); |
1742 } | 1746 } |
1743 gfx::Rect bounds(translated_x, translated_y, | 1747 gfx::Rect bounds_in_pixels(translated_x_in_pixels, translated_y_in_pixels, |
1744 xev->xconfigure.width, xev->xconfigure.height); | 1748 xev->xconfigure.width, xev->xconfigure.height); |
1745 bool size_changed = bounds_.size() != bounds.size(); | 1749 bool size_changed = bounds_in_pixels_.size() != bounds_in_pixels.size(); |
1746 bool origin_changed = bounds_.origin() != bounds.origin(); | 1750 bool origin_changed = |
1747 previous_bounds_ = bounds_; | 1751 bounds_in_pixels_.origin() != bounds_in_pixels.origin(); |
1748 bounds_ = bounds; | 1752 previous_bounds_in_pixels_ = bounds_in_pixels_; |
| 1753 bounds_in_pixels_ = bounds_in_pixels; |
1749 | 1754 |
1750 if (origin_changed) | 1755 if (origin_changed) |
1751 OnHostMoved(bounds_.origin()); | 1756 OnHostMoved(bounds_in_pixels_.origin()); |
1752 | 1757 |
1753 if (size_changed) { | 1758 if (size_changed) { |
1754 delayed_resize_task_.Reset(base::Bind( | 1759 delayed_resize_task_.Reset(base::Bind( |
1755 &DesktopWindowTreeHostX11::DelayedResize, | 1760 &DesktopWindowTreeHostX11::DelayedResize, |
1756 close_widget_factory_.GetWeakPtr(), | 1761 close_widget_factory_.GetWeakPtr(), bounds_in_pixels.size())); |
1757 bounds.size())); | |
1758 base::MessageLoop::current()->PostTask( | 1762 base::MessageLoop::current()->PostTask( |
1759 FROM_HERE, delayed_resize_task_.callback()); | 1763 FROM_HERE, delayed_resize_task_.callback()); |
1760 } | 1764 } |
1761 break; | 1765 break; |
1762 } | 1766 } |
1763 case GenericEvent: { | 1767 case GenericEvent: { |
1764 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | 1768 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); |
1765 if (!factory->ShouldProcessXI2Event(xev)) | 1769 if (!factory->ShouldProcessXI2Event(xev)) |
1766 break; | 1770 break; |
1767 | 1771 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1917 break; | 1921 break; |
1918 } | 1922 } |
1919 case SelectionNotify: { | 1923 case SelectionNotify: { |
1920 drag_drop_client_->OnSelectionNotify(xev->xselection); | 1924 drag_drop_client_->OnSelectionNotify(xev->xselection); |
1921 break; | 1925 break; |
1922 } | 1926 } |
1923 } | 1927 } |
1924 return ui::POST_DISPATCH_STOP_PROPAGATION; | 1928 return ui::POST_DISPATCH_STOP_PROPAGATION; |
1925 } | 1929 } |
1926 | 1930 |
1927 void DesktopWindowTreeHostX11::DelayedResize(const gfx::Size& size) { | 1931 void DesktopWindowTreeHostX11::DelayedResize(const gfx::Size& size_in_pixels) { |
1928 OnHostResized(size); | 1932 OnHostResized(size_in_pixels); |
1929 ResetWindowRegion(); | 1933 ResetWindowRegion(); |
1930 delayed_resize_task_.Cancel(); | 1934 delayed_resize_task_.Cancel(); |
1931 } | 1935 } |
1932 | 1936 |
| 1937 gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInPixels() const { |
| 1938 std::vector<int> value; |
| 1939 if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) && |
| 1940 value.size() >= 4) { |
| 1941 return gfx::Rect(value[0], value[1], value[2], value[3]); |
| 1942 } |
| 1943 |
| 1944 // Fetch the geometry of the root window. |
| 1945 Window root; |
| 1946 int x, y; |
| 1947 unsigned int width, height; |
| 1948 unsigned int border_width, depth; |
| 1949 if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y, &width, &height, |
| 1950 &border_width, &depth)) { |
| 1951 NOTIMPLEMENTED(); |
| 1952 return gfx::Rect(0, 0, 10, 10); |
| 1953 } |
| 1954 |
| 1955 return gfx::Rect(x, y, width, height); |
| 1956 } |
| 1957 |
| 1958 gfx::Rect DesktopWindowTreeHostX11::ToDIPRect( |
| 1959 const gfx::Rect& rect_in_pixels) const { |
| 1960 gfx::RectF rect_in_dip = rect_in_pixels; |
| 1961 GetRootTransform().TransformRectReverse(&rect_in_dip); |
| 1962 return gfx::ToEnclosingRect(rect_in_dip); |
| 1963 } |
| 1964 |
| 1965 gfx::Rect DesktopWindowTreeHostX11::ToPixelRect( |
| 1966 const gfx::Rect& rect_in_dip) const { |
| 1967 gfx::RectF rect_in_pixels = rect_in_dip; |
| 1968 GetRootTransform().TransformRect(&rect_in_pixels); |
| 1969 return gfx::ToEnclosingRect(rect_in_pixels); |
| 1970 } |
| 1971 |
1933 //////////////////////////////////////////////////////////////////////////////// | 1972 //////////////////////////////////////////////////////////////////////////////// |
1934 // DesktopWindowTreeHost, public: | 1973 // DesktopWindowTreeHost, public: |
1935 | 1974 |
1936 // static | 1975 // static |
1937 DesktopWindowTreeHost* DesktopWindowTreeHost::Create( | 1976 DesktopWindowTreeHost* DesktopWindowTreeHost::Create( |
1938 internal::NativeWidgetDelegate* native_widget_delegate, | 1977 internal::NativeWidgetDelegate* native_widget_delegate, |
1939 DesktopNativeWidgetAura* desktop_native_widget_aura) { | 1978 DesktopNativeWidgetAura* desktop_native_widget_aura) { |
1940 return new DesktopWindowTreeHostX11(native_widget_delegate, | 1979 return new DesktopWindowTreeHostX11(native_widget_delegate, |
1941 desktop_native_widget_aura); | 1980 desktop_native_widget_aura); |
1942 } | 1981 } |
1943 | 1982 |
1944 // static | 1983 // static |
1945 ui::NativeTheme* DesktopWindowTreeHost::GetNativeTheme(aura::Window* window) { | 1984 ui::NativeTheme* DesktopWindowTreeHost::GetNativeTheme(aura::Window* window) { |
1946 const views::LinuxUI* linux_ui = views::LinuxUI::instance(); | 1985 const views::LinuxUI* linux_ui = views::LinuxUI::instance(); |
1947 if (linux_ui) { | 1986 if (linux_ui) { |
1948 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); | 1987 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); |
1949 if (native_theme) | 1988 if (native_theme) |
1950 return native_theme; | 1989 return native_theme; |
1951 } | 1990 } |
1952 | 1991 |
1953 return ui::NativeTheme::instance(); | 1992 return ui::NativeTheme::instance(); |
1954 } | 1993 } |
1955 | 1994 |
1956 } // namespace views | 1995 } // namespace views |
OLD | NEW |