| 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_root_window_host_x11.h" | 5 #include "ui/views/widget/desktop_aura/desktop_root_window_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 29 matching lines...) Expand all Loading... |
| 40 #include "ui/views/ime/input_method.h" | 40 #include "ui/views/ime/input_method.h" |
| 41 #include "ui/views/linux_ui/linux_ui.h" | 41 #include "ui/views/linux_ui/linux_ui.h" |
| 42 #include "ui/views/views_delegate.h" | 42 #include "ui/views/views_delegate.h" |
| 43 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h" | 43 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h" |
| 44 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" | 44 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" |
| 45 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" | 45 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" |
| 46 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" | 46 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
| 47 #include "ui/views/widget/desktop_aura/desktop_root_window_host_observer_x11.h" | 47 #include "ui/views/widget/desktop_aura/desktop_root_window_host_observer_x11.h" |
| 48 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h" | 48 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h" |
| 49 #include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.h" | 49 #include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.h" |
| 50 #include "ui/views/widget/desktop_aura/x11_scoped_capture.h" |
| 50 #include "ui/views/widget/desktop_aura/x11_window_event_filter.h" | 51 #include "ui/views/widget/desktop_aura/x11_window_event_filter.h" |
| 51 | 52 |
| 52 namespace views { | 53 namespace views { |
| 53 | 54 |
| 54 DesktopRootWindowHostX11* DesktopRootWindowHostX11::g_current_capture = | 55 DesktopRootWindowHostX11* DesktopRootWindowHostX11::g_current_capture = |
| 55 NULL; | 56 NULL; |
| 56 std::list<XID>* DesktopRootWindowHostX11::open_windows_ = NULL; | 57 std::list<XID>* DesktopRootWindowHostX11::open_windows_ = NULL; |
| 57 | 58 |
| 58 DEFINE_WINDOW_PROPERTY_KEY( | 59 DEFINE_WINDOW_PROPERTY_KEY( |
| 59 aura::Window*, kViewsWindowForRootWindow, NULL); | 60 aura::Window*, kViewsWindowForRootWindow, NULL); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 FROM_HERE, | 286 FROM_HERE, |
| 286 base::Bind(&DesktopRootWindowHostX11::CloseNow, | 287 base::Bind(&DesktopRootWindowHostX11::CloseNow, |
| 287 close_widget_factory_.GetWeakPtr())); | 288 close_widget_factory_.GetWeakPtr())); |
| 288 } | 289 } |
| 289 } | 290 } |
| 290 | 291 |
| 291 void DesktopRootWindowHostX11::CloseNow() { | 292 void DesktopRootWindowHostX11::CloseNow() { |
| 292 if (xwindow_ == None) | 293 if (xwindow_ == None) |
| 293 return; | 294 return; |
| 294 | 295 |
| 296 x11_capture_.reset(); |
| 295 native_widget_delegate_->OnNativeWidgetDestroying(); | 297 native_widget_delegate_->OnNativeWidgetDestroying(); |
| 296 | 298 |
| 297 // If we have children, close them. Use a copy for iteration because they'll | 299 // If we have children, close them. Use a copy for iteration because they'll |
| 298 // remove themselves. | 300 // remove themselves. |
| 299 std::set<DesktopRootWindowHostX11*> window_children_copy = window_children_; | 301 std::set<DesktopRootWindowHostX11*> window_children_copy = window_children_; |
| 300 for (std::set<DesktopRootWindowHostX11*>::iterator it = | 302 for (std::set<DesktopRootWindowHostX11*>::iterator it = |
| 301 window_children_copy.begin(); it != window_children_copy.end(); | 303 window_children_copy.begin(); it != window_children_copy.end(); |
| 302 ++it) { | 304 ++it) { |
| 303 (*it)->CloseNow(); | 305 (*it)->CloseNow(); |
| 304 } | 306 } |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 delete native_region; | 461 delete native_region; |
| 460 } | 462 } |
| 461 | 463 |
| 462 void DesktopRootWindowHostX11::Activate() { | 464 void DesktopRootWindowHostX11::Activate() { |
| 463 X11DesktopHandler::get()->ActivateWindow(xwindow_); | 465 X11DesktopHandler::get()->ActivateWindow(xwindow_); |
| 464 native_widget_delegate_->AsWidget()->SetInitialFocus(); | 466 native_widget_delegate_->AsWidget()->SetInitialFocus(); |
| 465 } | 467 } |
| 466 | 468 |
| 467 void DesktopRootWindowHostX11::Deactivate() { | 469 void DesktopRootWindowHostX11::Deactivate() { |
| 468 // Deactivating a window means activating nothing. | 470 // Deactivating a window means activating nothing. |
| 471 x11_capture_.reset(); |
| 469 X11DesktopHandler::get()->ActivateWindow(None); | 472 X11DesktopHandler::get()->ActivateWindow(None); |
| 470 } | 473 } |
| 471 | 474 |
| 472 bool DesktopRootWindowHostX11::IsActive() const { | 475 bool DesktopRootWindowHostX11::IsActive() const { |
| 473 return X11DesktopHandler::get()->IsActiveWindow(xwindow_); | 476 return X11DesktopHandler::get()->IsActiveWindow(xwindow_); |
| 474 } | 477 } |
| 475 | 478 |
| 476 void DesktopRootWindowHostX11::Maximize() { | 479 void DesktopRootWindowHostX11::Maximize() { |
| 477 // When we're the process requesting the maximizing, we can accurately keep | 480 // When we're the process requesting the maximizing, we can accurately keep |
| 478 // track of our restored bounds instead of relying on the heuristics that are | 481 // track of our restored bounds instead of relying on the heuristics that are |
| 479 // in the PropertyNotify and ConfigureNotify handlers. | 482 // in the PropertyNotify and ConfigureNotify handlers. |
| 480 restored_bounds_ = bounds_; | 483 restored_bounds_ = bounds_; |
| 481 | 484 |
| 482 SetWMSpecState(true, | 485 SetWMSpecState(true, |
| 483 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), | 486 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), |
| 484 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); | 487 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); |
| 485 } | 488 } |
| 486 | 489 |
| 487 void DesktopRootWindowHostX11::Minimize() { | 490 void DesktopRootWindowHostX11::Minimize() { |
| 491 x11_capture_.reset(); |
| 488 XIconifyWindow(xdisplay_, xwindow_, 0); | 492 XIconifyWindow(xdisplay_, xwindow_, 0); |
| 489 } | 493 } |
| 490 | 494 |
| 491 void DesktopRootWindowHostX11::Restore() { | 495 void DesktopRootWindowHostX11::Restore() { |
| 492 SetWMSpecState(false, | 496 SetWMSpecState(false, |
| 493 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), | 497 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), |
| 494 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); | 498 atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); |
| 495 } | 499 } |
| 496 | 500 |
| 497 bool DesktopRootWindowHostX11::IsMaximized() const { | 501 bool DesktopRootWindowHostX11::IsMaximized() const { |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 } | 691 } |
| 688 | 692 |
| 689 XSetWMNormalHints(xdisplay_, xwindow_, &hints); | 693 XSetWMNormalHints(xdisplay_, xwindow_, &hints); |
| 690 } | 694 } |
| 691 | 695 |
| 692 void DesktopRootWindowHostX11::OnNativeWidgetFocus() { | 696 void DesktopRootWindowHostX11::OnNativeWidgetFocus() { |
| 693 native_widget_delegate_->AsWidget()->GetInputMethod()->OnFocus(); | 697 native_widget_delegate_->AsWidget()->GetInputMethod()->OnFocus(); |
| 694 } | 698 } |
| 695 | 699 |
| 696 void DesktopRootWindowHostX11::OnNativeWidgetBlur() { | 700 void DesktopRootWindowHostX11::OnNativeWidgetBlur() { |
| 697 if (xwindow_) | 701 if (xwindow_) { |
| 702 x11_capture_.reset(); |
| 698 native_widget_delegate_->AsWidget()->GetInputMethod()->OnBlur(); | 703 native_widget_delegate_->AsWidget()->GetInputMethod()->OnBlur(); |
| 704 } |
| 699 } | 705 } |
| 700 | 706 |
| 701 bool DesktopRootWindowHostX11::IsAnimatingClosed() const { | 707 bool DesktopRootWindowHostX11::IsAnimatingClosed() const { |
| 702 return false; | 708 return false; |
| 703 } | 709 } |
| 704 | 710 |
| 705 //////////////////////////////////////////////////////////////////////////////// | 711 //////////////////////////////////////////////////////////////////////////////// |
| 706 // DesktopRootWindowHostX11, aura::RootWindowHost implementation: | 712 // DesktopRootWindowHostX11, aura::RootWindowHost implementation: |
| 707 | 713 |
| 708 aura::RootWindow* DesktopRootWindowHostX11::GetRootWindow() { | 714 aura::RootWindow* DesktopRootWindowHostX11::GetRootWindow() { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 // X11's XPointerGrab() shouldn't be used for everything; it doesn't map | 812 // X11's XPointerGrab() shouldn't be used for everything; it doesn't map |
| 807 // cleanly to Windows' SetCapture(). GTK only provides a separate concept of | 813 // cleanly to Windows' SetCapture(). GTK only provides a separate concept of |
| 808 // a grab that wasn't the X11 pointer grab, but was instead a manual | 814 // a grab that wasn't the X11 pointer grab, but was instead a manual |
| 809 // redirection of the event. (You need to drop into GDK if you want to | 815 // redirection of the event. (You need to drop into GDK if you want to |
| 810 // perform a raw X11 grab). | 816 // perform a raw X11 grab). |
| 811 | 817 |
| 812 if (g_current_capture) | 818 if (g_current_capture) |
| 813 g_current_capture->OnCaptureReleased(); | 819 g_current_capture->OnCaptureReleased(); |
| 814 | 820 |
| 815 g_current_capture = this; | 821 g_current_capture = this; |
| 816 | 822 x11_capture_.reset(new X11ScopedCapture(xwindow_)); |
| 817 // TODO(erg): In addition to the above, NativeWidgetGtk performs a full X | |
| 818 // pointer grab when our NativeWidget is of type Menu. However, things work | |
| 819 // without it. Clicking inside a chrome window causes a release capture, and | |
| 820 // clicking outside causes an activation change. Since previous attempts at | |
| 821 // using XPointerGrab() to implement this have locked my X server, I'm going | |
| 822 // to skip this for now. | |
| 823 } | 823 } |
| 824 | 824 |
| 825 void DesktopRootWindowHostX11::ReleaseCapture() { | 825 void DesktopRootWindowHostX11::ReleaseCapture() { |
| 826 if (g_current_capture) | 826 if (g_current_capture == this) |
| 827 g_current_capture->OnCaptureReleased(); | 827 g_current_capture->OnCaptureReleased(); |
| 828 } | 828 } |
| 829 | 829 |
| 830 void DesktopRootWindowHostX11::SetCursor(gfx::NativeCursor cursor) { | 830 void DesktopRootWindowHostX11::SetCursor(gfx::NativeCursor cursor) { |
| 831 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); | 831 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); |
| 832 } | 832 } |
| 833 | 833 |
| 834 bool DesktopRootWindowHostX11::QueryMouseLocation( | 834 bool DesktopRootWindowHostX11::QueryMouseLocation( |
| 835 gfx::Point* location_return) { | 835 gfx::Point* location_return) { |
| 836 aura::client::CursorClient* cursor_client = | 836 aura::client::CursorClient* cursor_client = |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 SubstructureRedirectMask | SubstructureNotifyMask, | 1095 SubstructureRedirectMask | SubstructureNotifyMask, |
| 1096 &xclient); | 1096 &xclient); |
| 1097 } | 1097 } |
| 1098 | 1098 |
| 1099 bool DesktopRootWindowHostX11::HasWMSpecProperty(const char* property) const { | 1099 bool DesktopRootWindowHostX11::HasWMSpecProperty(const char* property) const { |
| 1100 return window_properties_.find(atom_cache_.GetAtom(property)) != | 1100 return window_properties_.find(atom_cache_.GetAtom(property)) != |
| 1101 window_properties_.end(); | 1101 window_properties_.end(); |
| 1102 } | 1102 } |
| 1103 | 1103 |
| 1104 void DesktopRootWindowHostX11::OnCaptureReleased() { | 1104 void DesktopRootWindowHostX11::OnCaptureReleased() { |
| 1105 x11_capture_.reset(); |
| 1105 g_current_capture = NULL; | 1106 g_current_capture = NULL; |
| 1106 delegate_->OnHostLostWindowCapture(); | 1107 delegate_->OnHostLostWindowCapture(); |
| 1107 native_widget_delegate_->OnMouseCaptureLost(); | 1108 native_widget_delegate_->OnMouseCaptureLost(); |
| 1108 } | 1109 } |
| 1109 | 1110 |
| 1110 void DesktopRootWindowHostX11::DispatchMouseEvent(ui::MouseEvent* event) { | 1111 void DesktopRootWindowHostX11::DispatchMouseEvent(ui::MouseEvent* event) { |
| 1111 if (!g_current_capture || g_current_capture == this) { | 1112 if (!g_current_capture || g_current_capture == this) { |
| 1112 delegate_->OnHostMouseEvent(event); | 1113 delegate_->OnHostMouseEvent(event); |
| 1113 } else { | 1114 } else { |
| 1114 // Another DesktopRootWindowHostX11 has installed itself as | 1115 // Another DesktopRootWindowHostX11 has installed itself as |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1535 if (linux_ui) { | 1536 if (linux_ui) { |
| 1536 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(); | 1537 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(); |
| 1537 if (native_theme) | 1538 if (native_theme) |
| 1538 return native_theme; | 1539 return native_theme; |
| 1539 } | 1540 } |
| 1540 | 1541 |
| 1541 return ui::NativeTheme::instance(); | 1542 return ui::NativeTheme::instance(); |
| 1542 } | 1543 } |
| 1543 | 1544 |
| 1544 } // namespace views | 1545 } // namespace views |
| OLD | NEW |