mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-02 20:26:59 +01:00
Linux: Add drag&drop support (issue #1258).
- Requires proper handling of the "XdndProxy" property on the top-level window. This currently works in cefsimple but not cefclient (perhaps due to https://bugzilla.gnome.org/show_bug.cgi?id=653264). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1759 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
81f8883b4a
commit
824f8f4009
@ -417,8 +417,10 @@ void CefBrowserHostImpl::PlatformTranslateMouseEvent(
|
||||
GetBrowser(),
|
||||
result.x, result.y,
|
||||
result.globalX, result.globalY);
|
||||
} else {
|
||||
// TODO(linux): Convert global{X,Y} to screen coordinates.
|
||||
} else if (window_x11_) {
|
||||
const gfx::Point& origin = window_x11_->bounds().origin();
|
||||
result.globalX += origin.x();
|
||||
result.globalY += origin.y();
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
@ -12,14 +12,23 @@
|
||||
|
||||
#include "ui/base/x/x11_util.h"
|
||||
#include "ui/events/platform/x11/x11_event_source.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
|
||||
#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const char kWMDeleteWindow[] = "WM_DELETE_WINDOW";
|
||||
const char kWMProtocols[] = "WM_PROTOCOLS";
|
||||
const char kNetWMPing[] = "_NET_WM_PING";
|
||||
const char kNetWMPid[] = "_NET_WM_PID";
|
||||
const char kXdndProxy[] = "XdndProxy";
|
||||
|
||||
const char* kAtomsToCache[] = {
|
||||
"WM_DELETE_WINDOW",
|
||||
"WM_PROTOCOLS",
|
||||
"_NET_WM_PING",
|
||||
"_NET_WM_PID",
|
||||
kWMDeleteWindow,
|
||||
kWMProtocols,
|
||||
kNetWMPing,
|
||||
kNetWMPid,
|
||||
kXdndProxy,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -90,8 +99,8 @@ CefWindowX11::CefWindowX11(CefRefPtr<CefBrowserHostImpl> browser,
|
||||
// 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");
|
||||
protocols[0] = atom_cache_.GetAtom(kWMDeleteWindow);
|
||||
protocols[1] = atom_cache_.GetAtom(kNetWMPing);
|
||||
XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
|
||||
|
||||
// We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
|
||||
@ -105,7 +114,7 @@ CefWindowX11::CefWindowX11(CefRefPtr<CefBrowserHostImpl> browser,
|
||||
long pid = getpid();
|
||||
XChangeProperty(xdisplay_,
|
||||
xwindow_,
|
||||
atom_cache_.GetAtom("_NET_WM_PID"),
|
||||
atom_cache_.GetAtom(kNetWMPid),
|
||||
XA_CARDINAL,
|
||||
32,
|
||||
PropModeReplace,
|
||||
@ -125,9 +134,9 @@ void CefWindowX11::Close() {
|
||||
XEvent ev = {0};
|
||||
ev.xclient.type = ClientMessage;
|
||||
ev.xclient.window = xwindow_;
|
||||
ev.xclient.message_type = atom_cache_.GetAtom("WM_PROTOCOLS");
|
||||
ev.xclient.message_type = atom_cache_.GetAtom(kWMProtocols);
|
||||
ev.xclient.format = 32;
|
||||
ev.xclient.data.l[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
|
||||
ev.xclient.data.l[0] = atom_cache_.GetAtom(kWMDeleteWindow);
|
||||
ev.xclient.data.l[1] = CurrentTime;
|
||||
XSendEvent(xdisplay_, xwindow_, False, NoEventMask, &ev);
|
||||
}
|
||||
@ -245,13 +254,52 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
|
||||
changes.width = bounds.width();
|
||||
changes.height = bounds.height();
|
||||
XConfigureWindow(xdisplay_, child, CWHeight | CWWidth, &changes);
|
||||
|
||||
// Explicitly set the screen bounds so that WindowTreeHost::*Screen()
|
||||
// methods return the correct results.
|
||||
views::DesktopWindowTreeHostX11* window_tree_host =
|
||||
views::DesktopWindowTreeHostX11::GetHostForXID(child);
|
||||
if (window_tree_host)
|
||||
window_tree_host->set_screen_bounds(bounds);
|
||||
|
||||
// Find the top-most window containing the browser window.
|
||||
views::X11TopmostWindowFinder finder;
|
||||
::Window topmost_window = finder.FindWindowAt(bounds.origin());
|
||||
DCHECK(topmost_window);
|
||||
|
||||
// Configure the drag&drop proxy property for the top-most window so
|
||||
// that all drag&drop-related messages will be sent to the child
|
||||
// DesktopWindowTreeHostX11. The proxy property is referenced by
|
||||
// DesktopDragDropClientAuraX11::FindWindowFor.
|
||||
::Window proxy_target = gfx::kNullAcceleratedWidget;
|
||||
ui::GetXIDProperty(topmost_window, kXdndProxy, &proxy_target);
|
||||
if (proxy_target != child) {
|
||||
// Set the proxy target for the top-most window.
|
||||
XChangeProperty(xdisplay_,
|
||||
topmost_window,
|
||||
atom_cache_.GetAtom(kXdndProxy),
|
||||
XA_WINDOW,
|
||||
32,
|
||||
PropModeReplace,
|
||||
reinterpret_cast<unsigned char*>(&child), 1);
|
||||
// Do the same for the proxy target per the spec.
|
||||
XChangeProperty(xdisplay_,
|
||||
child,
|
||||
atom_cache_.GetAtom(kXdndProxy),
|
||||
XA_WINDOW,
|
||||
32,
|
||||
PropModeReplace,
|
||||
reinterpret_cast<unsigned char*>(&child), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ClientMessage: {
|
||||
Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]);
|
||||
if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
|
||||
Atom message_type = xev->xclient.message_type;
|
||||
if (message_type == atom_cache_.GetAtom(kWMProtocols)) {
|
||||
Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]);
|
||||
if (protocol == atom_cache_.GetAtom(kWMDeleteWindow)) {
|
||||
// We have received a close message from the window manager.
|
||||
if (browser_ && browser_->destruction_state() <=
|
||||
CefBrowserHostImpl::DESTRUCTION_STATE_PENDING) {
|
||||
@ -266,7 +314,7 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
|
||||
// Allow the close.
|
||||
XDestroyWindow(xdisplay_, xwindow_);
|
||||
}
|
||||
} else if (message_type == atom_cache_.GetAtom("_NET_WM_PING")) {
|
||||
} else if (protocol == atom_cache_.GetAtom(kNetWMPing)) {
|
||||
XEvent reply_event = *xev;
|
||||
reply_event.xclient.window = parent_xwindow_;
|
||||
|
||||
@ -277,6 +325,7 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
|
||||
&reply_event);
|
||||
XFlush(xdisplay_);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DestroyNotify:
|
||||
|
@ -112,6 +112,12 @@ patches = [
|
||||
'name': 'webkit_platform_mac_328814',
|
||||
'path': '../third_party/WebKit/Source/platform/mac/',
|
||||
},
|
||||
{
|
||||
# Fix drag&drop of combined text and URL data on Linux/Aura.
|
||||
# https://codereview.chromium.org/208313009
|
||||
'name': 'ui_dragdrop_355390',
|
||||
'path': '../ui/base/dragdrop/',
|
||||
},
|
||||
{
|
||||
# Disable scollbar bounce and overlay on OS X.
|
||||
# http://code.google.com/p/chromiumembedded/issues/detail?id=364
|
||||
|
14
patch/patches/ui_dragdrop_355390.patch
Normal file
14
patch/patches/ui_dragdrop_355390.patch
Normal file
@ -0,0 +1,14 @@
|
||||
Index: os_exchange_data_provider_aurax11.cc
|
||||
===================================================================
|
||||
--- os_exchange_data_provider_aurax11.cc (revision 280796)
|
||||
+++ os_exchange_data_provider_aurax11.cc (working copy)
|
||||
@@ -155,7 +155,8 @@
|
||||
format_map_.Insert(atom_cache_.GetAtom(kMimeTypeMozillaURL), mem);
|
||||
|
||||
// Set a string fallback as well.
|
||||
- SetString(spec);
|
||||
+ if (!HasString())
|
||||
+ SetString(spec);
|
||||
|
||||
// Return early if this drag already contains file contents (this implies
|
||||
// that file contents must be populated before URLs). Nautilus (and possibly
|
@ -80,7 +80,34 @@ Index: desktop_aura/desktop_window_tree_host_x11.cc
|
||||
xwindow_ = None;
|
||||
|
||||
desktop_native_widget_aura_->OnHostClosed();
|
||||
@@ -1042,9 +1044,13 @@
|
||||
@@ -443,6 +445,8 @@
|
||||
}
|
||||
|
||||
gfx::Rect DesktopWindowTreeHostX11::GetWindowBoundsInScreen() const {
|
||||
+ if (!screen_bounds_.IsEmpty())
|
||||
+ return screen_bounds_;
|
||||
return bounds_;
|
||||
}
|
||||
|
||||
@@ -455,6 +459,8 @@
|
||||
// Attempts to calculate the rect by asking the NonClientFrameView what it
|
||||
// thought its GetBoundsForClientView() were broke combobox drop down
|
||||
// placement.
|
||||
+ if (!screen_bounds_.IsEmpty())
|
||||
+ return screen_bounds_;
|
||||
return bounds_;
|
||||
}
|
||||
|
||||
@@ -899,6 +905,8 @@
|
||||
}
|
||||
|
||||
gfx::Point DesktopWindowTreeHostX11::GetLocationOnNativeScreen() const {
|
||||
+ if (!screen_bounds_.IsEmpty())
|
||||
+ return screen_bounds_.origin();
|
||||
return bounds_.origin();
|
||||
}
|
||||
|
||||
@@ -1042,9 +1050,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +122,7 @@ Index: desktop_aura/desktop_window_tree_host_x11.cc
|
||||
bounds_.x(), bounds_.y(),
|
||||
bounds_.width(), bounds_.height(),
|
||||
0, // border width
|
||||
@@ -1600,6 +1606,10 @@
|
||||
@@ -1600,6 +1612,10 @@
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -110,7 +137,26 @@ Index: desktop_aura/desktop_window_tree_host_x11.h
|
||||
===================================================================
|
||||
--- desktop_aura/desktop_window_tree_host_x11.h (revision 280796)
|
||||
+++ desktop_aura/desktop_window_tree_host_x11.h (working copy)
|
||||
@@ -331,6 +331,9 @@
|
||||
@@ -84,6 +84,8 @@
|
||||
// Deallocates the internal list of open windows.
|
||||
static void CleanUpWindowList();
|
||||
|
||||
+ void set_screen_bounds(const gfx::Rect& bounds) { screen_bounds_ = bounds; }
|
||||
+
|
||||
protected:
|
||||
// Overridden from DesktopWindowTreeHost:
|
||||
virtual void Init(aura::Window* content_window,
|
||||
@@ -250,6 +252,9 @@
|
||||
// The bounds of |xwindow_|.
|
||||
gfx::Rect bounds_;
|
||||
|
||||
+ // Override the screen bounds when the host is a child window.
|
||||
+ gfx::Rect screen_bounds_;
|
||||
+
|
||||
// Whenever the bounds are set, we keep the previous set of bounds around so
|
||||
// we can have a better chance of getting the real |restored_bounds_|. Window
|
||||
// managers tend to send a Configure message with the maximized bounds, and
|
||||
@@ -331,6 +336,9 @@
|
||||
// the frame when |xwindow_| gains focus or handles a mouse button event.
|
||||
bool urgency_hint_set_;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user