diff --git a/atoms.cpp b/atoms.cpp index 89abe0679f..05d29cdde4 100644 --- a/atoms.cpp +++ b/atoms.cpp @@ -9,8 +9,10 @@ You can Freely distribute this program under the GNU General Public License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ + #include #include "atoms.h" +#include namespace KWinInternal { @@ -68,6 +70,13 @@ Atoms::Atoms() Atom fake; atoms[n] = &fake; names[n++] = (char *) "_DT_SM_WINDOW_INFO"; + + atoms[n] = &xdnd_aware; + names[n++] = (char*) "XdndAware"; + atoms[n] = &xdnd_position; + names[n++] = (char*) "XdndPosition"; + + assert( n <= max ); XInternAtoms( qt_xdisplay(), names, n, FALSE, atoms_return ); for (int i = 0; i < n; i++ ) diff --git a/atoms.h b/atoms.h index a2571f79ff..f315ae93f0 100644 --- a/atoms.h +++ b/atoms.h @@ -37,6 +37,8 @@ class Atoms Atom kde_net_wm_user_creation_time; Atom kde_system_tray_embedding; Atom net_wm_take_activity; + Atom xdnd_aware; + Atom xdnd_position; }; diff --git a/events.cpp b/events.cpp index 3b6676e2cf..8f4753176c 100644 --- a/events.cpp +++ b/events.cpp @@ -379,16 +379,8 @@ bool Workspace::workspaceEvent( XEvent * e ) QWhatsThis::leaveWhatsThisMode(); } - if (electric_have_borders && - (e->xcrossing.window == electric_top_border || - e->xcrossing.window == electric_left_border || - e->xcrossing.window == electric_bottom_border || - e->xcrossing.window == electric_right_border)) - { - // the user entered an electric border - electricBorder(e); - } - break; + if( electricBorder(e)) + return true; case LeaveNotify: { if ( !QWhatsThis::inWhatsThisMode() ) @@ -446,6 +438,10 @@ bool Workspace::workspaceEvent( XEvent * e ) // fall through case FocusOut: return true; // always eat these, they would tell Qt that KWin is the active app + case ClientMessage: + if( electricBorder( e )) + return true; + break; default: break; } diff --git a/workspace.cpp b/workspace.cpp index 50bd445903..6fb7172ce9 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -1910,6 +1910,16 @@ void Workspace::createBorderWindows() CopyFromParent, valuemask, &attributes); XMapWindow(qt_xdisplay(), electric_right_border); + // Set XdndAware on the windows, so that DND enter events are received (#86998) + Atom version = 4; // XDND version + XChangeProperty( qt_xdisplay(), electric_top_border, atoms->xdnd_aware, XA_ATOM, + 32, PropModeReplace, ( unsigned char* )&version, 1 ); + XChangeProperty( qt_xdisplay(), electric_bottom_border, atoms->xdnd_aware, XA_ATOM, + 32, PropModeReplace, ( unsigned char* )&version, 1 ); + XChangeProperty( qt_xdisplay(), electric_left_border, atoms->xdnd_aware, XA_ATOM, + 32, PropModeReplace, ( unsigned char* )&version, 1 ); + XChangeProperty( qt_xdisplay(), electric_right_border, atoms->xdnd_aware, XA_ATOM, + 32, PropModeReplace, ( unsigned char* )&version, 1 ); } @@ -2042,12 +2052,36 @@ void Workspace::clientMoved(const QPoint &pos, Time now) // this function is called when the user entered an electric border // with the mouse. It may switch to another virtual desktop -void Workspace::electricBorder(XEvent *e) +bool Workspace::electricBorder(XEvent *e) { - Time now = e->xcrossing.time; - QPoint p(e->xcrossing.x_root, e->xcrossing.y_root); - - clientMoved(p, now); + if( !electric_have_borders ) + return false; + if( e->type == EnterNotify ) + { + if( e->xcrossing.window == electric_top_border || + e->xcrossing.window == electric_left_border || + e->xcrossing.window == electric_bottom_border || + e->xcrossing.window == electric_right_border) + // the user entered an electric border + { + clientMoved( QPoint( e->xcrossing.x_root, e->xcrossing.y_root ), e->xcrossing.time ); + return true; + } + } + if( e->type == ClientMessage ) + { + if( e->xclient.message_type == atoms->xdnd_position + && ( e->xclient.window == electric_top_border + || e->xclient.window == electric_bottom_border + || e->xclient.window == electric_left_border + || e->xclient.window == electric_right_border )) + { + updateXTime(); + clientMoved( QPoint( e->xclient.data.l[2]>>16, e->xclient.data.l[2]&0xffff), qt_x_time ); + return true; + } + } + return false; } // electric borders (input only windows) have to be always on the diff --git a/workspace.h b/workspace.h index d3792398f7..3aff9b4f41 100644 --- a/workspace.h +++ b/workspace.h @@ -415,7 +415,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine void checkElectricBorders( bool force = false ); void createBorderWindows(); void destroyBorderWindows(); - void electricBorder(XEvent * e); + bool electricBorder(XEvent * e); void raiseElectricBorders(); // ------------------