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 |