diff --git a/mingw-w64-gtk4/1.patch b/mingw-w64-gtk4/1.patch new file mode 100644 index 0000000000..628111c4de --- /dev/null +++ b/mingw-w64-gtk4/1.patch @@ -0,0 +1,286 @@ +From a7b3e1e7fe1d2402240be0bd382da1f3213204b4 Mon Sep 17 00:00:00 2001 +From: Chun-wei Fan +Date: Thu, 31 Mar 2022 10:36:45 +0800 +Subject: [PATCH 1/4] gdkclipboard-win32.c: Fix call to + gdk_clipboard_claim_remote() + +The call to gdk_win32_clipboard_request_contentformats() can return NULL even +without an error condition being hit (such as when the system clipboard is +empty), so check whether the returned GdkContentFormat pointer is not NULL +before calling gdk_clipboard_claim_remote(), which expects it to be not NULL, +otherwise we face a warning from that funtion and the subsequent +g_object_unref(). + +This at least partially fixes issue #4796. +--- + gdk/win32/gdkclipboard-win32.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/gdk/win32/gdkclipboard-win32.c b/gdk/win32/gdkclipboard-win32.c +index 36d56b8b53..ce80019e56 100644 +--- a/gdk/win32/gdkclipboard-win32.c ++++ b/gdk/win32/gdkclipboard-win32.c +@@ -142,9 +142,13 @@ gdk_win32_clipboard_claim_remote (GdkWin32Clipboard *cb) + cb->sequence_number = -1; + + formats = gdk_win32_clipboard_request_contentformats (cb); +- gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb), formats); +- gdk_content_formats_unref (formats); +- cb->sequence_number = GetClipboardSequenceNumber (); ++ ++ if (formats != NULL) ++ { ++ gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb), formats); ++ gdk_content_formats_unref (formats); ++ cb->sequence_number = GetClipboardSequenceNumber (); ++ } + } + + static void +-- +2.35.1.windows.2 + + +From d65cab0e9f0c786ec9d45f4e26d951c8664bf31d Mon Sep 17 00:00:00 2001 +From: Luca Bacci +Date: Wed, 6 Apr 2022 19:45:50 +0200 +Subject: [PATCH 2/4] GdkWin32: Report serial for events + +--- + gdk/win32/gdkevents-win32.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c +index debc66e5d7..3f71e2a8f4 100644 +--- a/gdk/win32/gdkevents-win32.c ++++ b/gdk/win32/gdkevents-win32.c +@@ -873,6 +873,7 @@ _gdk_win32_append_event (GdkEvent *event) + { + GdkDisplay *display; + GList *link; ++ gulong serial; + + display = gdk_display_get_default (); + +@@ -880,8 +881,9 @@ _gdk_win32_append_event (GdkEvent *event) + #if 1 + link = _gdk_event_queue_append (display, event); + GDK_NOTE (EVENTS, _gdk_win32_print_event (event)); ++ serial = _gdk_display_get_next_serial (display); + /* event morphing, the passed in may not be valid afterwards */ +- _gdk_windowing_got_event (display, link, event, 0); ++ _gdk_windowing_got_event (display, link, event, serial); + #else + _gdk_event_queue_append (display, event); + GDK_NOTE (EVENTS, _gdk_win32_print_event (event)); +-- +2.35.1.windows.2 + + +From 1bab2485c7884c8a254c8876bd08690a3d08f0bf Mon Sep 17 00:00:00 2001 +From: Luca Bacci +Date: Mon, 4 Apr 2022 15:29:52 +0200 +Subject: [PATCH 3/4] GdkWin32: Correct generation of crossing events when + holding an implicit grab + +Fixes #4722 +--- + gdk/win32/gdkevents-win32.c | 43 ++++++++----------------------------- + 1 file changed, 9 insertions(+), 34 deletions(-) + +diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c +index 3f71e2a8f4..6012751952 100644 +--- a/gdk/win32/gdkevents-win32.c ++++ b/gdk/win32/gdkevents-win32.c +@@ -2322,60 +2322,35 @@ gdk_event_translate (MSG *msg, + + pen_touch_input = FALSE; + +- new_window = window; +- +- if (pointer_grab != NULL) +- { +- POINT pt; +- pt = msg->pt; +- +- new_window = NULL; +- hwnd = WindowFromPoint (pt); +- if (hwnd != NULL) +- { +- POINT client_pt = pt; +- +- ScreenToClient (hwnd, &client_pt); +- GetClientRect (hwnd, &rect); +- if (PtInRect (&rect, client_pt)) +- new_window = gdk_win32_handle_table_lookup (hwnd); +- } +- +- if (!pointer_grab->owner_events && +- new_window != NULL && +- new_window != pointer_grab->surface) +- new_window = NULL; +- } ++ g_set_object (&window, find_window_for_mouse_event (window, msg)); + +- if (mouse_window != new_window) ++ if (mouse_window != window) + { + GDK_NOTE (EVENTS, g_print (" mouse_window %p -> %p", + mouse_window ? GDK_SURFACE_HWND (mouse_window) : NULL, +- new_window ? GDK_SURFACE_HWND (new_window) : NULL)); ++ window ? GDK_SURFACE_HWND (window) : NULL)); + synthesize_crossing_events (display, + _gdk_device_manager->system_pointer, +- mouse_window, new_window, ++ mouse_window, window, + GDK_CROSSING_NORMAL, + &msg->pt, + 0, /* TODO: Set right mask */ + _gdk_win32_get_next_tick (msg->time), + FALSE); +- g_set_object (&mouse_window, new_window); ++ g_set_object (&mouse_window, window); + mouse_window_ignored_leave = NULL; +- if (new_window != NULL) +- track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (new_window)); ++ if (window != NULL) ++ track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (window)); + } +- else if (new_window != NULL && +- new_window == mouse_window_ignored_leave) ++ else if (window != NULL && window == mouse_window_ignored_leave) + { + /* If we ignored a leave event for this window and we're now getting + input again we need to re-arm the mouse tracking, as that was + cancelled by the mouseleave. */ + mouse_window_ignored_leave = NULL; +- track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (new_window)); ++ track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (window)); + } + +- g_set_object (&window, find_window_for_mouse_event (window, msg)); + impl = GDK_WIN32_SURFACE (window); + + /* If we haven't moved, don't create any GDK event. Windows +-- +2.35.1.windows.2 + + +From e0dc7b88c6de9dabbda4ec016b9ae1cce136f1f2 Mon Sep 17 00:00:00 2001 +From: Luca Bacci +Date: Wed, 6 Apr 2022 20:01:51 +0200 +Subject: [PATCH 4/4] GdkWin32: Generate crossing event after button release + +Fixes #4813 +--- + gdk/win32/gdkevents-win32.c | 76 +++++++++++++++++++++---------------- + 1 file changed, 43 insertions(+), 33 deletions(-) + +diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c +index 6012751952..7b184e2fba 100644 +--- a/gdk/win32/gdkevents-win32.c ++++ b/gdk/win32/gdkevents-win32.c +@@ -2244,6 +2244,10 @@ gdk_event_translate (MSG *msg, + button = 5; + + buttonup0: ++ { ++ gboolean release_implicit_grab = FALSE; ++ GdkSurface *prev_surface = NULL; ++ + GDK_NOTE (EVENTS, + g_print (" (%d,%d)", + GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam))); +@@ -2253,41 +2257,18 @@ gdk_event_translate (MSG *msg, + g_set_object (&window, find_window_for_mouse_event (window, msg)); + + if (pointer_grab != NULL && pointer_grab->implicit) +- { +- int state = build_pointer_event_state (msg); +- +- /* We keep the implicit grab until no buttons at all are held down */ +- if ((state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (button - 1))) == 0) +- { +- ReleaseCapture (); +- +- new_window = NULL; +- hwnd = WindowFromPoint (msg->pt); +- if (hwnd != NULL) +- { +- POINT client_pt = msg->pt; +- +- ScreenToClient (hwnd, &client_pt); +- GetClientRect (hwnd, &rect); +- if (PtInRect (&rect, client_pt)) +- new_window = gdk_win32_handle_table_lookup (hwnd); +- } ++ { ++ int state = build_pointer_event_state (msg); + +- synthesize_crossing_events (display, +- _gdk_device_manager->system_pointer, +- pointer_grab->surface, new_window, +- GDK_CROSSING_UNGRAB, +- &msg->pt, +- 0, /* TODO: Set right mask */ +- _gdk_win32_get_next_tick (msg->time), +- FALSE); +- g_set_object (&mouse_window, new_window); +- mouse_window_ignored_leave = NULL; +- } +- } ++ /* We keep the implicit grab until no buttons at all are held down */ ++ if ((state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (button - 1))) == 0) ++ { ++ release_implicit_grab = TRUE; ++ prev_surface = pointer_grab->surface; ++ } ++ } + +- generate_button_event (GDK_BUTTON_RELEASE, button, +- window, msg); ++ generate_button_event (GDK_BUTTON_RELEASE, button, window, msg); + + impl = GDK_WIN32_SURFACE (window); + +@@ -2296,8 +2277,37 @@ gdk_event_translate (MSG *msg, + impl->drag_move_resize_context.button == button) + gdk_win32_surface_end_move_resize_drag (window); + ++ if (release_implicit_grab) ++ { ++ ReleaseCapture (); ++ ++ new_window = NULL; ++ hwnd = WindowFromPoint (msg->pt); ++ if (hwnd != NULL) ++ { ++ POINT client_pt = msg->pt; ++ ++ ScreenToClient (hwnd, &client_pt); ++ GetClientRect (hwnd, &rect); ++ if (PtInRect (&rect, client_pt)) ++ new_window = gdk_win32_handle_table_lookup (hwnd); ++ } ++ ++ synthesize_crossing_events (display, ++ _gdk_device_manager->system_pointer, ++ prev_surface, new_window, ++ GDK_CROSSING_UNGRAB, ++ &msg->pt, ++ 0, /* TODO: Set right mask */ ++ _gdk_win32_get_next_tick (msg->time), ++ FALSE); ++ g_set_object (&mouse_window, new_window); ++ mouse_window_ignored_leave = NULL; ++ } ++ + return_val = TRUE; + break; ++ } + + case WM_MOUSEMOVE: + GDK_NOTE (EVENTS, +-- +2.35.1.windows.2 + diff --git a/mingw-w64-gtk4/PKGBUILD b/mingw-w64-gtk4/PKGBUILD index d4e11f8079..d5254dc839 100644 --- a/mingw-w64-gtk4/PKGBUILD +++ b/mingw-w64-gtk4/PKGBUILD @@ -4,7 +4,7 @@ _realname=gtk4 pkgbase=mingw-w64-${_realname} pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}" pkgver=4.6.2 -pkgrel=1 +pkgrel=2 pkgdesc="GObject-based multi-platform GUI toolkit (v4) (mingw-w64)" arch=('any') mingw_arch=('mingw32' 'mingw64' 'ucrt64' 'clang64' 'clang32') @@ -30,13 +30,25 @@ depends=("${MINGW_PACKAGE_PREFIX}-gcc-libs" "${MINGW_PACKAGE_PREFIX}-gst-plugins-bad-libs" "${MINGW_PACKAGE_PREFIX}-ffmpeg" "${MINGW_PACKAGE_PREFIX}-shared-mime-info") -source=("https://download.gnome.org/sources/gtk/${pkgver:0:3}/gtk-${pkgver}.tar.xz") -sha256sums=('ff263af609a50eb76056653592d929459aef4819a444c436f6d52c6f63c1faec') +source=("https://download.gnome.org/sources/gtk/${pkgver:0:3}/gtk-${pkgver}.tar.xz" + "1.patch") +sha256sums=('ff263af609a50eb76056653592d929459aef4819a444c436f6d52c6f63c1faec' + 'fbefb27c5b45c6a57795d6ed93dfe9b623986b8518d175e527c658286b89d2ed') +apply_patch_with_msg() { + for _patch in "$@" + do + msg2 "Applying $_patch" + patch -Np1 -i "${srcdir}/$_patch" + done +} prepare() { cd "${srcdir}/gtk-${pkgver}" + # https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/4608 + # https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/4627 + apply_patch_with_msg 1.patch } build() {