forked from AuroraMiddleware/gtk
Merge branch 'gtk3-dnd-find-dest-window-fix' into 'gtk-3-24'
GdkWin32: Fix DND destination window search See merge request GNOME/gtk!3885
This commit is contained in:
commit
a174568ef9
@ -2204,43 +2204,6 @@ _gdk_win32_window_get_drag_protocol (GdkWindow *window,
|
|||||||
return protocol;
|
return protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
gint x;
|
|
||||||
gint y;
|
|
||||||
HWND ignore;
|
|
||||||
HWND result;
|
|
||||||
} find_window_enum_arg;
|
|
||||||
|
|
||||||
static BOOL CALLBACK
|
|
||||||
find_window_enum_proc (HWND hwnd,
|
|
||||||
LPARAM lparam)
|
|
||||||
{
|
|
||||||
RECT rect;
|
|
||||||
POINT tl, br;
|
|
||||||
find_window_enum_arg *a = (find_window_enum_arg *) lparam;
|
|
||||||
|
|
||||||
if (hwnd == a->ignore)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (!IsWindowVisible (hwnd))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
tl.x = tl.y = 0;
|
|
||||||
ClientToScreen (hwnd, &tl);
|
|
||||||
GetClientRect (hwnd, &rect);
|
|
||||||
br.x = rect.right;
|
|
||||||
br.y = rect.bottom;
|
|
||||||
ClientToScreen (hwnd, &br);
|
|
||||||
|
|
||||||
if (a->x >= tl.x && a->y >= tl.y && a->x < br.x && a->y < br.y)
|
|
||||||
{
|
|
||||||
a->result = hwnd;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GdkWindow *
|
static GdkWindow *
|
||||||
gdk_win32_drag_context_find_window (GdkDragContext *context,
|
gdk_win32_drag_context_find_window (GdkDragContext *context,
|
||||||
GdkWindow *drag_window,
|
GdkWindow *drag_window,
|
||||||
@ -2250,51 +2213,47 @@ gdk_win32_drag_context_find_window (GdkDragContext *context,
|
|||||||
GdkDragProtocol *protocol)
|
GdkDragProtocol *protocol)
|
||||||
{
|
{
|
||||||
GdkWin32DragContext *context_win32 = GDK_WIN32_DRAG_CONTEXT (context);
|
GdkWin32DragContext *context_win32 = GDK_WIN32_DRAG_CONTEXT (context);
|
||||||
GdkWindow *dest_window, *dw;
|
GdkWindow *toplevel = NULL;
|
||||||
find_window_enum_arg a;
|
HWND hwnd = NULL;
|
||||||
|
POINT pt;
|
||||||
|
|
||||||
a.x = x_root * context_win32->scale - _gdk_offset_x;
|
pt.x = x_root * context_win32->scale - _gdk_offset_x;
|
||||||
a.y = y_root * context_win32->scale - _gdk_offset_y;
|
pt.y = y_root * context_win32->scale - _gdk_offset_y;
|
||||||
a.ignore = drag_window ? GDK_WINDOW_HWND (drag_window) : NULL;
|
|
||||||
a.result = NULL;
|
|
||||||
|
|
||||||
GDK_NOTE (DND,
|
GDK_NOTE (DND,
|
||||||
g_print ("gdk_drag_find_window_real: %p %+d%+d\n",
|
g_print ("gdk_drag_find_window_real: %+d%+d\n",
|
||||||
(drag_window ? GDK_WINDOW_HWND (drag_window) : NULL),
|
(int) pt.x, (int) pt.y));
|
||||||
a.x, a.y));
|
|
||||||
|
|
||||||
EnumWindows (find_window_enum_proc, (LPARAM) &a);
|
hwnd = WindowFromPoint (pt);
|
||||||
|
|
||||||
if (a.result == NULL)
|
if (hwnd)
|
||||||
dest_window = NULL;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
dw = gdk_win32_handle_table_lookup (a.result);
|
GdkWindow *window = gdk_win32_handle_table_lookup (hwnd);
|
||||||
if (dw)
|
|
||||||
|
if (window)
|
||||||
{
|
{
|
||||||
dest_window = gdk_window_get_toplevel (dw);
|
toplevel = gdk_window_get_toplevel (window);
|
||||||
g_object_ref (dest_window);
|
g_object_ref (toplevel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dest_window = gdk_win32_window_foreign_new_for_display (gdk_screen_get_display (screen), a.result);
|
toplevel = gdk_win32_window_foreign_new_for_display (gdk_screen_get_display (screen), hwnd);
|
||||||
|
|
||||||
if (use_ole2_dnd)
|
|
||||||
*protocol = GDK_DRAG_PROTO_OLE2;
|
|
||||||
else if (context->source_window)
|
|
||||||
*protocol = GDK_DRAG_PROTO_LOCAL;
|
|
||||||
else
|
|
||||||
*protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GDK_NOTE (DND,
|
if (use_ole2_dnd)
|
||||||
g_print ("gdk_drag_find_window: %p %+d%+d: %p: %p %s\n",
|
*protocol = GDK_DRAG_PROTO_OLE2;
|
||||||
(drag_window ? GDK_WINDOW_HWND (drag_window) : NULL),
|
else if (context->source_window)
|
||||||
x_root, y_root,
|
*protocol = GDK_DRAG_PROTO_LOCAL;
|
||||||
a.result,
|
else
|
||||||
(dest_window ? GDK_WINDOW_HWND (dest_window) : NULL),
|
*protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
|
||||||
_gdk_win32_drag_protocol_to_string (*protocol)));
|
|
||||||
|
|
||||||
return dest_window;
|
GDK_NOTE (DND,
|
||||||
|
g_print ("gdk_drag_find_window: %+d%+d: %p: %p %s\n",
|
||||||
|
x_root, y_root,
|
||||||
|
hwnd,
|
||||||
|
(toplevel ? GDK_WINDOW_HWND (toplevel) : NULL),
|
||||||
|
_gdk_win32_drag_protocol_to_string (*protocol)));
|
||||||
|
|
||||||
|
return toplevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -885,13 +885,13 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
|
|||||||
if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
|
if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
|
||||||
dwExStyle |= WS_EX_TOOLWINDOW;
|
dwExStyle |= WS_EX_TOOLWINDOW;
|
||||||
|
|
||||||
/* WS_EX_TRANSPARENT means "try draw this window last, and ignore input".
|
/* WS_EX_LAYERED | WS_EX_TRANSPARENT makes the window transparent w.r.t.
|
||||||
* It's the last part we're after. We don't want DND indicator to accept
|
* pointer input: the system will direct all pointer input to the window
|
||||||
* input, because that will make it a potential drop target, and if it's
|
* below. We don't want a DND indicator to accept pointer input, because
|
||||||
* under the mouse cursor, this will kill any DND.
|
* that will make it a potential drop target.
|
||||||
*/
|
*/
|
||||||
if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DND)
|
if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DND)
|
||||||
dwExStyle |= WS_EX_TRANSPARENT;
|
dwExStyle |= WS_EX_LAYERED | WS_EX_TRANSPARENT;
|
||||||
|
|
||||||
klass = RegisterGdkClass (window->window_type, impl->type_hint);
|
klass = RegisterGdkClass (window->window_type, impl->type_hint);
|
||||||
|
|
||||||
@ -1277,10 +1277,10 @@ show_window_internal (GdkWindow *window,
|
|||||||
|
|
||||||
exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
|
exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
|
||||||
|
|
||||||
/* Use SetWindowPos to show transparent windows so automatic redraws
|
/* If we have to show an input-only window,
|
||||||
* in other windows can be suppressed.
|
* redraws can be safely skipped.
|
||||||
*/
|
*/
|
||||||
if (exstyle & WS_EX_TRANSPARENT)
|
if (window->input_only)
|
||||||
{
|
{
|
||||||
UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
|
UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
|
||||||
|
|
||||||
@ -1416,7 +1416,6 @@ show_window_internal (GdkWindow *window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
|
if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
|
||||||
{
|
{
|
||||||
gdk_window_fullscreen (window);
|
gdk_window_fullscreen (window);
|
||||||
@ -1489,10 +1488,10 @@ gdk_win32_window_hide (GdkWindow *window)
|
|||||||
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
|
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
|
||||||
ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
|
ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
|
||||||
|
|
||||||
/* Use SetWindowPos to hide transparent windows so automatic redraws
|
/* If we have to hide an input-only window,
|
||||||
* in other windows can be suppressed.
|
* readraws can be safely skipped.
|
||||||
*/
|
*/
|
||||||
if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
|
if (window->input_only)
|
||||||
{
|
{
|
||||||
SetWindowPos (GDK_WINDOW_HWND (window), SWP_NOZORDER_SPECIFIED,
|
SetWindowPos (GDK_WINDOW_HWND (window), SWP_NOZORDER_SPECIFIED,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
@ -2787,6 +2786,7 @@ _gdk_win32_window_update_style_bits (GdkWindow *window)
|
|||||||
GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)window->impl;
|
GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)window->impl;
|
||||||
GdkWMDecoration decorations;
|
GdkWMDecoration decorations;
|
||||||
LONG old_style, new_style, old_exstyle, new_exstyle;
|
LONG old_style, new_style, old_exstyle, new_exstyle;
|
||||||
|
gboolean needs_basic_layering = FALSE;
|
||||||
gboolean all;
|
gboolean all;
|
||||||
RECT rect, before, after;
|
RECT rect, before, after;
|
||||||
gboolean was_topmost;
|
gboolean was_topmost;
|
||||||
@ -2842,7 +2842,18 @@ _gdk_win32_window_update_style_bits (GdkWindow *window)
|
|||||||
else
|
else
|
||||||
impl->layered = FALSE;
|
impl->layered = FALSE;
|
||||||
|
|
||||||
if (impl->layered)
|
/* DND windows need to have the WS_EX_TRANSPARENT | WS_EX_LAYERED styles
|
||||||
|
* set so to behave in input passthrough mode. That's essential for DND
|
||||||
|
* indicators.
|
||||||
|
*/
|
||||||
|
if (!impl->layered &&
|
||||||
|
GDK_WINDOW_HWND (window) != NULL &&
|
||||||
|
impl->type_hint == GDK_WINDOW_TYPE_HINT_DND)
|
||||||
|
{
|
||||||
|
needs_basic_layering = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (impl->layered || needs_basic_layering)
|
||||||
new_exstyle |= WS_EX_LAYERED;
|
new_exstyle |= WS_EX_LAYERED;
|
||||||
else
|
else
|
||||||
new_exstyle &= ~WS_EX_LAYERED;
|
new_exstyle &= ~WS_EX_LAYERED;
|
||||||
@ -2859,6 +2870,19 @@ _gdk_win32_window_update_style_bits (GdkWindow *window)
|
|||||||
update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
|
update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needs_basic_layering)
|
||||||
|
{
|
||||||
|
/* SetLayeredWindowAttributes may have been already called, e.g. to set an opacity level.
|
||||||
|
* We only have to call the API in case it has never been called before on the window.
|
||||||
|
*/
|
||||||
|
if (SetLastError(0),
|
||||||
|
!GetLayeredWindowAttributes (GDK_WINDOW_HWND (window), NULL, NULL, NULL) &&
|
||||||
|
GetLastError() == 0)
|
||||||
|
{
|
||||||
|
API_CALL (SetLayeredWindowAttributes, (GDK_WINDOW_HWND (window), 0, 255, LWA_ALPHA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (old_style == new_style && old_exstyle == new_exstyle )
|
if (old_style == new_style && old_exstyle == new_exstyle )
|
||||||
{
|
{
|
||||||
GDK_NOTE (MISC, g_print ("_gdk_win32_window_update_style_bits: %p: no change\n",
|
GDK_NOTE (MISC, g_print ("_gdk_win32_window_update_style_bits: %p: no change\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user