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/dpi.h" |
| 35 #include "ui/gfx/geometry/size_conversions.h" |
34 #include "ui/gfx/image/image_skia.h" | 36 #include "ui/gfx/image/image_skia.h" |
35 #include "ui/gfx/image/image_skia_rep.h" | 37 #include "ui/gfx/image/image_skia_rep.h" |
36 #include "ui/gfx/insets.h" | 38 #include "ui/gfx/insets.h" |
37 #include "ui/gfx/path.h" | 39 #include "ui/gfx/path.h" |
38 #include "ui/gfx/path_x11.h" | 40 #include "ui/gfx/path_x11.h" |
| 41 #include "ui/gfx/point.h" |
39 #include "ui/gfx/screen.h" | 42 #include "ui/gfx/screen.h" |
| 43 #include "ui/gfx/size.h" |
40 #include "ui/native_theme/native_theme.h" | 44 #include "ui/native_theme/native_theme.h" |
41 #include "ui/views/corewm/tooltip_aura.h" | 45 #include "ui/views/corewm/tooltip_aura.h" |
42 #include "ui/views/ime/input_method.h" | 46 #include "ui/views/ime/input_method.h" |
43 #include "ui/views/linux_ui/linux_ui.h" | 47 #include "ui/views/linux_ui/linux_ui.h" |
44 #include "ui/views/views_delegate.h" | 48 #include "ui/views/views_delegate.h" |
45 #include "ui/views/views_switches.h" | 49 #include "ui/views/views_switches.h" |
46 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" | 50 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" |
47 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" | 51 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" |
48 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" | 52 #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" | 53 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h" |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); | 382 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); |
379 // Enforce |restored_bounds_| since calling Maximize() could have reset it. | 383 // Enforce |restored_bounds_| since calling Maximize() could have reset it. |
380 restored_bounds_ = restored_bounds; | 384 restored_bounds_ = restored_bounds; |
381 } | 385 } |
382 | 386 |
383 bool DesktopWindowTreeHostX11::IsVisible() const { | 387 bool DesktopWindowTreeHostX11::IsVisible() const { |
384 return window_mapped_; | 388 return window_mapped_; |
385 } | 389 } |
386 | 390 |
387 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { | 391 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { |
388 gfx::Size size = AdjustSize(requested_size); | 392 gfx::Size size = AdjustSize(gfx::DIPToScreenSize(requested_size)); |
389 bool size_changed = bounds_.size() != size; | 393 bool size_changed = bounds_.size() != size; |
390 XResizeWindow(xdisplay_, xwindow_, size.width(), size.height()); | 394 XResizeWindow(xdisplay_, xwindow_, size.width(), size.height()); |
391 bounds_.set_size(size); | 395 bounds_.set_size(size); |
392 if (size_changed) { | 396 if (size_changed) { |
393 OnHostResized(size); | 397 OnHostResized(size); |
394 ResetWindowRegion(); | 398 ResetWindowRegion(); |
395 } | 399 } |
396 } | 400 } |
397 | 401 |
398 void DesktopWindowTreeHostX11::StackAtTop() { | 402 void DesktopWindowTreeHostX11::StackAtTop() { |
399 XRaiseWindow(xdisplay_, xwindow_); | 403 XRaiseWindow(xdisplay_, xwindow_); |
400 } | 404 } |
401 | 405 |
402 void DesktopWindowTreeHostX11::CenterWindow(const gfx::Size& size) { | 406 void DesktopWindowTreeHostX11::CenterWindow(const gfx::Size& size_dip) { |
403 gfx::Rect parent_bounds = GetWorkAreaBoundsInScreen(); | 407 gfx::Rect parent_bounds = GetWorkAreaBoundsInScreen(); |
404 | 408 |
| 409 gfx::Size size = gfx::DIPToScreenSize(size_dip); |
| 410 |
405 // If |window_|'s transient parent bounds are big enough to contain |size|, | 411 // If |window_|'s transient parent bounds are big enough to contain |size|, |
406 // use them instead. | 412 // use them instead. |
407 if (wm::GetTransientParent(content_window_)) { | 413 if (wm::GetTransientParent(content_window_)) { |
408 gfx::Rect transient_parent_rect = | 414 gfx::Rect transient_parent_rect = |
409 wm::GetTransientParent(content_window_)->GetBoundsInScreen(); | 415 wm::GetTransientParent(content_window_)->GetBoundsInScreen(); |
410 if (transient_parent_rect.height() >= size.height() && | 416 if (transient_parent_rect.height() >= size.height() && |
411 transient_parent_rect.width() >= size.width()) { | 417 transient_parent_rect.width() >= size.width()) { |
412 parent_bounds = transient_parent_rect; | 418 parent_bounds = transient_parent_rect; |
413 } | 419 } |
414 } | 420 } |
(...skipping 22 matching lines...) Expand all Loading... |
437 } else if (IsMaximized()) { | 443 } else if (IsMaximized()) { |
438 *show_state = ui::SHOW_STATE_MAXIMIZED; | 444 *show_state = ui::SHOW_STATE_MAXIMIZED; |
439 } else if (!IsActive()) { | 445 } else if (!IsActive()) { |
440 *show_state = ui::SHOW_STATE_INACTIVE; | 446 *show_state = ui::SHOW_STATE_INACTIVE; |
441 } else { | 447 } else { |
442 *show_state = ui::SHOW_STATE_NORMAL; | 448 *show_state = ui::SHOW_STATE_NORMAL; |
443 } | 449 } |
444 } | 450 } |
445 | 451 |
446 gfx::Rect DesktopWindowTreeHostX11::GetWindowBoundsInScreen() const { | 452 gfx::Rect DesktopWindowTreeHostX11::GetWindowBoundsInScreen() const { |
447 return bounds_; | 453 return gfx::ScreenToDIPRect(bounds_); |
448 } | 454 } |
449 | 455 |
450 gfx::Rect DesktopWindowTreeHostX11::GetClientAreaBoundsInScreen() const { | 456 gfx::Rect DesktopWindowTreeHostX11::GetClientAreaBoundsInScreen() const { |
451 // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its | 457 // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its |
452 // needed for View::ConvertPointToScreen() to work | 458 // needed for View::ConvertPointToScreen() to work |
453 // correctly. DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just | 459 // correctly. DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just |
454 // asks windows what it thinks the client rect is. | 460 // asks windows what it thinks the client rect is. |
455 // | 461 // |
456 // Attempts to calculate the rect by asking the NonClientFrameView what it | 462 // Attempts to calculate the rect by asking the NonClientFrameView what it |
457 // thought its GetBoundsForClientView() were broke combobox drop down | 463 // thought its GetBoundsForClientView() were broke combobox drop down |
458 // placement. | 464 // placement. |
459 return bounds_; | 465 return gfx::ScreenToDIPRect(bounds_); |
460 } | 466 } |
461 | 467 |
462 gfx::Rect DesktopWindowTreeHostX11::GetRestoredBounds() const { | 468 gfx::Rect DesktopWindowTreeHostX11::GetRestoredBounds() const { |
463 // We can't reliably track the restored bounds of a window, but we can get | 469 // 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 | 470 // 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 | 471 // or restoring bounds, we can record the current bounds before we request |
466 // maximization, and clear it when we detect a state change. | 472 // maximization, and clear it when we detect a state change. |
467 if (!restored_bounds_.IsEmpty()) | 473 if (!restored_bounds_.IsEmpty()) |
468 return restored_bounds_; | 474 return gfx::ScreenToDIPRect(restored_bounds_); |
469 | 475 |
470 return GetWindowBoundsInScreen(); | 476 return GetWindowBoundsInScreen(); |
471 } | 477 } |
472 | 478 |
473 gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInScreen() const { | 479 gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInScreen() const { |
474 std::vector<int> value; | 480 std::vector<int> value; |
475 if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) && | 481 if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) && |
476 value.size() >= 4) { | 482 value.size() >= 4) { |
477 return gfx::Rect(value[0], value[1], value[2], value[3]); | 483 return gfx::Rect(value[0], value[1], value[2], value[3]); |
478 } | 484 } |
479 | 485 |
480 // Fetch the geometry of the root window. | 486 // Fetch the geometry of the root window. |
481 Window root; | 487 Window root; |
482 int x, y; | 488 int x, y; |
483 unsigned int width, height; | 489 unsigned int width, height; |
484 unsigned int border_width, depth; | 490 unsigned int border_width, depth; |
485 if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y, | 491 if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y, |
486 &width, &height, &border_width, &depth)) { | 492 &width, &height, &border_width, &depth)) { |
487 NOTIMPLEMENTED(); | 493 NOTIMPLEMENTED(); |
488 return gfx::Rect(0, 0, 10, 10); | 494 return gfx::Rect(0, 0, 10, 10); |
489 } | 495 } |
490 | 496 |
491 return gfx::Rect(x, y, width, height); | 497 return gfx::ScreenToDIPRect(gfx::Rect(x, y, width, height)); |
492 } | 498 } |
493 | 499 |
494 void DesktopWindowTreeHostX11::SetShape(gfx::NativeRegion native_region) { | 500 void DesktopWindowTreeHostX11::SetShape(gfx::NativeRegion native_region) { |
495 if (window_shape_) | 501 if (window_shape_) |
496 XDestroyRegion(window_shape_); | 502 XDestroyRegion(window_shape_); |
497 custom_window_shape_ = false; | 503 custom_window_shape_ = false; |
498 window_shape_ = NULL; | 504 window_shape_ = NULL; |
499 | 505 |
500 if (native_region) { | 506 if (native_region) { |
501 custom_window_shape_ = true; | 507 custom_window_shape_ = true; |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 | 1085 |
1080 // x.org will BadMatch if we don't set a border when the depth isn't the | 1086 // x.org will BadMatch if we don't set a border when the depth isn't the |
1081 // same as the parent depth. | 1087 // same as the parent depth. |
1082 attribute_mask |= CWBorderPixel; | 1088 attribute_mask |= CWBorderPixel; |
1083 swa.border_pixel = 0; | 1089 swa.border_pixel = 0; |
1084 | 1090 |
1085 use_argb_visual_ = true; | 1091 use_argb_visual_ = true; |
1086 } | 1092 } |
1087 } | 1093 } |
1088 | 1094 |
1089 bounds_ = gfx::Rect(params.bounds.origin(), | 1095 gfx::Point origin_screen = gfx::DIPToScreenPoint(params.bounds.origin()); |
1090 AdjustSize(params.bounds.size())); | 1096 gfx::Size size_screen = gfx::DIPToScreenSize(params.bounds.size()); |
| 1097 bounds_ = gfx::Rect(origin_screen, |
| 1098 AdjustSize(size_screen)); |
1091 xwindow_ = XCreateWindow( | 1099 xwindow_ = XCreateWindow( |
1092 xdisplay_, x_root_window_, | 1100 xdisplay_, x_root_window_, |
1093 bounds_.x(), bounds_.y(), | 1101 origin_screen.x(), origin_screen.y(), |
1094 bounds_.width(), bounds_.height(), | 1102 size_screen.width(), size_screen.height(), |
1095 0, // border width | 1103 0, // border width |
1096 depth, | 1104 depth, |
1097 InputOutput, | 1105 InputOutput, |
1098 visual, | 1106 visual, |
1099 attribute_mask, | 1107 attribute_mask, |
1100 &swa); | 1108 &swa); |
1101 if (ui::PlatformEventSource::GetInstance()) | 1109 if (ui::PlatformEventSource::GetInstance()) |
1102 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); | 1110 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); |
1103 open_windows().push_back(xwindow_); | 1111 open_windows().push_back(xwindow_); |
1104 | 1112 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1402 window_properties_.end(); | 1410 window_properties_.end(); |
1403 } | 1411 } |
1404 | 1412 |
1405 void DesktopWindowTreeHostX11::SetUseNativeFrame(bool use_native_frame) { | 1413 void DesktopWindowTreeHostX11::SetUseNativeFrame(bool use_native_frame) { |
1406 use_native_frame_ = use_native_frame; | 1414 use_native_frame_ = use_native_frame; |
1407 ui::SetUseOSWindowFrame(xwindow_, use_native_frame); | 1415 ui::SetUseOSWindowFrame(xwindow_, use_native_frame); |
1408 ResetWindowRegion(); | 1416 ResetWindowRegion(); |
1409 } | 1417 } |
1410 | 1418 |
1411 void DesktopWindowTreeHostX11::DispatchMouseEvent(ui::MouseEvent* event) { | 1419 void DesktopWindowTreeHostX11::DispatchMouseEvent(ui::MouseEvent* event) { |
| 1420 event->set_location(gfx::ScreenToDIPPoint(event->location())); |
1412 // In Windows, the native events sent to chrome are separated into client | 1421 // In Windows, the native events sent to chrome are separated into client |
1413 // and non-client versions of events, which we record on our LocatedEvent | 1422 // and non-client versions of events, which we record on our LocatedEvent |
1414 // structures. On X11, we emulate the concept of non-client. Before we pass | 1423 // structures. On X11, we emulate the concept of non-client. Before we pass |
1415 // this event to the cross platform event handling framework, we need to | 1424 // this event to the cross platform event handling framework, we need to |
1416 // make sure it is appropriately marked as non-client if it's in the non | 1425 // make sure it is appropriately marked as non-client if it's in the non |
1417 // client area, or otherwise, we can get into a state where the a window is | 1426 // client area, or otherwise, we can get into a state where the a window is |
1418 // set as the |mouse_pressed_handler_| in window_event_dispatcher.cc | 1427 // set as the |mouse_pressed_handler_| in window_event_dispatcher.cc |
1419 // despite the mouse button being released. | 1428 // despite the mouse button being released. |
1420 // | 1429 // |
1421 // We can't do this later in the dispatch process because we share that | 1430 // We can't do this later in the dispatch process because we share that |
1422 // with ash, and ash gets confused about event IS_NON_CLIENT-ness on | 1431 // with ash, and ash gets confused about event IS_NON_CLIENT-ness on |
1423 // events, since ash doesn't expect this bit to be set, because it's never | 1432 // events, since ash doesn't expect this bit to be set, because it's never |
1424 // been set before. (This works on ash on Windows because none of the mouse | 1433 // been set before. (This works on ash on Windows because none of the mouse |
1425 // events on the ash desktop are clicking in what Windows considers to be a | 1434 // events on the ash desktop are clicking in what Windows considers to be a |
1426 // non client area.) Likewise, we won't want to do the following in any | 1435 // non client area.) Likewise, we won't want to do the following in any |
1427 // WindowTreeHost that hosts ash. | 1436 // WindowTreeHost that hosts ash. |
1428 if (content_window_ && content_window_->delegate()) { | 1437 if (content_window_ && content_window_->delegate()) { |
1429 int flags = event->flags(); | 1438 int flags = event->flags(); |
1430 int hit_test_code = | 1439 int hit_test_code = content_window_->delegate()->GetNonClientComponent( |
1431 content_window_->delegate()->GetNonClientComponent(event->location()); | 1440 gfx::ScreenToDIPPoint(event->location())); |
1432 if (hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE) | 1441 if (hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE) |
1433 flags |= ui::EF_IS_NON_CLIENT; | 1442 flags |= ui::EF_IS_NON_CLIENT; |
1434 event->set_flags(flags); | 1443 event->set_flags(flags); |
1435 } | 1444 } |
1436 | 1445 |
1437 // While we unset the urgency hint when we gain focus, we also must remove it | 1446 // While we unset the urgency hint when we gain focus, we also must remove it |
1438 // on mouse clicks because we can call FlashFrame() on an active window. | 1447 // on mouse clicks because we can call FlashFrame() on an active window. |
1439 if (event->IsAnyButton() || event->IsMouseWheelEvent()) | 1448 if (event->IsAnyButton() || event->IsMouseWheelEvent()) |
1440 FlashFrame(false); | 1449 FlashFrame(false); |
1441 | 1450 |
1442 if (!g_current_capture || g_current_capture == this) { | 1451 if (!g_current_capture || g_current_capture == this) { |
| 1452 event->set_location(gfx::DIPToScreenPoint(event->location())); |
1443 SendEventToProcessor(event); | 1453 SendEventToProcessor(event); |
1444 } else { | 1454 } else { |
1445 // Another DesktopWindowTreeHostX11 has installed itself as | 1455 // Another DesktopWindowTreeHostX11 has installed itself as |
1446 // capture. Translate the event's location and dispatch to the other. | 1456 // capture. Translate the event's location and dispatch to the other. |
1447 event->ConvertLocationToTarget(window(), g_current_capture->window()); | 1457 event->ConvertLocationToTarget(window(), g_current_capture->window()); |
| 1458 event->set_location(gfx::DIPToScreenPoint(event->location())); |
1448 g_current_capture->SendEventToProcessor(event); | 1459 g_current_capture->SendEventToProcessor(event); |
1449 } | 1460 } |
1450 } | 1461 } |
1451 | 1462 |
1452 void DesktopWindowTreeHostX11::DispatchTouchEvent(ui::TouchEvent* event) { | 1463 void DesktopWindowTreeHostX11::DispatchTouchEvent(ui::TouchEvent* event) { |
1453 if (g_current_capture && g_current_capture != this && | 1464 if (g_current_capture && g_current_capture != this && |
1454 event->type() == ui::ET_TOUCH_PRESSED) { | 1465 event->type() == ui::ET_TOUCH_PRESSED) { |
1455 event->ConvertLocationToTarget(window(), g_current_capture->window()); | 1466 event->ConvertLocationToTarget(window(), g_current_capture->window()); |
1456 g_current_capture->SendEventToProcessor(event); | 1467 g_current_capture->SendEventToProcessor(event); |
1457 } else { | 1468 } else { |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1943 if (linux_ui) { | 1954 if (linux_ui) { |
1944 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); | 1955 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); |
1945 if (native_theme) | 1956 if (native_theme) |
1946 return native_theme; | 1957 return native_theme; |
1947 } | 1958 } |
1948 | 1959 |
1949 return ui::NativeTheme::instance(); | 1960 return ui::NativeTheme::instance(); |
1950 } | 1961 } |
1951 | 1962 |
1952 } // namespace views | 1963 } // namespace views |
OLD | NEW |