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 |