190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <X11/Xlib.h> 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#undef RootWindow 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/debug/stack_trace.h" 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_loop.h" 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/message_loop/message_pump_x11.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/run_loop.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/env.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/root_window.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window.h" 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window_tree_host.h" 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/x/x11_util.h" 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/point_conversions.h" 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gfx/screen.h" 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/controls/image_view.h" 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/widget/widget.h" 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace views { 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace { 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ScopedCapturer { 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) explicit ScopedCapturer(aura::RootWindowHost* host) 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : host_(host) { 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) host_->SetCapture(); 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ~ScopedCapturer() { 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) host_->ReleaseCapture(); 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::RootWindowHost* host_; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedCapturer); 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)X11WholeScreenMoveLoop::X11WholeScreenMoveLoop( 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) X11WholeScreenMoveLoopDelegate* delegate) 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : delegate_(delegate), 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) in_move_loop_(false), 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) grab_input_window_(None) { 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)X11WholeScreenMoveLoop::~X11WholeScreenMoveLoop() {} 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// DesktopRootWindowHostLinux, MessageLoop::Dispatcher implementation: 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool X11WholeScreenMoveLoop::Dispatch(const base::NativeEvent& event) { 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) XEvent* xev = event; 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note: the escape key is handled in the tab drag controller, which has 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // keyboard focus even though we took pointer grab. 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (xev->type) { 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case MotionNotify: { 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (drag_widget_.get()) { 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Screen* screen = gfx::Screen::GetNativeScreen(); 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point location = gfx::ToFlooredPoint( 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) screen->GetCursorScreenPoint() - drag_offset_); 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drag_widget_->SetBounds(gfx::Rect(location, drag_image_.size())); 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnMouseMovement(&xev->xmotion); 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case ButtonRelease: { 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (xev->xbutton.button == Button1) { 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Assume that drags are being done with the left mouse button. Only 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // break the drag if the left mouse button was released. 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delegate_->OnMouseReleased(); 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// DesktopRootWindowHostLinux, aura::client::WindowMoveClient implementation: 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source, 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::NativeCursor cursor) { 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Start a capture on the host, so that it continues to receive events during 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the drag. 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ScopedCapturer capturer(source->GetDispatcher()->host()); 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!in_move_loop_); // Can only handle one nested loop at a time. 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) in_move_loop_ = true; 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XDisplay* display = gfx::GetXDisplay(); 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) grab_input_window_ = CreateDragInputWindow(display); 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!drag_image_.isNull()) 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateDragImageWindow(); 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::MessagePumpX11::Current()->AddDispatcherForWindow( 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) this, grab_input_window_); 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!GrabPointerWithCursor(cursor)) 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // We are handling a mouse drag outside of the aura::RootWindow system. We 1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // must manually make aura think that the mouse button is pressed so that we 1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // don't draw extraneous tooltips. 1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Env::GetInstance()->set_mouse_button_flags(ui::EF_LEFT_MOUSE_BUTTON); 1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop); 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::RunLoop run_loop(aura::Env::GetInstance()->GetDispatcher()); 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) quit_closure_ = run_loop.QuitClosure(); 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) run_loop.Run(); 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid X11WholeScreenMoveLoop::UpdateCursor(gfx::NativeCursor cursor) { 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(in_move_loop_); 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GrabPointerWithCursor(cursor); 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void X11WholeScreenMoveLoop::EndMoveLoop() { 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!in_move_loop_) 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // We undo our emulated mouse click from RunMoveLoop(); 1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Env::GetInstance()->set_mouse_button_flags(0); 1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(erg): Is this ungrab the cause of having to click to give input focus 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // on drawn out windows? Not ungrabbing here screws the X server until I kill 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the chrome process. 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Ungrab before we let go of the window. 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XDisplay* display = gfx::GetXDisplay(); 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) XUngrabPointer(display, CurrentTime); 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::MessagePumpX11::Current()->RemoveDispatcherForWindow( 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) grab_input_window_); 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drag_widget_.reset(); 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnMoveLoopEnded(); 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) XDestroyWindow(display, grab_input_window_); 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) in_move_loop_ = false; 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) quit_closure_.Run(); 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void X11WholeScreenMoveLoop::SetDragImage(const gfx::ImageSkia& image, 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Vector2dF offset) { 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drag_image_ = image; 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drag_offset_ = offset; 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reset the Y offset, so that the drag-image is always just below the cursor, 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // so that it is possible to see where the cursor is going. 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drag_offset_.set_y(0.f); 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool X11WholeScreenMoveLoop::GrabPointerWithCursor(gfx::NativeCursor cursor) { 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XDisplay* display = gfx::GetXDisplay(); 1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch XGrabServer(display); 1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch XUngrabPointer(display, CurrentTime); 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int ret = XGrabPointer( 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch display, 1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch grab_input_window_, 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch False, 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ButtonPressMask | ButtonReleaseMask | PointerMotionMask, 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GrabModeAsync, 1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GrabModeAsync, 1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch None, 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cursor.platform(), 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CurrentTime); 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch XUngrabServer(display); 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (ret != GrabSuccess) { 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Grabbing new tab for dragging failed: " 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << ui::GetX11ErrorString(display, ret); 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)Window X11WholeScreenMoveLoop::CreateDragInputWindow(XDisplay* display) { 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Creates an invisible, InputOnly toplevel window. This window will receive 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // all mouse movement for drags. It turns out that normal windows doing a 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // grab doesn't redirect pointer motion events if the pointer isn't over the 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // grabbing window. But InputOnly windows are able to grab everything. This 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is what GTK+ does, and I found a patch to KDE that did something similar. 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned long attribute_mask = CWEventMask | CWOverrideRedirect; 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) XSetWindowAttributes swa; 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memset(&swa, 0, sizeof(swa)); 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) swa.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | 199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StructureNotifyMask; 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) swa.override_redirect = True; 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Window window = XCreateWindow(display, 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DefaultRootWindow(display), 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) -100, -100, 10, 10, 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 0, CopyFromParent, InputOnly, CopyFromParent, 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) attribute_mask, &swa); 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) XMapRaised(display, window); 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessagePumpX11::Current()->BlockUntilWindowMapped(window); 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return window; 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void X11WholeScreenMoveLoop::CreateDragImageWindow() { 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Widget* widget = new Widget; 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Widget::InitParams params(Widget::InitParams::TYPE_DRAG); 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.opacity = Widget::InitParams::OPAQUE_WINDOW; 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.accept_events = false; 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point location = gfx::ToFlooredPoint( 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Screen::GetNativeScreen()->GetCursorScreenPoint() - drag_offset_); 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.bounds = gfx::Rect(location, drag_image_.size()); 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) widget->set_focus_on_creation(false); 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) widget->set_frame_type(Widget::FRAME_TYPE_FORCE_NATIVE); 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) widget->Init(params); 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) widget->GetNativeWindow()->SetName("DragWindow"); 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ImageView* image = new ImageView(); 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) image->SetImage(drag_image_); 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) image->SetBounds(0, 0, drag_image_.width(), drag_image_.height()); 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) widget->SetContentsView(image); 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) widget->Show(); 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) widget->GetNativeWindow()->layer()->SetFillsBoundsOpaquely(false); 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drag_widget_.reset(widget); 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace views 238