| 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 |