Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Unified Diff: ui/views/widget/desktop_root_window_host_linux.cc

Issue 11369220: Move the desktop aura classes into a desktop subdir to make the gyp simpler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/widget/desktop_root_window_host_linux.h ('k') | ui/views/widget/desktop_root_window_host_win.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/widget/desktop_root_window_host_linux.cc
===================================================================
--- ui/views/widget/desktop_root_window_host_linux.cc (revision 167419)
+++ ui/views/widget/desktop_root_window_host_linux.cc (working copy)
@@ -1,1105 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/widget/desktop_root_window_host_linux.h"
-
-#include <X11/extensions/XInput2.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-
-#include "base/message_pump_aurax11.h"
-#include "base/stringprintf.h"
-#include "base/utf_string_conversions.h"
-#include "ui/aura/client/default_capture_client.h"
-#include "ui/aura/client/screen_position_client.h"
-#include "ui/aura/client/user_action_client.h"
-#include "ui/aura/focus_manager.h"
-#include "ui/aura/root_window.h"
-#include "ui/views/corewm/compound_event_filter.h"
-#include "ui/views/corewm/input_method_event_filter.h"
-#include "ui/aura/window_property.h"
-#include "ui/base/events/event_utils.h"
-#include "ui/base/native_theme/native_theme.h"
-#include "ui/base/touch/touch_factory.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/views/ime/input_method_bridge.h"
-#include "ui/views/widget/desktop_aura/desktop_activation_client.h"
-#include "ui/views/widget/desktop_aura/desktop_cursor_client.h"
-#include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
-#include "ui/views/widget/desktop_layout_manager.h"
-#include "ui/views/widget/desktop_native_widget_aura.h"
-#include "ui/views/widget/desktop_screen_position_client.h"
-#include "ui/views/widget/x11_desktop_handler.h"
-#include "ui/views/widget/x11_desktop_window_move_client.h"
-#include "ui/views/widget/x11_window_event_filter.h"
-
-namespace views {
-
-DesktopRootWindowHostLinux* DesktopRootWindowHostLinux::g_current_capture =
- NULL;
-
-DEFINE_WINDOW_PROPERTY_KEY(
- aura::Window*, kViewsWindowForRootWindow, NULL);
-
-DEFINE_WINDOW_PROPERTY_KEY(
- DesktopRootWindowHostLinux*, kHostForRootWindow, NULL);
-
-namespace {
-
-// Standard Linux mouse buttons for going back and forward.
-const int kBackMouseButton = 8;
-const int kForwardMouseButton = 9;
-
-// Constants that are part of EWMH.
-const int k_NET_WM_STATE_ADD = 1;
-const int k_NET_WM_STATE_REMOVE = 0;
-
-const char* kAtomsToCache[] = {
- "WM_DELETE_WINDOW",
- "WM_S0",
- "_NET_WM_PID",
- "_NET_WM_PING",
- "_NET_WM_STATE",
- "_NET_WM_STATE_FULLSCREEN",
- "_NET_WM_STATE_HIDDEN",
- "_NET_WM_STATE_MAXIMIZED_HORZ",
- "_NET_WM_STATE_MAXIMIZED_VERT",
- NULL
-};
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-// DesktopRootWindowHostLinux, public:
-
-DesktopRootWindowHostLinux::DesktopRootWindowHostLinux(
- internal::NativeWidgetDelegate* native_widget_delegate,
- DesktopNativeWidgetAura* desktop_native_widget_aura,
- const gfx::Rect& initial_bounds)
- : close_widget_factory_(this),
- xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()),
- xwindow_(0),
- x_root_window_(DefaultRootWindow(xdisplay_)),
- atom_cache_(xdisplay_, kAtomsToCache),
- window_mapped_(false),
- focus_when_shown_(false),
- current_cursor_(ui::kCursorNull),
- native_widget_delegate_(native_widget_delegate),
- desktop_native_widget_aura_(desktop_native_widget_aura) {
-}
-
-DesktopRootWindowHostLinux::~DesktopRootWindowHostLinux() {
- root_window_->ClearProperty(kHostForRootWindow);
-}
-
-// static
-ui::NativeTheme* DesktopRootWindowHost::GetNativeTheme(aura::Window* window) {
- return ui::NativeTheme::instance();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// DesktopRootWindowHostLinux, private:
-
-void DesktopRootWindowHostLinux::InitX11Window(
- const Widget::InitParams& params) {
- unsigned long attribute_mask = CWBackPixmap;
- XSetWindowAttributes swa;
- memset(&swa, 0, sizeof(swa));
- swa.background_pixmap = None;
-
- if (params.type == Widget::InitParams::TYPE_MENU) {
- swa.override_redirect = True;
- attribute_mask |= CWOverrideRedirect;
- }
-
- xwindow_ = XCreateWindow(
- xdisplay_, x_root_window_,
- params.bounds.x(), params.bounds.y(),
- params.bounds.width(), params.bounds.height(),
- 0, // border width
- CopyFromParent, // depth
- InputOutput,
- CopyFromParent, // visual
- attribute_mask,
- &swa);
- base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_);
-
- // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL().
-
- long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
- KeyPressMask | KeyReleaseMask |
- EnterWindowMask | LeaveWindowMask |
- ExposureMask | VisibilityChangeMask |
- StructureNotifyMask | PropertyChangeMask |
- PointerMotionMask;
- XSelectInput(xdisplay_, xwindow_, event_mask);
- XFlush(xdisplay_);
-
- if (base::MessagePumpForUI::HasXInput2())
- ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
-
- invisible_cursor_ = ui::CreateInvisibleCursor();
-
- // TODO(erg): We currently only request window deletion events. We also
- // should listen for activation events and anything else that GTK+ listens
- // for, and do something useful.
- ::Atom protocols[2];
- protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
- protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
- XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
-
- // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
- // the desktop environment.
- XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);
-
- // Likewise, the X server needs to know this window's pid so it knows which
- // program to kill if the window hangs.
- pid_t pid = getpid();
- XChangeProperty(xdisplay_,
- xwindow_,
- atom_cache_.GetAtom("_NET_WM_PID"),
- XA_CARDINAL,
- 32,
- PropModeReplace,
- reinterpret_cast<unsigned char*>(&pid), 1);
-}
-
-// static
-aura::Window* DesktopRootWindowHostLinux::GetContentWindowForXID(XID xid) {
- aura::RootWindow* root = aura::RootWindow::GetForAcceleratedWidget(xid);
- return root ? root->GetProperty(kViewsWindowForRootWindow) : NULL;
-}
-
-// static
-DesktopRootWindowHostLinux* DesktopRootWindowHostLinux::GetHostForXID(XID xid) {
- aura::RootWindow* root = aura::RootWindow::GetForAcceleratedWidget(xid);
- return root ? root->GetProperty(kHostForRootWindow) : NULL;
-}
-
-void DesktopRootWindowHostLinux::HandleNativeWidgetActivationChanged(
- bool active) {
- native_widget_delegate_->OnNativeWidgetActivationChanged(active);
- native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint();
-}
-
-// TODO(erg): This method should basically be everything I need form
-// RootWindowHostLinux::RootWindowHostLinux().
-aura::RootWindow* DesktopRootWindowHostLinux::InitRootWindow(
- const Widget::InitParams& params) {
- bounds_ = params.bounds;
-
- aura::RootWindow::CreateParams rw_params(bounds_);
- rw_params.host = this;
- root_window_ = new aura::RootWindow(rw_params);
- root_window_->Init();
- root_window_->AddChild(content_window_);
- root_window_->SetLayoutManager(new DesktopLayoutManager(root_window_));
- root_window_->SetProperty(kViewsWindowForRootWindow, content_window_);
- root_window_->SetProperty(kHostForRootWindow, this);
- root_window_host_delegate_ = root_window_;
-
- // If we're given a parent, we need to mark ourselves as transient to another
- // window. Otherwise activation gets screwy.
- gfx::NativeView parent = params.GetParent();
- if (!params.child && params.GetParent())
- parent->AddTransientChild(content_window_);
-
- native_widget_delegate_->OnNativeWidgetCreated();
-
- capture_client_.reset(new aura::client::DefaultCaptureClient(root_window_));
- aura::client::SetCaptureClient(root_window_, capture_client_.get());
-
- // Ensure that the X11DesktopHandler exists so that it dispatches activation
- // messages to us.
- X11DesktopHandler::get();
-
- focus_manager_.reset(new aura::FocusManager);
- root_window_->set_focus_manager(focus_manager_.get());
-
- activation_client_.reset(
- new DesktopActivationClient(root_window_->GetFocusManager()));
- aura::client::SetActivationClient(root_window_,
- activation_client_.get());
-
- dispatcher_client_.reset(new DesktopDispatcherClient);
- aura::client::SetDispatcherClient(root_window_,
- dispatcher_client_.get());
-
- cursor_client_.reset(new DesktopCursorClient(root_window_));
- aura::client::SetCursorClient(root_window_,
- cursor_client_.get());
-
- position_client_.reset(new DesktopScreenPositionClient);
- aura::client::SetScreenPositionClient(root_window_,
- position_client_.get());
-
- // No event filter for aura::Env. Create CompoundEvnetFilter per RootWindow.
- root_window_event_filter_ = new corewm::CompoundEventFilter;
- // Pass ownership of the filter to the root_window.
- root_window_->SetEventFilter(root_window_event_filter_);
-
- input_method_filter_.reset(new corewm::InputMethodEventFilter);
- input_method_filter_->SetInputMethodPropertyInRootWindow(root_window_);
- root_window_event_filter_->AddFilter(input_method_filter_.get());
-
- // TODO(erg): Unify this code once the other consumer goes away.
- x11_window_event_filter_.reset(
- new X11WindowEventFilter(root_window_, activation_client_.get()));
- x11_window_event_filter_->SetUseHostWindowBorders(false);
- root_window_event_filter_->AddFilter(x11_window_event_filter_.get());
-
- x11_window_move_client_.reset(new X11DesktopWindowMoveClient);
- aura::client::SetWindowMoveClient(root_window_,
- x11_window_move_client_.get());
-
- focus_manager_->SetFocusedWindow(content_window_, NULL);
- return root_window_;
-}
-
-bool DesktopRootWindowHostLinux::IsWindowManagerPresent() {
- // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
- // of WM_Sn selections (where n is a screen number).
- return XGetSelectionOwner(
- xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
-}
-
-void DesktopRootWindowHostLinux::SetWMSpecState(bool enabled,
- ::Atom state1,
- ::Atom state2) {
- XEvent xclient;
- memset(&xclient, 0, sizeof(xclient));
- xclient.type = ClientMessage;
- xclient.xclient.window = xwindow_;
- xclient.xclient.message_type = atom_cache_.GetAtom("_NET_WM_STATE");
- xclient.xclient.format = 32;
- xclient.xclient.data.l[0] =
- enabled ? k_NET_WM_STATE_ADD : k_NET_WM_STATE_REMOVE;
- xclient.xclient.data.l[1] = state1;
- xclient.xclient.data.l[2] = state2;
- xclient.xclient.data.l[3] = 1;
- xclient.xclient.data.l[4] = 0;
-
- XSendEvent(xdisplay_, x_root_window_, False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- &xclient);
-}
-
-bool DesktopRootWindowHostLinux::HasWMSpecProperty(const char* property) const {
- return window_properties_.find(atom_cache_.GetAtom(property)) !=
- window_properties_.end();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// DesktopRootWindowHostLinux, DesktopRootWindowHost implementation:
-
-aura::RootWindow* DesktopRootWindowHostLinux::Init(
- aura::Window* content_window,
- const Widget::InitParams& params) {
- content_window_ = content_window;
-
- // TODO(erg): Check whether we *should* be building a RootWindowHost here, or
- // whether we should be proxying requests to another DRWHL.
-
- // In some situations, views tries to make a zero sized window, and that
- // makes us crash. Make sure we have valid sizes.
- Widget::InitParams sanitized_params = params;
- if (sanitized_params.bounds.width() == 0)
- sanitized_params.bounds.set_width(100);
- if (sanitized_params.bounds.height() == 0)
- sanitized_params.bounds.set_height(100);
-
- InitX11Window(sanitized_params);
- return InitRootWindow(sanitized_params);
-}
-
-void DesktopRootWindowHostLinux::Close() {
- // TODO(erg): Might need to do additional hiding tasks here.
-
- if (!close_widget_factory_.HasWeakPtrs()) {
- // And we delay the close so that if we are called from an ATL callback,
- // we don't destroy the window before the callback returned (as the caller
- // may delete ourselves on destroy and the ATL callback would still
- // dereference us when the callback returns).
- MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&DesktopRootWindowHostLinux::CloseNow,
- close_widget_factory_.GetWeakPtr()));
- }
-}
-
-void DesktopRootWindowHostLinux::CloseNow() {
- // Remove the event listeners we've installed. We need to remove these
- // because otherwise we get assert during ~RootWindow().
- root_window_event_filter_->RemoveFilter(x11_window_event_filter_.get());
- root_window_event_filter_->RemoveFilter(input_method_filter_.get());
-
- // Actually free our native resources.
- base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_);
- XDestroyWindow(xdisplay_, xwindow_);
- xwindow_ = None;
-
- desktop_native_widget_aura_->OnHostClosed();
-}
-
-aura::RootWindowHost* DesktopRootWindowHostLinux::AsRootWindowHost() {
- return this;
-}
-
-void DesktopRootWindowHostLinux::ShowWindowWithState(
- ui::WindowShowState show_state) {
- if (show_state != ui::SHOW_STATE_DEFAULT &&
- show_state != ui::SHOW_STATE_NORMAL) {
- // Only forwarding to Show().
- NOTIMPLEMENTED();
- }
-
- Show();
-}
-
-void DesktopRootWindowHostLinux::ShowMaximizedWithBounds(
- const gfx::Rect& restored_bounds) {
- // TODO(erg):
- NOTIMPLEMENTED();
-
- // TODO(erg): We shouldn't completely fall down here.
- Show();
-}
-
-bool DesktopRootWindowHostLinux::IsVisible() const {
- return window_mapped_;
-}
-
-void DesktopRootWindowHostLinux::SetSize(const gfx::Size& size) {
- // TODO(erg):
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::CenterWindow(const gfx::Size& size) {
- gfx::Rect parent_bounds = GetWorkAreaBoundsInScreen();
-
- // If |window_|'s transient parent bounds are big enough to contain |size|,
- // use them instead.
- if (content_window_->transient_parent()) {
- gfx::Rect transient_parent_rect =
- content_window_->transient_parent()->GetBoundsInScreen();
- if (transient_parent_rect.height() >= size.height() &&
- transient_parent_rect.width() >= size.width()) {
- parent_bounds = transient_parent_rect;
- }
- }
-
- gfx::Rect window_bounds(
- parent_bounds.x() + (parent_bounds.width() - size.width()) / 2,
- parent_bounds.y() + (parent_bounds.height() - size.height()) / 2,
- size.width(),
- size.height());
- // Don't size the window bigger than the parent, otherwise the user may not be
- // able to close or move it.
- window_bounds.AdjustToFit(parent_bounds);
-
- SetBounds(window_bounds);
-}
-
-void DesktopRootWindowHostLinux::GetWindowPlacement(
- gfx::Rect* bounds,
- ui::WindowShowState* show_state) const {
- *bounds = bounds_;
-
- // TODO(erg): This needs a better implementation. For now, we're just pass
- // back the normal state until we keep track of this.
- *show_state = ui::SHOW_STATE_NORMAL;
-}
-
-gfx::Rect DesktopRootWindowHostLinux::GetWindowBoundsInScreen() const {
- return bounds_;
-}
-
-gfx::Rect DesktopRootWindowHostLinux::GetClientAreaBoundsInScreen() const {
- // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its
- // needed for View::ConvertPointToScreen() to work
- // correctly. DesktopRootWindowHostWin::GetClientAreaBoundsInScreen() just
- // asks windows what it thinks the client rect is.
- //
- // Attempts to calculate the rect by asking the NonClientFrameView what it
- // thought its GetBoundsForClientView() were broke combobox drop down
- // placement.
- return bounds_;
-}
-
-gfx::Rect DesktopRootWindowHostLinux::GetRestoredBounds() const {
- // TODO(erg):
- NOTIMPLEMENTED();
- return gfx::Rect();
-}
-
-gfx::Rect DesktopRootWindowHostLinux::GetWorkAreaBoundsInScreen() const {
- std::vector<int> value;
- if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) &&
- value.size() >= 4) {
- return gfx::Rect(value[0], value[1], value[2], value[3]);
- }
-
- // TODO(erg): As a fallback, we should return the bounds for the current
- // monitor. However, that's pretty difficult and requires futzing with XRR.
- NOTIMPLEMENTED();
- return gfx::Rect();
-}
-
-void DesktopRootWindowHostLinux::SetShape(gfx::NativeRegion native_region) {
- // TODO(erg):
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::Activate() {
- X11DesktopHandler::get()->ActivateWindow(xwindow_);
-}
-
-void DesktopRootWindowHostLinux::Deactivate() {
- // Deactivating a window means activating nothing.
- X11DesktopHandler::get()->ActivateWindow(None);
-}
-
-bool DesktopRootWindowHostLinux::IsActive() const {
- return X11DesktopHandler::get()->IsActiveWindow(xwindow_);
-}
-
-void DesktopRootWindowHostLinux::Maximize() {
- SetWMSpecState(true,
- atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
- atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
-}
-
-void DesktopRootWindowHostLinux::Minimize() {
- XIconifyWindow(xdisplay_, xwindow_, 0);
-}
-
-void DesktopRootWindowHostLinux::Restore() {
- SetWMSpecState(false,
- atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
- atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
-}
-
-bool DesktopRootWindowHostLinux::IsMaximized() const {
- return (HasWMSpecProperty("_NET_WM_STATE_MAXIMIZED_VERT") ||
- HasWMSpecProperty("_NET_WM_STATE_MAXIMIZED_HORZ"));
-}
-
-bool DesktopRootWindowHostLinux::IsMinimized() const {
- return HasWMSpecProperty("_NET_WM_STATE_HIDDEN");
-}
-
-void DesktopRootWindowHostLinux::OnCaptureReleased() {
- native_widget_delegate_->OnMouseCaptureLost();
- g_current_capture = NULL;
-}
-
-void DesktopRootWindowHostLinux::DispatchMouseEvent(ui::MouseEvent* event) {
- if (!g_current_capture || g_current_capture == this) {
- root_window_host_delegate_->OnHostMouseEvent(event);
- } else {
- // Another DesktopRootWindowHostLinux has installed itself as
- // capture. Translate the event's location and dispatch to the other.
- event->ConvertLocationToTarget(root_window_,
- g_current_capture->root_window_);
- g_current_capture->root_window_host_delegate_->OnHostMouseEvent(event);
- }
-}
-
-bool DesktopRootWindowHostLinux::HasCapture() const {
- return g_current_capture == this;
-}
-
-void DesktopRootWindowHostLinux::SetAlwaysOnTop(bool always_on_top) {
- // TODO(erg):
- NOTIMPLEMENTED();
-}
-
-InputMethod* DesktopRootWindowHostLinux::CreateInputMethod() {
- ui::InputMethod* host = input_method_filter_->input_method();
- return new InputMethodBridge(this, host);
-}
-
-internal::InputMethodDelegate*
- DesktopRootWindowHostLinux::GetInputMethodDelegate() {
- return this;
-}
-
-void DesktopRootWindowHostLinux::SetWindowTitle(const string16& title) {
- XStoreName(xdisplay_, xwindow_, UTF16ToUTF8(title).c_str());
-}
-
-void DesktopRootWindowHostLinux::ClearNativeFocus() {
- // This method is weird and misnamed. Instead of clearing the native focus,
- // it sets the focus to our |content_window_|, which will trigger a cascade
- // of focus changes into views.
- if (content_window_ && content_window_->GetFocusManager() &&
- content_window_->Contains(
- content_window_->GetFocusManager()->GetFocusedWindow())) {
- content_window_->GetFocusManager()->SetFocusedWindow(content_window_, NULL);
- }
-}
-
-Widget::MoveLoopResult DesktopRootWindowHostLinux::RunMoveLoop(
- const gfx::Vector2d& drag_offset) {
- SetCapture();
-
- if (x11_window_move_client_->RunMoveLoop(content_window_, drag_offset) ==
- aura::client::MOVE_SUCCESSFUL)
- return Widget::MOVE_LOOP_SUCCESSFUL;
-
- return Widget::MOVE_LOOP_CANCELED;
-}
-
-void DesktopRootWindowHostLinux::EndMoveLoop() {
- x11_window_move_client_->EndMoveLoop();
-}
-
-void DesktopRootWindowHostLinux::SetVisibilityChangedAnimationsEnabled(
- bool value) {
- // Much like the previous NativeWidgetGtk, we don't have anything to do here.
-}
-
-bool DesktopRootWindowHostLinux::ShouldUseNativeFrame() {
- return false;
-}
-
-void DesktopRootWindowHostLinux::FrameTypeChanged() {
-}
-
-NonClientFrameView* DesktopRootWindowHostLinux::CreateNonClientFrameView() {
- return NULL;
-}
-
-void DesktopRootWindowHostLinux::SetFullscreen(bool fullscreen) {
- SetWMSpecState(fullscreen,
- atom_cache_.GetAtom("_NET_WM_STATE_FULLSCREEN"),
- None);
-}
-
-bool DesktopRootWindowHostLinux::IsFullscreen() const {
- return HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN");
-}
-
-void DesktopRootWindowHostLinux::SetOpacity(unsigned char opacity) {
- // TODO(erg):
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::SetWindowIcons(
- const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
- // TODO(erg):
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::SetAccessibleName(const string16& name) {
- // TODO(erg):
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::SetAccessibleRole(
- ui::AccessibilityTypes::Role role) {
- // TODO(erg):
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::SetAccessibleState(
- ui::AccessibilityTypes::State state) {
- // TODO(erg):
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::InitModalType(ui::ModalType modal_type) {
- // TODO(erg):
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::FlashFrame(bool flash_frame) {
- // TODO(erg):
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::OnNativeWidgetFocus() {
- native_widget_delegate_->AsWidget()->GetInputMethod()->OnFocus();
-}
-
-void DesktopRootWindowHostLinux::OnNativeWidgetBlur() {
- if (xwindow_)
- native_widget_delegate_->AsWidget()->GetInputMethod()->OnBlur();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// DesktopRootWindowHostLinux, aura::RootWindowHost implementation:
-
-void DesktopRootWindowHostLinux::SetDelegate(
- aura::RootWindowHostDelegate* delegate) {
- root_window_host_delegate_ = delegate;
-}
-
-aura::RootWindow* DesktopRootWindowHostLinux::GetRootWindow() {
- return root_window_;
-}
-
-gfx::AcceleratedWidget DesktopRootWindowHostLinux::GetAcceleratedWidget() {
- return xwindow_;
-}
-
-void DesktopRootWindowHostLinux::Show() {
- if (!window_mapped_) {
- // Before we map the window, set size hints. Otherwise, some window managers
- // will ignore toplevel XMoveWindow commands.
- XSizeHints size_hints;
- size_hints.flags = PPosition;
- size_hints.x = bounds_.x();
- size_hints.y = bounds_.y();
- XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
-
- XMapWindow(xdisplay_, xwindow_);
-
- // We now block until our window is mapped. Some X11 APIs will crash and
- // burn if passed |xwindow_| before the window is mapped, and XMapWindow is
- // asynchronous.
- base::MessagePumpAuraX11::Current()->BlockUntilWindowMapped(xwindow_);
- window_mapped_ = true;
- }
-}
-
-void DesktopRootWindowHostLinux::Hide() {
- if (window_mapped_) {
- XWithdrawWindow(xdisplay_, xwindow_, 0);
- window_mapped_ = false;
- }
-}
-
-void DesktopRootWindowHostLinux::ToggleFullScreen() {
- NOTIMPLEMENTED();
-}
-
-gfx::Rect DesktopRootWindowHostLinux::GetBounds() const {
- return bounds_;
-}
-
-void DesktopRootWindowHostLinux::SetBounds(const gfx::Rect& bounds) {
- bool origin_changed = bounds_.origin() != bounds.origin();
- bool size_changed = bounds_.size() != bounds.size();
- XWindowChanges changes = {0};
- unsigned value_mask = 0;
-
- if (size_changed) {
- changes.width = bounds.width();
- changes.height = bounds.height();
- value_mask |= CWHeight | CWWidth;
- }
-
- if (origin_changed) {
- changes.x = bounds.x();
- changes.y = bounds.y();
- value_mask |= CWX | CWY;
- }
- if (value_mask)
- XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
-
- // Assume that the resize will go through as requested, which should be the
- // case if we're running without a window manager. If there's a window
- // manager, it can modify or ignore the request, but (per ICCCM) we'll get a
- // (possibly synthetic) ConfigureNotify about the actual size and correct
- // |bounds_| later.
- bounds_ = bounds;
-
- if (origin_changed)
- native_widget_delegate_->AsWidget()->OnNativeWidgetMove();
- if (size_changed)
- root_window_host_delegate_->OnHostResized(bounds.size());
- else
- root_window_host_delegate_->OnHostPaint();
-}
-
-gfx::Point DesktopRootWindowHostLinux::GetLocationOnNativeScreen() const {
- return bounds_.origin();
-}
-
-void DesktopRootWindowHostLinux::SetCapture() {
- // This is vaguely based on the old NativeWidgetGtk implementation.
- //
- // X11's XPointerGrab() shouldn't be used for everything; it doesn't map
- // cleanly to Windows' SetCapture(). GTK only provides a separate concept of
- // a grab that wasn't the X11 pointer grab, but was instead a manual
- // redirection of the event. (You need to drop into GDK if you want to
- // perform a raw X11 grab).
-
- if (g_current_capture)
- g_current_capture->OnCaptureReleased();
-
- g_current_capture = this;
-
- // TODO(erg): In addition to the above, NativeWidgetGtk performs a full X
- // pointer grab when our NativeWidget is of type Menu. However, things work
- // without it. Clicking inside a chrome window causes a release capture, and
- // clicking outside causes an activation change. Since previous attempts at
- // using XPointerGrab() to implement this have locked my X server, I'm going
- // to skip this for now.
-}
-
-void DesktopRootWindowHostLinux::ReleaseCapture() {
- if (g_current_capture)
- g_current_capture->OnCaptureReleased();
-}
-
-void DesktopRootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) {
- XDefineCursor(xdisplay_, xwindow_, cursor.platform());
-}
-
-bool DesktopRootWindowHostLinux::QueryMouseLocation(
- gfx::Point* location_return) {
- ::Window root_return, child_return;
- int root_x_return, root_y_return, win_x_return, win_y_return;
- unsigned int mask_return;
- XQueryPointer(xdisplay_,
- xwindow_,
- &root_return,
- &child_return,
- &root_x_return, &root_y_return,
- &win_x_return, &win_y_return,
- &mask_return);
- *location_return = gfx::Point(
- std::max(0, std::min(bounds_.width(), win_x_return)),
- std::max(0, std::min(bounds_.height(), win_y_return)));
- return (win_x_return >= 0 && win_x_return < bounds_.width() &&
- win_y_return >= 0 && win_y_return < bounds_.height());
-}
-
-bool DesktopRootWindowHostLinux::ConfineCursorToRootWindow() {
- NOTIMPLEMENTED();
- return false;
-}
-
-void DesktopRootWindowHostLinux::UnConfineCursor() {
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::MoveCursorTo(const gfx::Point& location) {
- NOTIMPLEMENTED();
-}
-
-void DesktopRootWindowHostLinux::SetFocusWhenShown(bool focus_when_shown) {
- static const char* k_NET_WM_USER_TIME = "_NET_WM_USER_TIME";
- focus_when_shown_ = focus_when_shown;
- if (IsWindowManagerPresent() && !focus_when_shown_) {
- ui::SetIntProperty(xwindow_,
- k_NET_WM_USER_TIME,
- k_NET_WM_USER_TIME,
- 0);
- }
-}
-
-bool DesktopRootWindowHostLinux::CopyAreaToSkCanvas(
- const gfx::Rect& source_bounds,
- const gfx::Point& dest_offset,
- SkCanvas* canvas) {
- NOTIMPLEMENTED();
- return false;
-}
-
-bool DesktopRootWindowHostLinux::GrabSnapshot(
- const gfx::Rect& snapshot_bounds,
- std::vector<unsigned char>* png_representation) {
- NOTIMPLEMENTED();
- return false;
-}
-
-void DesktopRootWindowHostLinux::PostNativeEvent(
- const base::NativeEvent& native_event) {
- DCHECK(xwindow_);
- DCHECK(xdisplay_);
- XEvent xevent = *native_event;
- xevent.xany.display = xdisplay_;
- xevent.xany.window = xwindow_;
-
- switch (xevent.type) {
- case EnterNotify:
- case LeaveNotify:
- case MotionNotify:
- case KeyPress:
- case KeyRelease:
- case ButtonPress:
- case ButtonRelease: {
- // The fields used below are in the same place for all of events
- // above. Using xmotion from XEvent's unions to avoid repeating
- // the code.
- xevent.xmotion.root = x_root_window_;
- xevent.xmotion.time = CurrentTime;
-
- gfx::Point point(xevent.xmotion.x, xevent.xmotion.y);
- root_window_->ConvertPointToNativeScreen(&point);
- xevent.xmotion.x_root = point.x();
- xevent.xmotion.y_root = point.y();
- }
- default:
- break;
- }
- XSendEvent(xdisplay_, xwindow_, False, 0, &xevent);
-}
-
-void DesktopRootWindowHostLinux::OnDeviceScaleFactorChanged(
- float device_scale_factor) {
-}
-
-void DesktopRootWindowHostLinux::PrepareForShutdown() {
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// DesktopRootWindowHostLinux, views::internal::InputMethodDelegate:
-
-void DesktopRootWindowHostLinux::DispatchKeyEventPostIME(
- const ui::KeyEvent& key) {
- FocusManager* focus_manager =
- native_widget_delegate_->AsWidget()->GetFocusManager();
- if (native_widget_delegate_->OnKeyEvent(key) || !focus_manager)
- return;
- focus_manager->OnKeyEvent(key);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// DesktopRootWindowHostLinux, MessageLoop::Dispatcher implementation:
-
-bool DesktopRootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
- XEvent* xev = event;
-
- // May want to factor CheckXEventForConsistency(xev); into a common location
- // since it is called here.
- switch (xev->type) {
- case Expose:
- // TODO(erg): Can we only redraw the affected areas?
- root_window_host_delegate_->OnHostPaint();
- break;
- case KeyPress: {
- ui::KeyEvent keydown_event(xev, false);
- root_window_host_delegate_->OnHostKeyEvent(&keydown_event);
- break;
- }
- case KeyRelease: {
- ui::KeyEvent keyup_event(xev, false);
- root_window_host_delegate_->OnHostKeyEvent(&keyup_event);
- break;
- }
- case ButtonPress: {
- if (static_cast<int>(xev->xbutton.button) == kBackMouseButton ||
- static_cast<int>(xev->xbutton.button) == kForwardMouseButton) {
- aura::client::UserActionClient* gesture_client =
- aura::client::GetUserActionClient(root_window_);
- if (gesture_client) {
- gesture_client->OnUserAction(
- static_cast<int>(xev->xbutton.button) == kBackMouseButton ?
- aura::client::UserActionClient::BACK :
- aura::client::UserActionClient::FORWARD);
- }
- break;
- }
- } // fallthrough
- case ButtonRelease: {
- ui::MouseEvent mouseev(xev);
- DispatchMouseEvent(&mouseev);
- break;
- }
- case FocusOut:
- if (xev->xfocus.mode != NotifyGrab) {
- ReleaseCapture();
- root_window_host_delegate_->OnHostLostWindowCapture();
- } else {
- root_window_host_delegate_->OnHostLostMouseGrab();
- }
- break;
- case ConfigureNotify: {
- DCHECK_EQ(xwindow_, xev->xconfigure.window);
- DCHECK_EQ(xwindow_, xev->xconfigure.event);
- // It's possible that the X window may be resized by some other means than
- // from within aura (e.g. the X window manager can change the size). Make
- // sure the root window size is maintained properly.
- gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
- xev->xconfigure.width, xev->xconfigure.height);
- bool size_changed = bounds_.size() != bounds.size();
- bool origin_changed = bounds_.origin() != bounds.origin();
- bounds_ = bounds;
- if (size_changed)
- root_window_host_delegate_->OnHostResized(bounds.size());
- if (origin_changed)
- root_window_host_delegate_->OnHostMoved(bounds_.origin());
- break;
- }
- case GenericEvent: {
- ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
- if (!factory->ShouldProcessXI2Event(xev))
- break;
-
- ui::EventType type = ui::EventTypeFromNative(xev);
- XEvent last_event;
- int num_coalesced = 0;
-
- switch (type) {
- // case ui::ET_TOUCH_MOVED:
- // num_coalesced = CoalescePendingMotionEvents(xev, &last_event);
- // if (num_coalesced > 0)
- // xev = &last_event;
- // // fallthrough
- // case ui::ET_TOUCH_PRESSED:
- // case ui::ET_TOUCH_RELEASED: {
- // ui::TouchEvent touchev(xev);
- // root_window_host_delegate_->OnHostTouchEvent(&touchev);
- // break;
- // }
- case ui::ET_MOUSE_MOVED:
- case ui::ET_MOUSE_DRAGGED:
- case ui::ET_MOUSE_PRESSED:
- case ui::ET_MOUSE_RELEASED:
- case ui::ET_MOUSE_ENTERED:
- case ui::ET_MOUSE_EXITED: {
- if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) {
- // If this is a motion event, we want to coalesce all pending motion
- // events that are at the top of the queue.
- num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
- if (num_coalesced > 0)
- xev = &last_event;
- } else if (type == ui::ET_MOUSE_PRESSED) {
- XIDeviceEvent* xievent =
- static_cast<XIDeviceEvent*>(xev->xcookie.data);
- int button = xievent->detail;
- if (button == kBackMouseButton || button == kForwardMouseButton) {
- aura::client::UserActionClient* gesture_client =
- aura::client::GetUserActionClient(
- root_window_host_delegate_->AsRootWindow());
- if (gesture_client) {
- bool reverse_direction =
- ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled();
- gesture_client->OnUserAction(
- (button == kBackMouseButton && !reverse_direction) ||
- (button == kForwardMouseButton && reverse_direction) ?
- aura::client::UserActionClient::BACK :
- aura::client::UserActionClient::FORWARD);
- }
- break;
- }
- }
- ui::MouseEvent mouseev(xev);
- DispatchMouseEvent(&mouseev);
- break;
- }
- case ui::ET_MOUSEWHEEL: {
- ui::MouseWheelEvent mouseev(xev);
- DispatchMouseEvent(&mouseev);
- break;
- }
- case ui::ET_SCROLL_FLING_START:
- case ui::ET_SCROLL_FLING_CANCEL:
- case ui::ET_SCROLL: {
- ui::ScrollEvent scrollev(xev);
- root_window_host_delegate_->OnHostScrollEvent(&scrollev);
- break;
- }
- case ui::ET_UNKNOWN:
- break;
- default:
- NOTREACHED();
- }
-
- // If we coalesced an event we need to free its cookie.
- if (num_coalesced > 0)
- XFreeEventData(xev->xgeneric.display, &last_event.xcookie);
- break;
- }
- case MapNotify: {
- // If there's no window manager running, we need to assign the X input
- // focus to our host window.
- if (!IsWindowManagerPresent() && focus_when_shown_)
- XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime);
- break;
- }
- case ClientMessage: {
- Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]);
- if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
- // We have received a close message from the window manager.
- root_window_->OnRootWindowHostCloseRequested();
- } else if (message_type == atom_cache_.GetAtom("_NET_WM_PING")) {
- XEvent reply_event = *xev;
- reply_event.xclient.window = x_root_window_;
-
- XSendEvent(xdisplay_,
- reply_event.xclient.window,
- False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- &reply_event);
- }
- break;
- }
- case MappingNotify: {
- switch (xev->xmapping.request) {
- case MappingModifier:
- case MappingKeyboard:
- XRefreshKeyboardMapping(&xev->xmapping);
- root_window_->OnKeyboardMappingChanged();
- break;
- case MappingPointer:
- ui::UpdateButtonMap();
- break;
- default:
- NOTIMPLEMENTED() << " Unknown request: " << xev->xmapping.request;
- break;
- }
- break;
- }
- case MotionNotify: {
- // Discard all but the most recent motion event that targets the same
- // window with unchanged state.
- XEvent last_event;
- while (XPending(xev->xany.display)) {
- XEvent next_event;
- XPeekEvent(xev->xany.display, &next_event);
- if (next_event.type == MotionNotify &&
- next_event.xmotion.window == xev->xmotion.window &&
- next_event.xmotion.subwindow == xev->xmotion.subwindow &&
- next_event.xmotion.state == xev->xmotion.state) {
- XNextEvent(xev->xany.display, &last_event);
- xev = &last_event;
- } else {
- break;
- }
- }
-
- ui::MouseEvent mouseev(xev);
- DispatchMouseEvent(&mouseev);
- break;
- }
- case PropertyNotify: {
- // Get our new window property state if the WM has told us its changed.
- ::Atom state = atom_cache_.GetAtom("_NET_WM_STATE");
-
- std::vector< ::Atom> atom_list;
- if (xev->xproperty.atom == state &&
- ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list)) {
- window_properties_.clear();
- std::copy(atom_list.begin(), atom_list.end(),
- inserter(window_properties_, window_properties_.begin()));
-
- // Now that we have different window properties, we may need to
- // relayout the window. (The windows code doesn't need this because
- // their window change is synchronous.)
- native_widget_delegate_->AsWidget()->GetRootView()->Layout();
- }
- }
- }
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// DesktopRootWindowHost, public:
-
-// static
-DesktopRootWindowHost* DesktopRootWindowHost::Create(
- internal::NativeWidgetDelegate* native_widget_delegate,
- DesktopNativeWidgetAura* desktop_native_widget_aura,
- const gfx::Rect& initial_bounds) {
- return new DesktopRootWindowHostLinux(native_widget_delegate,
- desktop_native_widget_aura,
- initial_bounds);
-}
-
-} // namespace views
« no previous file with comments | « ui/views/widget/desktop_root_window_host_linux.h ('k') | ui/views/widget/desktop_root_window_host_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698