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 13 matching lines...) Expand all Loading... | |
| 24 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" | 24 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" |
| 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/event_utils.h" | 27 #include "ui/events/event_utils.h" |
| 28 #include "ui/events/platform/platform_event_source.h" | 28 #include "ui/events/platform/platform_event_source.h" |
| 29 #include "ui/events/platform/x11/x11_event_source.h" | 29 #include "ui/events/platform/x11/x11_event_source.h" |
| 30 #include "ui/events/x/device_data_manager_x11.h" | 30 #include "ui/events/x/device_data_manager_x11.h" |
| 31 #include "ui/events/x/device_list_cache_x.h" | 31 #include "ui/events/x/device_list_cache_x.h" |
| 32 #include "ui/events/x/touch_factory_x11.h" | 32 #include "ui/events/x/touch_factory_x11.h" |
| 33 #include "ui/gfx/display.h" | 33 #include "ui/gfx/display.h" |
| 34 #include "ui/gfx/geometry/size_conversions.h" | |
| 34 #include "ui/gfx/image/image_skia.h" | 35 #include "ui/gfx/image/image_skia.h" |
| 35 #include "ui/gfx/image/image_skia_rep.h" | 36 #include "ui/gfx/image/image_skia_rep.h" |
| 36 #include "ui/gfx/insets.h" | 37 #include "ui/gfx/insets.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" |
| 40 #include "ui/gfx/point.h" | |
| 39 #include "ui/gfx/screen.h" | 41 #include "ui/gfx/screen.h" |
| 42 #include "ui/gfx/size.h" | |
| 40 #include "ui/native_theme/native_theme.h" | 43 #include "ui/native_theme/native_theme.h" |
| 41 #include "ui/views/corewm/tooltip_aura.h" | 44 #include "ui/views/corewm/tooltip_aura.h" |
| 42 #include "ui/views/ime/input_method.h" | 45 #include "ui/views/ime/input_method.h" |
| 43 #include "ui/views/linux_ui/linux_ui.h" | 46 #include "ui/views/linux_ui/linux_ui.h" |
| 44 #include "ui/views/views_delegate.h" | 47 #include "ui/views/views_delegate.h" |
| 45 #include "ui/views/views_switches.h" | 48 #include "ui/views/views_switches.h" |
| 46 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" | 49 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" |
| 47 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" | 50 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" |
| 48 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" | 51 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
| 49 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h" | 52 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 "XdndPosition", | 119 "XdndPosition", |
| 117 "XdndProxy", // Proxy windows? | 120 "XdndProxy", // Proxy windows? |
| 118 "XdndSelection", | 121 "XdndSelection", |
| 119 "XdndStatus", | 122 "XdndStatus", |
| 120 "XdndTypeList", | 123 "XdndTypeList", |
| 121 NULL | 124 NULL |
| 122 }; | 125 }; |
| 123 | 126 |
| 124 } // namespace | 127 } // namespace |
| 125 | 128 |
| 129 float GetDeviceScaleFactor() { | |
| 130 gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); | |
| 131 return display.device_scale_factor(); | |
| 132 } | |
| 133 | |
| 134 gfx::Point ScreenToDIPPoint(const gfx::Point& pixel_point) { | |
| 135 return ToFlooredPoint(ScalePoint(pixel_point, 1.0f / GetDeviceScaleFactor())); | |
| 136 } | |
| 137 | |
| 138 gfx::Point DIPToScreenPoint(const gfx::Point& dip_point) { | |
| 139 return ToFlooredPoint(gfx::ScalePoint(dip_point, GetDeviceScaleFactor())); | |
| 140 } | |
| 141 | |
| 142 gfx::Size ScreenToDIPSize(const gfx::Size& size_in_pixels) { | |
| 143 // Always ceil sizes. Otherwise we may be leaving off part of the bounds. | |
| 144 return gfx::ToCeiledSize( | |
| 145 gfx::ScaleSize(size_in_pixels, 1.0f / GetDeviceScaleFactor())); | |
| 146 } | |
| 147 | |
| 148 gfx::Size DIPToScreenSize(const gfx::Size& dip_size) { | |
| 149 // Always ceil sizes. Otherwise we may be leaving off part of the bounds. | |
| 150 return gfx::ToCeiledSize(gfx::ScaleSize(dip_size, GetDeviceScaleFactor())); | |
| 151 } | |
| 152 | |
| 153 gfx::Rect DIPToScreenRect(const gfx::Rect& dip_bounds) { | |
| 154 // See comment in ScreenToDIPRect for why we calculate size like this. | |
| 155 return gfx::Rect(DIPToScreenPoint(dip_bounds.origin()), | |
| 156 DIPToScreenSize(dip_bounds.size())); | |
| 157 } | |
| 158 | |
| 159 gfx::Rect ScreenToDIPRect(const gfx::Rect& pixel_bounds) { | |
| 160 // It's important we scale the origin and size separately. If we instead | |
| 161 // calculated the size from the floored origin and ceiled right the size could | |
| 162 // vary depending upon where the two points land. That would cause problems | |
| 163 // for the places this code is used (in particular mapping from native window | |
| 164 // bounds to DIPs). | |
| 165 return gfx::Rect(ScreenToDIPPoint(pixel_bounds.origin()), | |
| 166 ScreenToDIPSize(pixel_bounds.size())); | |
| 167 } | |
| 168 | |
| 126 //////////////////////////////////////////////////////////////////////////////// | 169 //////////////////////////////////////////////////////////////////////////////// |
| 127 // DesktopWindowTreeHostX11, public: | 170 // DesktopWindowTreeHostX11, public: |
| 128 | 171 |
| 129 DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( | 172 DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( |
| 130 internal::NativeWidgetDelegate* native_widget_delegate, | 173 internal::NativeWidgetDelegate* native_widget_delegate, |
| 131 DesktopNativeWidgetAura* desktop_native_widget_aura) | 174 DesktopNativeWidgetAura* desktop_native_widget_aura) |
| 132 : xdisplay_(gfx::GetXDisplay()), | 175 : xdisplay_(gfx::GetXDisplay()), |
| 133 xwindow_(0), | 176 xwindow_(0), |
| 134 x_root_window_(DefaultRootWindow(xdisplay_)), | 177 x_root_window_(DefaultRootWindow(xdisplay_)), |
| 135 atom_cache_(xdisplay_, kAtomsToCache), | 178 atom_cache_(xdisplay_, kAtomsToCache), |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 378 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); | 421 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); |
| 379 // Enforce |restored_bounds_| since calling Maximize() could have reset it. | 422 // Enforce |restored_bounds_| since calling Maximize() could have reset it. |
| 380 restored_bounds_ = restored_bounds; | 423 restored_bounds_ = restored_bounds; |
| 381 } | 424 } |
| 382 | 425 |
| 383 bool DesktopWindowTreeHostX11::IsVisible() const { | 426 bool DesktopWindowTreeHostX11::IsVisible() const { |
| 384 return window_mapped_; | 427 return window_mapped_; |
| 385 } | 428 } |
| 386 | 429 |
| 387 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { | 430 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { |
| 388 gfx::Size size = AdjustSize(requested_size); | 431 gfx::Size size = AdjustSize(DIPToScreenSize(requested_size)); |
| 389 bool size_changed = bounds_.size() != size; | 432 bool size_changed = bounds_.size() != size; |
| 390 XResizeWindow(xdisplay_, xwindow_, size.width(), size.height()); | 433 XResizeWindow(xdisplay_, xwindow_, size.width(), size.height()); |
| 391 bounds_.set_size(size); | 434 bounds_.set_size(size); |
| 392 if (size_changed) { | 435 if (size_changed) { |
| 393 OnHostResized(size); | 436 OnHostResized(size); |
| 394 ResetWindowRegion(); | 437 ResetWindowRegion(); |
| 395 } | 438 } |
| 396 } | 439 } |
| 397 | 440 |
| 398 void DesktopWindowTreeHostX11::StackAtTop() { | 441 void DesktopWindowTreeHostX11::StackAtTop() { |
| 399 XRaiseWindow(xdisplay_, xwindow_); | 442 XRaiseWindow(xdisplay_, xwindow_); |
| 400 } | 443 } |
| 401 | 444 |
| 402 void DesktopWindowTreeHostX11::CenterWindow(const gfx::Size& size) { | 445 void DesktopWindowTreeHostX11::CenterWindow(const gfx::Size& size_dip) { |
| 403 gfx::Rect parent_bounds = GetWorkAreaBoundsInScreen(); | 446 gfx::Rect parent_bounds = GetWorkAreaBoundsInScreen(); |
| 404 | 447 |
| 448 gfx::Size size = DIPToScreenSize(size_dip); | |
| 449 | |
| 405 // If |window_|'s transient parent bounds are big enough to contain |size|, | 450 // If |window_|'s transient parent bounds are big enough to contain |size|, |
| 406 // use them instead. | 451 // use them instead. |
| 407 if (wm::GetTransientParent(content_window_)) { | 452 if (wm::GetTransientParent(content_window_)) { |
| 408 gfx::Rect transient_parent_rect = | 453 gfx::Rect transient_parent_rect = |
| 409 wm::GetTransientParent(content_window_)->GetBoundsInScreen(); | 454 wm::GetTransientParent(content_window_)->GetBoundsInScreen(); |
| 410 if (transient_parent_rect.height() >= size.height() && | 455 if (transient_parent_rect.height() >= size.height() && |
| 411 transient_parent_rect.width() >= size.width()) { | 456 transient_parent_rect.width() >= size.width()) { |
| 412 parent_bounds = transient_parent_rect; | 457 parent_bounds = transient_parent_rect; |
| 413 } | 458 } |
| 414 } | 459 } |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 437 } else if (IsMaximized()) { | 482 } else if (IsMaximized()) { |
| 438 *show_state = ui::SHOW_STATE_MAXIMIZED; | 483 *show_state = ui::SHOW_STATE_MAXIMIZED; |
| 439 } else if (!IsActive()) { | 484 } else if (!IsActive()) { |
| 440 *show_state = ui::SHOW_STATE_INACTIVE; | 485 *show_state = ui::SHOW_STATE_INACTIVE; |
| 441 } else { | 486 } else { |
| 442 *show_state = ui::SHOW_STATE_NORMAL; | 487 *show_state = ui::SHOW_STATE_NORMAL; |
| 443 } | 488 } |
| 444 } | 489 } |
| 445 | 490 |
| 446 gfx::Rect DesktopWindowTreeHostX11::GetWindowBoundsInScreen() const { | 491 gfx::Rect DesktopWindowTreeHostX11::GetWindowBoundsInScreen() const { |
| 447 return bounds_; | 492 return ScreenToDIPRect(bounds_); |
| 448 } | 493 } |
| 449 | 494 |
| 450 gfx::Rect DesktopWindowTreeHostX11::GetClientAreaBoundsInScreen() const { | 495 gfx::Rect DesktopWindowTreeHostX11::GetClientAreaBoundsInScreen() const { |
| 451 // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its | 496 // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its |
| 452 // needed for View::ConvertPointToScreen() to work | 497 // needed for View::ConvertPointToScreen() to work |
| 453 // correctly. DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just | 498 // correctly. DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just |
| 454 // asks windows what it thinks the client rect is. | 499 // asks windows what it thinks the client rect is. |
| 455 // | 500 // |
| 456 // Attempts to calculate the rect by asking the NonClientFrameView what it | 501 // Attempts to calculate the rect by asking the NonClientFrameView what it |
| 457 // thought its GetBoundsForClientView() were broke combobox drop down | 502 // thought its GetBoundsForClientView() were broke combobox drop down |
| 458 // placement. | 503 // placement. |
| 459 return bounds_; | 504 return ScreenToDIPRect(bounds_); |
| 460 } | 505 } |
| 461 | 506 |
| 462 gfx::Rect DesktopWindowTreeHostX11::GetRestoredBounds() const { | 507 gfx::Rect DesktopWindowTreeHostX11::GetRestoredBounds() const { |
| 463 // We can't reliably track the restored bounds of a window, but we can get | 508 // We can't reliably track the restored bounds of a window, but we can get |
| 464 // the 90% case down. When *chrome* is the process that requests maximizing | 509 // the 90% case down. When *chrome* is the process that requests maximizing |
| 465 // or restoring bounds, we can record the current bounds before we request | 510 // or restoring bounds, we can record the current bounds before we request |
| 466 // maximization, and clear it when we detect a state change. | 511 // maximization, and clear it when we detect a state change. |
| 467 if (!restored_bounds_.IsEmpty()) | 512 if (!restored_bounds_.IsEmpty()) |
| 468 return restored_bounds_; | 513 return ScreenToDIPRect(restored_bounds_); |
| 469 | 514 |
| 470 return GetWindowBoundsInScreen(); | 515 return GetWindowBoundsInScreen(); |
| 471 } | 516 } |
| 472 | 517 |
| 473 gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInScreen() const { | 518 gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInScreen() const { |
| 474 std::vector<int> value; | 519 std::vector<int> value; |
| 475 if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) && | 520 if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) && |
| 476 value.size() >= 4) { | 521 value.size() >= 4) { |
| 477 return gfx::Rect(value[0], value[1], value[2], value[3]); | 522 return ScreenToDIPRect(gfx::Rect(value[0], value[1], value[2], value[3])); |
| 478 } | 523 } |
| 479 | 524 |
| 480 // Fetch the geometry of the root window. | 525 // Fetch the geometry of the root window. |
| 481 Window root; | 526 Window root; |
| 482 int x, y; | 527 int x, y; |
| 483 unsigned int width, height; | 528 unsigned int width, height; |
| 484 unsigned int border_width, depth; | 529 unsigned int border_width, depth; |
| 485 if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y, | 530 if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y, |
| 486 &width, &height, &border_width, &depth)) { | 531 &width, &height, &border_width, &depth)) { |
| 487 NOTIMPLEMENTED(); | 532 NOTIMPLEMENTED(); |
| 488 return gfx::Rect(0, 0, 10, 10); | 533 return gfx::Rect(0, 0, 10, 10); |
| 489 } | 534 } |
| 490 | 535 |
| 491 return gfx::Rect(x, y, width, height); | 536 return ScreenToDIPRect(gfx::Rect(x, y, width, height)); |
|
Elliot Glaysher
2014/10/16 00:27:40
So bounds in screen are also dips?
scottmg
2014/10/17 00:09:11
Yeah, that's confusing, but that one's Screen/Clie
| |
| 492 } | 537 } |
| 493 | 538 |
| 494 void DesktopWindowTreeHostX11::SetShape(gfx::NativeRegion native_region) { | 539 void DesktopWindowTreeHostX11::SetShape(gfx::NativeRegion native_region) { |
| 495 if (window_shape_) | 540 if (window_shape_) |
| 496 XDestroyRegion(window_shape_); | 541 XDestroyRegion(window_shape_); |
| 497 custom_window_shape_ = false; | 542 custom_window_shape_ = false; |
| 498 window_shape_ = NULL; | 543 window_shape_ = NULL; |
| 499 | 544 |
| 500 if (native_region) { | 545 if (native_region) { |
| 501 custom_window_shape_ = true; | 546 custom_window_shape_ = true; |
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1079 | 1124 |
| 1080 // x.org will BadMatch if we don't set a border when the depth isn't the | 1125 // x.org will BadMatch if we don't set a border when the depth isn't the |
| 1081 // same as the parent depth. | 1126 // same as the parent depth. |
| 1082 attribute_mask |= CWBorderPixel; | 1127 attribute_mask |= CWBorderPixel; |
| 1083 swa.border_pixel = 0; | 1128 swa.border_pixel = 0; |
| 1084 | 1129 |
| 1085 use_argb_visual_ = true; | 1130 use_argb_visual_ = true; |
| 1086 } | 1131 } |
| 1087 } | 1132 } |
| 1088 | 1133 |
| 1089 bounds_ = gfx::Rect(params.bounds.origin(), | 1134 gfx::Point origin_screen = DIPToScreenPoint(params.bounds.origin()); |
| 1090 AdjustSize(params.bounds.size())); | 1135 gfx::Size size_screen = DIPToScreenSize(params.bounds.size()); |
| 1136 bounds_ = gfx::Rect(origin_screen, | |
| 1137 AdjustSize(size_screen)); | |
| 1091 xwindow_ = XCreateWindow( | 1138 xwindow_ = XCreateWindow( |
| 1092 xdisplay_, x_root_window_, | 1139 xdisplay_, x_root_window_, |
| 1093 bounds_.x(), bounds_.y(), | 1140 origin_screen.x(), origin_screen.y(), |
| 1094 bounds_.width(), bounds_.height(), | 1141 size_screen.width(), size_screen.height(), |
| 1095 0, // border width | 1142 0, // border width |
| 1096 depth, | 1143 depth, |
| 1097 InputOutput, | 1144 InputOutput, |
| 1098 visual, | 1145 visual, |
| 1099 attribute_mask, | 1146 attribute_mask, |
| 1100 &swa); | 1147 &swa); |
| 1101 if (ui::PlatformEventSource::GetInstance()) | 1148 if (ui::PlatformEventSource::GetInstance()) |
| 1102 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); | 1149 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); |
| 1103 open_windows().push_back(xwindow_); | 1150 open_windows().push_back(xwindow_); |
| 1104 | 1151 |
| (...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1943 if (linux_ui) { | 1990 if (linux_ui) { |
| 1944 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); | 1991 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); |
| 1945 if (native_theme) | 1992 if (native_theme) |
| 1946 return native_theme; | 1993 return native_theme; |
| 1947 } | 1994 } |
| 1948 | 1995 |
| 1949 return ui::NativeTheme::instance(); | 1996 return ui::NativeTheme::instance(); |
| 1950 } | 1997 } |
| 1951 | 1998 |
| 1952 } // namespace views | 1999 } // namespace views |
| OLD | NEW |