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(),
|
GetBrowser(),
|
||||||
result.x, result.y,
|
result.x, result.y,
|
||||||
result.globalX, result.globalY);
|
result.globalX, result.globalY);
|
||||||
} else {
|
} else if (window_x11_) {
|
||||||
// TODO(linux): Convert global{X,Y} to screen coordinates.
|
const gfx::Point& origin = window_x11_->bounds().origin();
|
||||||
|
result.globalX += origin.x();
|
||||||
|
result.globalY += origin.y();
|
||||||
}
|
}
|
||||||
|
|
||||||
// modifiers
|
// modifiers
|
||||||
|
@ -12,14 +12,23 @@
|
|||||||
|
|
||||||
#include "ui/base/x/x11_util.h"
|
#include "ui/base/x/x11_util.h"
|
||||||
#include "ui/events/platform/x11/x11_event_source.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 {
|
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[] = {
|
const char* kAtomsToCache[] = {
|
||||||
"WM_DELETE_WINDOW",
|
kWMDeleteWindow,
|
||||||
"WM_PROTOCOLS",
|
kWMProtocols,
|
||||||
"_NET_WM_PING",
|
kNetWMPing,
|
||||||
"_NET_WM_PID",
|
kNetWMPid,
|
||||||
|
kXdndProxy,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,8 +99,8 @@ CefWindowX11::CefWindowX11(CefRefPtr<CefBrowserHostImpl> browser,
|
|||||||
// should listen for activation events and anything else that GTK+ listens
|
// should listen for activation events and anything else that GTK+ listens
|
||||||
// for, and do something useful.
|
// for, and do something useful.
|
||||||
::Atom protocols[2];
|
::Atom protocols[2];
|
||||||
protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
|
protocols[0] = atom_cache_.GetAtom(kWMDeleteWindow);
|
||||||
protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
|
protocols[1] = atom_cache_.GetAtom(kNetWMPing);
|
||||||
XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
|
XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
|
||||||
|
|
||||||
// We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
|
// 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();
|
long pid = getpid();
|
||||||
XChangeProperty(xdisplay_,
|
XChangeProperty(xdisplay_,
|
||||||
xwindow_,
|
xwindow_,
|
||||||
atom_cache_.GetAtom("_NET_WM_PID"),
|
atom_cache_.GetAtom(kNetWMPid),
|
||||||
XA_CARDINAL,
|
XA_CARDINAL,
|
||||||
32,
|
32,
|
||||||
PropModeReplace,
|
PropModeReplace,
|
||||||
@ -125,9 +134,9 @@ void CefWindowX11::Close() {
|
|||||||
XEvent ev = {0};
|
XEvent ev = {0};
|
||||||
ev.xclient.type = ClientMessage;
|
ev.xclient.type = ClientMessage;
|
||||||
ev.xclient.window = xwindow_;
|
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.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;
|
ev.xclient.data.l[1] = CurrentTime;
|
||||||
XSendEvent(xdisplay_, xwindow_, False, NoEventMask, &ev);
|
XSendEvent(xdisplay_, xwindow_, False, NoEventMask, &ev);
|
||||||
}
|
}
|
||||||
@ -245,13 +254,52 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
|
|||||||
changes.width = bounds.width();
|
changes.width = bounds.width();
|
||||||
changes.height = bounds.height();
|
changes.height = bounds.height();
|
||||||
XConfigureWindow(xdisplay_, child, CWHeight | CWWidth, &changes);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case ClientMessage: {
|
case ClientMessage: {
|
||||||
Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]);
|
Atom message_type = xev->xclient.message_type;
|
||||||
if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
|
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.
|
// We have received a close message from the window manager.
|
||||||
if (browser_ && browser_->destruction_state() <=
|
if (browser_ && browser_->destruction_state() <=
|
||||||
CefBrowserHostImpl::DESTRUCTION_STATE_PENDING) {
|
CefBrowserHostImpl::DESTRUCTION_STATE_PENDING) {
|
||||||
@ -266,7 +314,7 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
|
|||||||
// Allow the close.
|
// Allow the close.
|
||||||
XDestroyWindow(xdisplay_, xwindow_);
|
XDestroyWindow(xdisplay_, xwindow_);
|
||||||
}
|
}
|
||||||
} else if (message_type == atom_cache_.GetAtom("_NET_WM_PING")) {
|
} else if (protocol == atom_cache_.GetAtom(kNetWMPing)) {
|
||||||
XEvent reply_event = *xev;
|
XEvent reply_event = *xev;
|
||||||
reply_event.xclient.window = parent_xwindow_;
|
reply_event.xclient.window = parent_xwindow_;
|
||||||
|
|
||||||
@ -277,6 +325,7 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
|
|||||||
&reply_event);
|
&reply_event);
|
||||||
XFlush(xdisplay_);
|
XFlush(xdisplay_);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DestroyNotify:
|
case DestroyNotify:
|
||||||
|
@ -112,6 +112,12 @@ patches = [
|
|||||||
'name': 'webkit_platform_mac_328814',
|
'name': 'webkit_platform_mac_328814',
|
||||||
'path': '../third_party/WebKit/Source/platform/mac/',
|
'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.
|
# Disable scollbar bounce and overlay on OS X.
|
||||||
# http://code.google.com/p/chromiumembedded/issues/detail?id=364
|
# 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;
|
xwindow_ = None;
|
||||||
|
|
||||||
desktop_native_widget_aura_->OnHostClosed();
|
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_.x(), bounds_.y(),
|
||||||
bounds_.width(), bounds_.height(),
|
bounds_.width(), bounds_.height(),
|
||||||
0, // border width
|
0, // border width
|
||||||
@@ -1600,6 +1606,10 @@
|
@@ -1600,6 +1612,10 @@
|
||||||
}
|
}
|
||||||
break;
|
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 (revision 280796)
|
||||||
+++ desktop_aura/desktop_window_tree_host_x11.h (working copy)
|
+++ 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.
|
// the frame when |xwindow_| gains focus or handles a mouse button event.
|
||||||
bool urgency_hint_set_;
|
bool urgency_hint_set_;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user