| 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_root_window_host_linux.h" | 5 #include "ui/views/widget/desktop_root_window_host_linux.h" |
| 6 | 6 |
| 7 #include <X11/extensions/XInput2.h> | 7 #include <X11/extensions/XInput2.h> |
| 8 #include <X11/Xatom.h> | 8 #include <X11/Xatom.h> |
| 9 #include <X11/Xutil.h> | 9 #include <X11/Xutil.h> |
| 10 | 10 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 DesktopRootWindowHostLinux::DesktopRootWindowHostLinux( | 58 DesktopRootWindowHostLinux::DesktopRootWindowHostLinux( |
| 59 internal::NativeWidgetDelegate* native_widget_delegate, | 59 internal::NativeWidgetDelegate* native_widget_delegate, |
| 60 const gfx::Rect& initial_bounds) | 60 const gfx::Rect& initial_bounds) |
| 61 : xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), | 61 : xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), |
| 62 xwindow_(0), | 62 xwindow_(0), |
| 63 x_root_window_(DefaultRootWindow(xdisplay_)), | 63 x_root_window_(DefaultRootWindow(xdisplay_)), |
| 64 atom_cache_(xdisplay_, kAtomsToCache), | 64 atom_cache_(xdisplay_, kAtomsToCache), |
| 65 window_mapped_(false), | 65 window_mapped_(false), |
| 66 focus_when_shown_(false), | 66 focus_when_shown_(false), |
| 67 has_capture_(false), | 67 has_capture_(false), |
| 68 cursor_loader_(), |
| 69 current_cursor_(ui::kCursorNull), |
| 70 cursor_shown_(true), |
| 68 native_widget_delegate_(native_widget_delegate) { | 71 native_widget_delegate_(native_widget_delegate) { |
| 69 } | 72 } |
| 70 | 73 |
| 71 DesktopRootWindowHostLinux::~DesktopRootWindowHostLinux() { | 74 DesktopRootWindowHostLinux::~DesktopRootWindowHostLinux() { |
| 72 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); | 75 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); |
| 73 XDestroyWindow(xdisplay_, xwindow_); | 76 XDestroyWindow(xdisplay_, xwindow_); |
| 74 } | 77 } |
| 75 | 78 |
| 76 //////////////////////////////////////////////////////////////////////////////// | 79 //////////////////////////////////////////////////////////////////////////////// |
| 77 // DesktopRootWindowHostLinux, private: | 80 // DesktopRootWindowHostLinux, private: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 104 | 107 |
| 105 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | | 108 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | |
| 106 KeyPressMask | KeyReleaseMask | | 109 KeyPressMask | KeyReleaseMask | |
| 107 EnterWindowMask | LeaveWindowMask | | 110 EnterWindowMask | LeaveWindowMask | |
| 108 ExposureMask | VisibilityChangeMask | | 111 ExposureMask | VisibilityChangeMask | |
| 109 StructureNotifyMask | PropertyChangeMask | | 112 StructureNotifyMask | PropertyChangeMask | |
| 110 PointerMotionMask; | 113 PointerMotionMask; |
| 111 XSelectInput(xdisplay_, xwindow_, event_mask); | 114 XSelectInput(xdisplay_, xwindow_, event_mask); |
| 112 XFlush(xdisplay_); | 115 XFlush(xdisplay_); |
| 113 | 116 |
| 114 // TODO(erg): Something about an invisible cursor here? Don't think I need | 117 invisible_cursor_ = ui::CreateInvisibleCursor(); |
| 115 // it, but this is where it was. | |
| 116 | 118 |
| 117 // TODO(erg): We currently only request window deletion events. We also | 119 // TODO(erg): We currently only request window deletion events. We also |
| 118 // should listen for activation events and anything else that GTK+ listens | 120 // should listen for activation events and anything else that GTK+ listens |
| 119 // for, and do something useful. | 121 // for, and do something useful. |
| 120 ::Atom protocols[2]; | 122 ::Atom protocols[2]; |
| 121 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW"); | 123 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW"); |
| 122 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING"); | 124 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING"); |
| 123 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); | 125 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); |
| 124 | 126 |
| 125 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with | 127 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 | 170 |
| 169 aura::DesktopActivationClient* activation_client = | 171 aura::DesktopActivationClient* activation_client = |
| 170 X11DesktopHandler::get()->get_activation_client(); | 172 X11DesktopHandler::get()->get_activation_client(); |
| 171 aura::client::SetActivationClient( | 173 aura::client::SetActivationClient( |
| 172 root_window_.get(), activation_client); | 174 root_window_.get(), activation_client); |
| 173 | 175 |
| 174 dispatcher_client_.reset(new aura::DesktopDispatcherClient); | 176 dispatcher_client_.reset(new aura::DesktopDispatcherClient); |
| 175 aura::client::SetDispatcherClient(root_window_.get(), | 177 aura::client::SetDispatcherClient(root_window_.get(), |
| 176 dispatcher_client_.get()); | 178 dispatcher_client_.get()); |
| 177 | 179 |
| 180 // The cursor client is a curious thing; it proxies some, but not all, calls |
| 181 // to our SetCursor() method. We require all calls to go through a route that |
| 182 // uses a CursorLoader, which includes all the ones in views:: internal. |
| 183 // |
| 184 // TODO(erg): This is a code smell. I suspect that I'm working around the |
| 185 // CursorClient's interface being plain wrong. |
| 186 aura::client::SetCursorClient(root_window_.get(), this); |
| 187 |
| 178 // No event filter for aura::Env. Create CompoundEvnetFilter per RootWindow. | 188 // No event filter for aura::Env. Create CompoundEvnetFilter per RootWindow. |
| 179 root_window_event_filter_ = new aura::shared::CompoundEventFilter; | 189 root_window_event_filter_ = new aura::shared::CompoundEventFilter; |
| 180 // Pass ownership of the filter to the root_window. | 190 // Pass ownership of the filter to the root_window. |
| 181 root_window_->SetEventFilter(root_window_event_filter_); | 191 root_window_->SetEventFilter(root_window_event_filter_); |
| 182 | 192 |
| 183 input_method_filter_.reset(new aura::shared::InputMethodEventFilter()); | 193 input_method_filter_.reset(new aura::shared::InputMethodEventFilter()); |
| 184 input_method_filter_->SetInputMethodPropertyInRootWindow(root_window_.get()); | 194 input_method_filter_->SetInputMethodPropertyInRootWindow(root_window_.get()); |
| 185 root_window_event_filter_->AddFilter(input_method_filter_.get()); | 195 root_window_event_filter_->AddFilter(input_method_filter_.get()); |
| 186 | 196 |
| 187 // TODO(erg): Unify this code once the other consumer goes away. | 197 // TODO(erg): Unify this code once the other consumer goes away. |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 // TODO(erg): This needs a better implementation. For now, we're just pass | 312 // TODO(erg): This needs a better implementation. For now, we're just pass |
| 303 // back the normal state until we keep track of this. | 313 // back the normal state until we keep track of this. |
| 304 *show_state = ui::SHOW_STATE_NORMAL; | 314 *show_state = ui::SHOW_STATE_NORMAL; |
| 305 } | 315 } |
| 306 | 316 |
| 307 gfx::Rect DesktopRootWindowHostLinux::GetWindowBoundsInScreen() const { | 317 gfx::Rect DesktopRootWindowHostLinux::GetWindowBoundsInScreen() const { |
| 308 return bounds_; | 318 return bounds_; |
| 309 } | 319 } |
| 310 | 320 |
| 311 gfx::Rect DesktopRootWindowHostLinux::GetClientAreaBoundsInScreen() const { | 321 gfx::Rect DesktopRootWindowHostLinux::GetClientAreaBoundsInScreen() const { |
| 312 NOTIMPLEMENTED(); | 322 // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its |
| 313 // TODO(erg): This is wrong, but would require looking at the actual views | 323 // needed for View::ConvertPointToScreen() to work |
| 314 // hierarchy to do correctly. | 324 // correctly. DesktopRootWindowHostWin::GetClientAreaBoundsInScreen() just |
| 325 // asks windows what it thinks the client rect is. |
| 326 // |
| 327 // Attempts to calculate the rect by asking the NonClientFrameView what it |
| 328 // thought its GetBoundsForClientView() were broke combobox drop down |
| 329 // placement. |
| 315 return bounds_; | 330 return bounds_; |
| 316 } | 331 } |
| 317 | 332 |
| 318 gfx::Rect DesktopRootWindowHostLinux::GetRestoredBounds() const { | 333 gfx::Rect DesktopRootWindowHostLinux::GetRestoredBounds() const { |
| 319 // TODO(erg): | 334 // TODO(erg): |
| 320 NOTIMPLEMENTED(); | 335 NOTIMPLEMENTED(); |
| 321 return gfx::Rect(); | 336 return gfx::Rect(); |
| 322 } | 337 } |
| 323 | 338 |
| 324 gfx::Rect DesktopRootWindowHostLinux::GetWorkAreaBoundsInScreen() const { | 339 gfx::Rect DesktopRootWindowHostLinux::GetWorkAreaBoundsInScreen() const { |
| 325 // TODO(erg): | 340 std::vector<int> value; |
| 341 if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) && |
| 342 value.size() >= 4) { |
| 343 return gfx::Rect(value[0], value[1], value[2], value[3]); |
| 344 } |
| 345 |
| 346 // TODO(erg): As a fallback, we should return the bounds for the current |
| 347 // monitor. However, that's pretty difficult and requires futzing with XRR. |
| 326 NOTIMPLEMENTED(); | 348 NOTIMPLEMENTED(); |
| 327 return gfx::Rect(); | 349 return gfx::Rect(); |
| 328 } | 350 } |
| 329 | 351 |
| 330 void DesktopRootWindowHostLinux::SetShape(gfx::NativeRegion native_region) { | 352 void DesktopRootWindowHostLinux::SetShape(gfx::NativeRegion native_region) { |
| 331 // TODO(erg): | 353 // TODO(erg): |
| 332 NOTIMPLEMENTED(); | 354 NOTIMPLEMENTED(); |
| 333 } | 355 } |
| 334 | 356 |
| 335 void DesktopRootWindowHostLinux::Activate() { | 357 void DesktopRootWindowHostLinux::Activate() { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 366 | 388 |
| 367 bool DesktopRootWindowHostLinux::IsMaximized() const { | 389 bool DesktopRootWindowHostLinux::IsMaximized() const { |
| 368 return (HasWMSpecProperty("_NET_WM_STATE_MAXIMIZED_VERT") || | 390 return (HasWMSpecProperty("_NET_WM_STATE_MAXIMIZED_VERT") || |
| 369 HasWMSpecProperty("_NET_WM_STATE_MAXIMIZED_HORZ")); | 391 HasWMSpecProperty("_NET_WM_STATE_MAXIMIZED_HORZ")); |
| 370 } | 392 } |
| 371 | 393 |
| 372 bool DesktopRootWindowHostLinux::IsMinimized() const { | 394 bool DesktopRootWindowHostLinux::IsMinimized() const { |
| 373 return HasWMSpecProperty("_NET_WM_STATE_HIDDEN"); | 395 return HasWMSpecProperty("_NET_WM_STATE_HIDDEN"); |
| 374 } | 396 } |
| 375 | 397 |
| 398 void DesktopRootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { |
| 399 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); |
| 400 } |
| 401 |
| 376 bool DesktopRootWindowHostLinux::HasCapture() const { | 402 bool DesktopRootWindowHostLinux::HasCapture() const { |
| 377 return has_capture_; | 403 return has_capture_; |
| 378 } | 404 } |
| 379 | 405 |
| 380 void DesktopRootWindowHostLinux::SetAlwaysOnTop(bool always_on_top) { | 406 void DesktopRootWindowHostLinux::SetAlwaysOnTop(bool always_on_top) { |
| 381 // TODO(erg): | 407 // TODO(erg): |
| 382 NOTIMPLEMENTED(); | 408 NOTIMPLEMENTED(); |
| 383 } | 409 } |
| 384 | 410 |
| 385 InputMethod* DesktopRootWindowHostLinux::CreateInputMethod() { | 411 InputMethod* DesktopRootWindowHostLinux::CreateInputMethod() { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 // when asked fixes the case where buttons pressed don't receive button | 584 // when asked fixes the case where buttons pressed don't receive button |
| 559 // release events. | 585 // release events. |
| 560 has_capture_ = true; | 586 has_capture_ = true; |
| 561 } | 587 } |
| 562 | 588 |
| 563 void DesktopRootWindowHostLinux::ReleaseCapture() { | 589 void DesktopRootWindowHostLinux::ReleaseCapture() { |
| 564 has_capture_ = false; | 590 has_capture_ = false; |
| 565 } | 591 } |
| 566 | 592 |
| 567 void DesktopRootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) { | 593 void DesktopRootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) { |
| 568 NOTIMPLEMENTED(); | 594 cursor_loader_.SetPlatformCursor(&cursor); |
| 595 |
| 596 if (cursor == current_cursor_) |
| 597 return; |
| 598 current_cursor_ = cursor; |
| 599 |
| 600 if (cursor_shown_) |
| 601 SetCursorInternal(cursor); |
| 569 } | 602 } |
| 570 | 603 |
| 571 void DesktopRootWindowHostLinux::ShowCursor(bool show) { | 604 void DesktopRootWindowHostLinux::ShowCursor(bool show) { |
| 572 NOTIMPLEMENTED(); | 605 if (show == cursor_shown_) |
| 606 return; |
| 607 cursor_shown_ = show; |
| 608 SetCursorInternal(show ? current_cursor_ : invisible_cursor_); |
| 573 } | 609 } |
| 574 | 610 |
| 575 bool DesktopRootWindowHostLinux::QueryMouseLocation( | 611 bool DesktopRootWindowHostLinux::QueryMouseLocation( |
| 576 gfx::Point* location_return) { | 612 gfx::Point* location_return) { |
| 577 ::Window root_return, child_return; | 613 ::Window root_return, child_return; |
| 578 int root_x_return, root_y_return, win_x_return, win_y_return; | 614 int root_x_return, root_y_return, win_x_return, win_y_return; |
| 579 unsigned int mask_return; | 615 unsigned int mask_return; |
| 580 XQueryPointer(xdisplay_, | 616 XQueryPointer(xdisplay_, |
| 581 xwindow_, | 617 xwindow_, |
| 582 &root_return, | 618 &root_return, |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 } | 692 } |
| 657 | 693 |
| 658 void DesktopRootWindowHostLinux::OnDeviceScaleFactorChanged( | 694 void DesktopRootWindowHostLinux::OnDeviceScaleFactorChanged( |
| 659 float device_scale_factor) { | 695 float device_scale_factor) { |
| 660 } | 696 } |
| 661 | 697 |
| 662 void DesktopRootWindowHostLinux::PrepareForShutdown() { | 698 void DesktopRootWindowHostLinux::PrepareForShutdown() { |
| 663 } | 699 } |
| 664 | 700 |
| 665 //////////////////////////////////////////////////////////////////////////////// | 701 //////////////////////////////////////////////////////////////////////////////// |
| 702 // DesktopRootWindowHostLinux, aura::CursorClient implementation: |
| 703 |
| 704 bool DesktopRootWindowHostLinux::IsCursorVisible() const { |
| 705 return cursor_shown_; |
| 706 } |
| 707 |
| 708 void DesktopRootWindowHostLinux::SetDeviceScaleFactor( |
| 709 float device_scale_factor) { |
| 710 cursor_loader_.UnloadAll(); |
| 711 cursor_loader_.set_device_scale_factor(device_scale_factor); |
| 712 } |
| 713 |
| 714 //////////////////////////////////////////////////////////////////////////////// |
| 666 // DesktopRootWindowHostLinux, MessageLoop::Dispatcher implementation: | 715 // DesktopRootWindowHostLinux, MessageLoop::Dispatcher implementation: |
| 667 | 716 |
| 668 bool DesktopRootWindowHostLinux::Dispatch(const base::NativeEvent& event) { | 717 bool DesktopRootWindowHostLinux::Dispatch(const base::NativeEvent& event) { |
| 669 XEvent* xev = event; | 718 XEvent* xev = event; |
| 670 | 719 |
| 671 // May want to factor CheckXEventForConsistency(xev); into a common location | 720 // May want to factor CheckXEventForConsistency(xev); into a common location |
| 672 // since it is called here. | 721 // since it is called here. |
| 673 switch (xev->type) { | 722 switch (xev->type) { |
| 674 case Expose: | 723 case Expose: |
| 675 // TODO(erg): Can we only redraw the affected areas? | 724 // TODO(erg): Can we only redraw the affected areas? |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 // DesktopRootWindowHost, public: | 941 // DesktopRootWindowHost, public: |
| 893 | 942 |
| 894 // static | 943 // static |
| 895 DesktopRootWindowHost* DesktopRootWindowHost::Create( | 944 DesktopRootWindowHost* DesktopRootWindowHost::Create( |
| 896 internal::NativeWidgetDelegate* native_widget_delegate, | 945 internal::NativeWidgetDelegate* native_widget_delegate, |
| 897 const gfx::Rect& initial_bounds) { | 946 const gfx::Rect& initial_bounds) { |
| 898 return new DesktopRootWindowHostLinux(native_widget_delegate, initial_bounds); | 947 return new DesktopRootWindowHostLinux(native_widget_delegate, initial_bounds); |
| 899 } | 948 } |
| 900 | 949 |
| 901 } // namespace views | 950 } // namespace views |
| OLD | NEW |