Chromium Code Reviews| 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 |
| 411 // use them instead. | 416 // |size_in_pixels|, 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_in_pixels.height() && |
| 416 transient_parent_rect.width() >= size.width()) { | 421 transient_parent_rect.width() >= size_in_pixels.width()) { |
|
pkotwicz
2015/02/19 03:07:20
You meant to compare against |size| not |size_in_p
sadrul
2015/02/24 00:11:27
Good catch. Done.
| |
| 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( |
| 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.AdjustToFit(parent_bounds_in_pixels); |
|
pkotwicz
2015/02/19 03:07:20
window_bounds -> window_bounds_in_pixels
sadrul
2015/02/24 00:11:28
Done.
| |
| 429 | 435 |
| 430 SetBounds(window_bounds); | 436 SetBounds(window_bounds); |
| 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) { |
|
pkotwicz
2015/02/19 03:07:20
|native_region| is in "DIP" coordinates. I quickly
| |
| 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; |
| 507 window_shape_ = gfx::CreateRegionFromSkRegion(*native_region); | 496 window_shape_ = gfx::CreateRegionFromSkRegion(*native_region); |
| 508 delete native_region; | 497 delete native_region; |
| 509 } | 498 } |
| (...skipping 22 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(bounds_in_pixels_.origin(), |
| 543 if (adjusted_bounds != bounds_) | 532 AdjustSize(bounds_in_pixels_.size())); |
|
pkotwicz
2015/02/19 03:07:20
adjusted_bounds -> adjusted_bounds_in_pixels
sadrul
2015/02/24 00:11:28
Done.
| |
| 533 if (adjusted_bounds != bounds_in_pixels_) | |
| 544 SetBounds(adjusted_bounds); | 534 SetBounds(adjusted_bounds); |
| 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); | |
|
pkotwicz
2015/02/19 03:07:20
Nit: Why bother? We are going to use the scale fac
sadrul
2015/02/24 00:11:28
It makes sense to use the DSF of the display this
| |
| 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(requested_bounds_in_pixel.origin(), |
| 893 bool origin_changed = bounds_.origin() != bounds.origin(); | 896 AdjustSize(requested_bounds_in_pixel.size())); |
|
pkotwicz
2015/02/19 03:07:20
bounds -> bounds_in_pixels
sadrul
2015/02/24 00:11:27
Done.
| |
| 894 bool size_changed = bounds_.size() != bounds.size(); | 897 bool origin_changed = bounds_in_pixels_.origin() != bounds.origin(); |
| 898 bool size_changed = bounds_in_pixels_.size() != bounds.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.width() < min_size_in_pixels_.width() || |
| 900 bounds.height() < min_size_.height() || | 904 bounds.height() < min_size_in_pixels_.height() || |
| 901 (!max_size_.IsEmpty() && | 905 (!max_size_in_pixels_.IsEmpty() && |
| 902 (bounds.width() > max_size_.width() || | 906 (bounds.width() > max_size_in_pixels_.width() || |
| 903 bounds.height() > max_size_.height()))) { | 907 bounds.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 = bounds.size(); |
|
pkotwicz
2015/02/19 03:07:20
size -> size_in_pixels
sadrul
2015/02/24 00:11:27
Done.
| |
| 908 size.SetToMin(max_size_); | 912 size.SetToMin(max_size_in_pixels_); |
| 909 size.SetToMax(min_size_); | 913 size.SetToMax(min_size_in_pixels_); |
| 910 bounds.set_size(size); | 914 bounds.set_size(size); |
| 911 } | 915 } |
| 912 | 916 |
| 913 changes.width = bounds.width(); | 917 changes.width = bounds.width(); |
| 914 changes.height = bounds.height(); | 918 changes.height = bounds.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.x(); |
| 920 changes.y = bounds.y(); | 924 changes.y = bounds.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; |
| 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.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_ = gfx::Rect(bounds_in_pixels_.origin(), |
| 1063 xwindow_ = XCreateWindow( | 1068 AdjustSize(bounds_in_pixels_.size())); |
|
pkotwicz
2015/02/19 03:07:20
Nit: bounds_in_pixels_.set_size(AdjustSize(bounds_
sadrul
2015/02/24 00:11:28
Done.
| |
| 1064 xdisplay_, x_root_window_, | 1069 xwindow_ = XCreateWindow(xdisplay_, x_root_window_, bounds_in_pixels_.x(), |
| 1065 bounds_.x(), bounds_.y(), | 1070 bounds_in_pixels_.y(), bounds_in_pixels_.width(), |
| 1066 bounds_.width(), bounds_.height(), | 1071 bounds_in_pixels_.height(), |
| 1067 0, // border width | 1072 0, // border width |
| 1068 depth, | 1073 depth, InputOutput, visual, attribute_mask, &swa); |
| 1069 InputOutput, | |
| 1070 visual, | |
| 1071 attribute_mask, | |
| 1072 &swa); | |
| 1073 if (ui::PlatformEventSource::GetInstance()) | 1074 if (ui::PlatformEventSource::GetInstance()) |
| 1074 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); | 1075 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); |
| 1075 open_windows().push_back(xwindow_); | 1076 open_windows().push_back(xwindow_); |
| 1076 | 1077 |
| 1077 // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL(). | 1078 // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL(). |
| 1078 | 1079 |
| 1079 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | | 1080 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | |
| 1080 KeyPressMask | KeyReleaseMask | | 1081 KeyPressMask | KeyReleaseMask | |
| 1081 EnterWindowMask | LeaveWindowMask | | 1082 EnterWindowMask | LeaveWindowMask | |
| 1082 ExposureMask | VisibilityChangeMask | | 1083 ExposureMask | VisibilityChangeMask | |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1201 // icon. | 1202 // icon. |
| 1202 gfx::ImageSkia* window_icon = ViewsDelegate::views_delegate ? | 1203 gfx::ImageSkia* window_icon = ViewsDelegate::views_delegate ? |
| 1203 ViewsDelegate::views_delegate->GetDefaultWindowIcon() : NULL; | 1204 ViewsDelegate::views_delegate->GetDefaultWindowIcon() : NULL; |
| 1204 if (window_icon) { | 1205 if (window_icon) { |
| 1205 SetWindowIcons(gfx::ImageSkia(), *window_icon); | 1206 SetWindowIcons(gfx::ImageSkia(), *window_icon); |
| 1206 } | 1207 } |
| 1207 CreateCompositor(GetAcceleratedWidget()); | 1208 CreateCompositor(GetAcceleratedWidget()); |
| 1208 } | 1209 } |
| 1209 | 1210 |
| 1210 gfx::Size DesktopWindowTreeHostX11::AdjustSize( | 1211 gfx::Size DesktopWindowTreeHostX11::AdjustSize( |
| 1211 const gfx::Size& requested_size) { | 1212 const gfx::Size& requested_size_in_pixels) { |
| 1212 std::vector<gfx::Display> displays = | 1213 std::vector<gfx::Display> displays = |
| 1213 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)->GetAllDisplays(); | 1214 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)->GetAllDisplays(); |
| 1214 // Compare against all monitor sizes. The window manager can move the window | 1215 // Compare against all monitor sizes. The window manager can move the window |
| 1215 // to whichever monitor it wants. | 1216 // to whichever monitor it wants. |
| 1216 for (size_t i = 0; i < displays.size(); ++i) { | 1217 for (size_t i = 0; i < displays.size(); ++i) { |
| 1217 if (requested_size == displays[i].size()) { | 1218 if (requested_size_in_pixels == displays[i].GetSizeInPixel()) { |
| 1218 return gfx::Size(requested_size.width() - 1, | 1219 return gfx::Size(requested_size_in_pixels.width() - 1, |
| 1219 requested_size.height() - 1); | 1220 requested_size_in_pixels.height() - 1); |
| 1220 } | 1221 } |
| 1221 } | 1222 } |
| 1222 | 1223 |
| 1223 // Do not request a 0x0 window size. It causes an XError. | 1224 // Do not request a 0x0 window size. It causes an XError. |
| 1224 gfx::Size size = requested_size; | 1225 gfx::Size size = requested_size_in_pixels; |
|
pkotwicz
2015/02/19 03:07:20
size -> size_in_pixels
sadrul
2015/02/24 00:11:28
Done.
| |
| 1225 size.SetToMax(gfx::Size(1,1)); | 1226 size.SetToMax(gfx::Size(1,1)); |
| 1226 return size; | 1227 return size; |
| 1227 } | 1228 } |
| 1228 | 1229 |
| 1229 void DesktopWindowTreeHostX11::OnWMStateUpdated() { | 1230 void DesktopWindowTreeHostX11::OnWMStateUpdated() { |
| 1230 std::vector< ::Atom> atom_list; | 1231 std::vector< ::Atom> atom_list; |
| 1231 // Ignore the return value of ui::GetAtomArrayProperty(). Fluxbox removes the | 1232 // Ignore the return value of ui::GetAtomArrayProperty(). Fluxbox removes the |
| 1232 // _NET_WM_STATE property when no _NET_WM_STATE atoms are set. | 1233 // _NET_WM_STATE property when no _NET_WM_STATE atoms are set. |
| 1233 ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list); | 1234 ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list); |
| 1234 | 1235 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1254 if (is_minimized != was_minimized) { | 1255 if (is_minimized != was_minimized) { |
| 1255 if (is_minimized) { | 1256 if (is_minimized) { |
| 1256 compositor()->SetVisible(false); | 1257 compositor()->SetVisible(false); |
| 1257 content_window_->Hide(); | 1258 content_window_->Hide(); |
| 1258 } else { | 1259 } else { |
| 1259 content_window_->Show(); | 1260 content_window_->Show(); |
| 1260 compositor()->SetVisible(true); | 1261 compositor()->SetVisible(true); |
| 1261 } | 1262 } |
| 1262 } | 1263 } |
| 1263 | 1264 |
| 1264 if (restored_bounds_.IsEmpty()) { | 1265 if (restored_bounds_in_pixels_.IsEmpty()) { |
| 1265 DCHECK(!IsFullscreen()); | 1266 DCHECK(!IsFullscreen()); |
| 1266 if (IsMaximized()) { | 1267 if (IsMaximized()) { |
| 1267 // The request that we become maximized originated from a different | 1268 // The request that we become maximized originated from a different |
| 1268 // process. |bounds_| already contains our maximized bounds. Do a best | 1269 // process. |bounds_in_pixels_| already contains our maximized bounds. Do |
| 1269 // effort attempt to get restored bounds by setting it to our previously | 1270 // 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 | 1271 // previously set bounds (and if we get this wrong, we aren't any worse |
| 1271 // we'd otherwise be returning our maximized bounds). | 1272 // off since we'd otherwise be returning our maximized bounds). |
| 1272 restored_bounds_ = previous_bounds_; | 1273 restored_bounds_in_pixels_ = previous_bounds_in_pixels_; |
| 1273 } | 1274 } |
| 1274 } else if (!IsMaximized() && !IsFullscreen()) { | 1275 } else if (!IsMaximized() && !IsFullscreen()) { |
| 1275 // If we have restored bounds, but WM_STATE no longer claims to be | 1276 // If we have restored bounds, but WM_STATE no longer claims to be |
| 1276 // maximized or fullscreen, we should clear our restored bounds. | 1277 // maximized or fullscreen, we should clear our restored bounds. |
| 1277 restored_bounds_ = gfx::Rect(); | 1278 restored_bounds_in_pixels_ = gfx::Rect(); |
| 1278 } | 1279 } |
| 1279 | 1280 |
| 1280 // Ignore requests by the window manager to enter or exit fullscreen (e.g. as | 1281 // 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 | 1282 // a result of pressing a window manager accelerator key). Chrome does not |
| 1282 // handle window manager initiated fullscreen. In particular, Chrome needs to | 1283 // handle window manager initiated fullscreen. In particular, Chrome needs to |
| 1283 // do preprocessing before the x window's fullscreen state is toggled. | 1284 // do preprocessing before the x window's fullscreen state is toggled. |
| 1284 | 1285 |
| 1285 is_always_on_top_ = HasWMSpecProperty("_NET_WM_STATE_ABOVE"); | 1286 is_always_on_top_ = HasWMSpecProperty("_NET_WM_STATE_ABOVE"); |
| 1286 | 1287 |
| 1287 // Now that we have different window properties, we may need to relayout the | 1288 // 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 | 1289 // window. (The windows code doesn't need this because their window change is |
| 1289 // synchronous.) | 1290 // synchronous.) |
| 1290 Relayout(); | 1291 Relayout(); |
| 1291 ResetWindowRegion(); | 1292 ResetWindowRegion(); |
| 1292 } | 1293 } |
| 1293 | 1294 |
| 1294 void DesktopWindowTreeHostX11::OnFrameExtentsUpdated() { | 1295 void DesktopWindowTreeHostX11::OnFrameExtentsUpdated() { |
| 1295 std::vector<int> insets; | 1296 std::vector<int> insets; |
| 1296 if (ui::GetIntArrayProperty(xwindow_, "_NET_FRAME_EXTENTS", &insets) && | 1297 if (ui::GetIntArrayProperty(xwindow_, "_NET_FRAME_EXTENTS", &insets) && |
| 1297 insets.size() == 4) { | 1298 insets.size() == 4) { |
| 1298 // |insets| are returned in the order: [left, right, top, bottom]. | 1299 // |insets| are returned in the order: [left, right, top, bottom]. |
| 1299 native_window_frame_borders_ = gfx::Insets( | 1300 native_window_frame_borders_in_pixels_ = |
| 1300 insets[2], | 1301 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); |
| 1301 insets[0], | |
| 1302 insets[3], | |
| 1303 insets[1]); | |
| 1304 } else { | 1302 } else { |
| 1305 native_window_frame_borders_ = gfx::Insets(); | 1303 native_window_frame_borders_in_pixels_ = gfx::Insets(); |
| 1306 } | 1304 } |
| 1307 } | 1305 } |
| 1308 | 1306 |
| 1309 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { | 1307 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { |
| 1310 if (!window_mapped_) | 1308 if (!window_mapped_) |
| 1311 return; | 1309 return; |
| 1312 | 1310 |
| 1313 gfx::Size minimum = native_widget_delegate_->GetMinimumSize(); | 1311 gfx::Size minimum = |
| 1314 gfx::Size maximum = native_widget_delegate_->GetMaximumSize(); | 1312 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); |
| 1315 if (min_size_ == minimum && max_size_ == maximum) | 1313 gfx::Size maximum = |
| 1314 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); | |
|
pkotwicz
2015/02/19 03:07:20
minimum -> minimum_in_pixels
maximum -> maximum_in
sadrul
2015/02/24 00:11:27
Done.
| |
| 1315 if (min_size_in_pixels_ == minimum && max_size_in_pixels_ == maximum) | |
| 1316 return; | 1316 return; |
| 1317 | 1317 |
| 1318 min_size_ = minimum; | 1318 min_size_in_pixels_ = minimum; |
| 1319 max_size_ = maximum; | 1319 max_size_in_pixels_ = maximum; |
| 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.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.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 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 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) { |
|
pkotwicz
2015/02/19 03:07:20
Nit: Can you please fix the alignment here?
sadrul
2015/02/24 00:11:27
Done.
| |
| 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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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(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); |
|
pkotwicz
2015/02/19 03:07:20
damage_rect -> damage_rect_in_pixels
sadrul
2015/02/24 00:11:27
Done.
| |
| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 = xev->xconfigure.x; |
| 1737 int translated_y = xev->xconfigure.y; | 1740 int translated_y = 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_, |
| 1741 0, 0, &translated_x, &translated_y, &unused); | 1744 0, 0, &translated_x, &translated_y, &unused); |
| 1742 } | 1745 } |
| 1743 gfx::Rect bounds(translated_x, translated_y, | 1746 gfx::Rect bounds(translated_x, translated_y, |
|
pkotwicz
2015/02/19 03:07:20
bounds -> bounds_in_pixels
translated_x -> transla
sadrul
2015/02/24 00:11:27
Done.
| |
| 1744 xev->xconfigure.width, xev->xconfigure.height); | 1747 xev->xconfigure.width, xev->xconfigure.height); |
| 1745 bool size_changed = bounds_.size() != bounds.size(); | 1748 bool size_changed = bounds_in_pixels_.size() != bounds.size(); |
| 1746 bool origin_changed = bounds_.origin() != bounds.origin(); | 1749 bool origin_changed = bounds_in_pixels_.origin() != bounds.origin(); |
| 1747 previous_bounds_ = bounds_; | 1750 previous_bounds_in_pixels_ = bounds_in_pixels_; |
| 1748 bounds_ = bounds; | 1751 bounds_in_pixels_ = bounds; |
| 1749 | 1752 |
| 1750 if (origin_changed) | 1753 if (origin_changed) |
| 1751 OnHostMoved(bounds_.origin()); | 1754 OnHostMoved(bounds_in_pixels_.origin()); |
| 1752 | 1755 |
| 1753 if (size_changed) { | 1756 if (size_changed) { |
| 1754 delayed_resize_task_.Reset(base::Bind( | 1757 delayed_resize_task_.Reset(base::Bind( |
| 1755 &DesktopWindowTreeHostX11::DelayedResize, | 1758 &DesktopWindowTreeHostX11::DelayedResize, |
| 1756 close_widget_factory_.GetWeakPtr(), | 1759 close_widget_factory_.GetWeakPtr(), |
| 1757 bounds.size())); | 1760 bounds.size())); |
| 1758 base::MessageLoop::current()->PostTask( | 1761 base::MessageLoop::current()->PostTask( |
| 1759 FROM_HERE, delayed_resize_task_.callback()); | 1762 FROM_HERE, delayed_resize_task_.callback()); |
| 1760 } | 1763 } |
| 1761 break; | 1764 break; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1917 break; | 1920 break; |
| 1918 } | 1921 } |
| 1919 case SelectionNotify: { | 1922 case SelectionNotify: { |
| 1920 drag_drop_client_->OnSelectionNotify(xev->xselection); | 1923 drag_drop_client_->OnSelectionNotify(xev->xselection); |
| 1921 break; | 1924 break; |
| 1922 } | 1925 } |
| 1923 } | 1926 } |
| 1924 return ui::POST_DISPATCH_STOP_PROPAGATION; | 1927 return ui::POST_DISPATCH_STOP_PROPAGATION; |
| 1925 } | 1928 } |
| 1926 | 1929 |
| 1927 void DesktopWindowTreeHostX11::DelayedResize(const gfx::Size& size) { | 1930 void DesktopWindowTreeHostX11::DelayedResize(const gfx::Size& size) { |
|
pkotwicz
2015/02/19 03:07:20
size -> size_in_pixels
sadrul
2015/02/24 00:11:27
Done.
| |
| 1928 OnHostResized(size); | 1931 OnHostResized(size); |
| 1929 ResetWindowRegion(); | 1932 ResetWindowRegion(); |
| 1930 delayed_resize_task_.Cancel(); | 1933 delayed_resize_task_.Cancel(); |
| 1931 } | 1934 } |
| 1932 | 1935 |
| 1936 gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInPixels() const { | |
| 1937 std::vector<int> value; | |
| 1938 if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) && | |
| 1939 value.size() >= 4) { | |
| 1940 return gfx::Rect(value[0], value[1], value[2], value[3]); | |
| 1941 } | |
| 1942 | |
| 1943 // Fetch the geometry of the root window. | |
| 1944 Window root; | |
| 1945 int x, y; | |
| 1946 unsigned int width, height; | |
| 1947 unsigned int border_width, depth; | |
| 1948 if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y, &width, &height, | |
| 1949 &border_width, &depth)) { | |
| 1950 NOTIMPLEMENTED(); | |
| 1951 return gfx::Rect(0, 0, 10, 10); | |
| 1952 } | |
| 1953 | |
| 1954 return gfx::Rect(x, y, width, height); | |
| 1955 } | |
| 1956 | |
| 1957 gfx::Rect DesktopWindowTreeHostX11::ToDIPRect( | |
| 1958 const gfx::Rect& rect_in_pixels) const { | |
| 1959 gfx::RectF rect_in_dip = rect_in_pixels; | |
| 1960 GetRootTransform().TransformRectReverse(&rect_in_dip); | |
| 1961 return gfx::ToEnclosingRect(rect_in_dip); | |
| 1962 } | |
| 1963 | |
| 1964 gfx::Rect DesktopWindowTreeHostX11::ToPixelRect( | |
| 1965 const gfx::Rect& rect_in_dip) const { | |
| 1966 gfx::RectF rect_in_pixels = rect_in_dip; | |
| 1967 GetRootTransform().TransformRect(&rect_in_pixels); | |
| 1968 return gfx::ToEnclosingRect(rect_in_pixels); | |
| 1969 } | |
| 1970 | |
| 1933 //////////////////////////////////////////////////////////////////////////////// | 1971 //////////////////////////////////////////////////////////////////////////////// |
| 1934 // DesktopWindowTreeHost, public: | 1972 // DesktopWindowTreeHost, public: |
| 1935 | 1973 |
| 1936 // static | 1974 // static |
| 1937 DesktopWindowTreeHost* DesktopWindowTreeHost::Create( | 1975 DesktopWindowTreeHost* DesktopWindowTreeHost::Create( |
| 1938 internal::NativeWidgetDelegate* native_widget_delegate, | 1976 internal::NativeWidgetDelegate* native_widget_delegate, |
| 1939 DesktopNativeWidgetAura* desktop_native_widget_aura) { | 1977 DesktopNativeWidgetAura* desktop_native_widget_aura) { |
| 1940 return new DesktopWindowTreeHostX11(native_widget_delegate, | 1978 return new DesktopWindowTreeHostX11(native_widget_delegate, |
| 1941 desktop_native_widget_aura); | 1979 desktop_native_widget_aura); |
| 1942 } | 1980 } |
| 1943 | 1981 |
| 1944 // static | 1982 // static |
| 1945 ui::NativeTheme* DesktopWindowTreeHost::GetNativeTheme(aura::Window* window) { | 1983 ui::NativeTheme* DesktopWindowTreeHost::GetNativeTheme(aura::Window* window) { |
| 1946 const views::LinuxUI* linux_ui = views::LinuxUI::instance(); | 1984 const views::LinuxUI* linux_ui = views::LinuxUI::instance(); |
| 1947 if (linux_ui) { | 1985 if (linux_ui) { |
| 1948 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); | 1986 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); |
| 1949 if (native_theme) | 1987 if (native_theme) |
| 1950 return native_theme; | 1988 return native_theme; |
| 1951 } | 1989 } |
| 1952 | 1990 |
| 1953 return ui::NativeTheme::instance(); | 1991 return ui::NativeTheme::instance(); |
| 1954 } | 1992 } |
| 1955 | 1993 |
| 1956 } // namespace views | 1994 } // namespace views |
| OLD | NEW |