gtk4-prep: event controllers - #21659
Open
Arecsu wants to merge 86 commits into
Open
Conversation
Restore the scroll event masks that were removed when cleaning up
gtk_widget_add_events() calls during the event controller conversion.
Both widgets still use the old g_signal_connect('scroll-event', ...)
for event forwarding (colorequal forwards to notebook/sliders,
tonequal controls propagation), which requires GDK_SCROLL_MASK in
the widget's event mask to function.
- Properly indent closing brace in tonecurve.c secondary-button handler - Add missing newline before closing brace in colorzones.c - Remove stray duplicate void gui_init line in map_locations.c
Update copyright end-year to 2026 in files touched by event controller conversion that still had outdated ranges.
…ontroller conversion
…incompatible with gesture controllers)
…mGpsMap incompatible with gesture controllers)" This reverts commit 4f60af5.
…Map uses widget class vfuncs, not GtkGesture)
- Replace gtk_gesture_single_get_button() with _get_current_button() in _popup_button_press_cb and _popup_button_release_cb. The gesture uses click_all (button=0), so get_button() always returns 0, making all button-type checks silently dead. - Restore window validation guard that was dropped during conversion: reject events whose GdkWindow doesn't match the popup area widget. - Restore BUTTON1_MASK injection on the forwarded motion state, needed for the correct motion tolerance calculation (400 vs 50px). - Restore dt_gui_get_scroll_unit_deltas() usage in _popup_scroll_cb to accumulate smooth-scroll events properly instead of truncating fractional deltas to zero.
Replace gtk_gesture_single_get_button() with _get_current_button() in _event_band_press_cb and _event_entry_press_cb. Both callbacks are connected via click_all (button=0), so get_button() always returns 0, making drag, double-click reset, and right-click popup all non-functional.
_area_scrolled_callback calls gtk_get_current_event() but never frees the returned event, leaking one GdkEvent per scroll event in the colorequal graph.
Both _blendop_blendif_showmask_clicked and _blendop_masks_modes_none_clicked lost their GDK_BUTTON_PRIMARY checks during the event controller conversion. These callbacks are connected via dt_iop_togglebutton_new which uses a gesture with button=0 (all buttons), so non-primary clicks would incorrectly trigger mask display toggles and mask mode changes.
_presets_scrolled was using raw dx/dy values directly, which truncates fractional smooth-scroll deltas to zero on trackpads. Restore dt_gui_get_scroll_unit_deltas() to accumulate events until a full scroll unit is reached, with a raw-value fallback.
Replace gtk_gesture_single_get_button() with _get_current_button() in 6 lib module callbacks that are connected via click_all (button=0): - collect: view_onButtonPressed_cb - colorpicker: _live_sample_button_cb - export: _widht_mdlclick_cb, _height_mdlclick_cb, _scale_mdlclick_cb - tagging: _click_on_view_dictionary, _click_on_view_attached - colorlabels: _lib_colorlabels_button_press_callback - masks: _tree_button_pressed_cb get_button() returns the configured button (always 0 for click_all), not the actual event button, making all button-type checks unconditionally false.
Add a short-hand macro for the verbose gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(x)) pattern that appears 156 times across 60 files. dt_gui_get_widget(x) → gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(x))
Replace outdated FIXME comment with a proper GTK4 migration note. The original TODO asked for a helper to extract event flags — gtk_get_current_event_state() already provides this in GTK3, and gtk_event_controller_get_current_event_state() will be the GTK4 equivalent. Also removed several other stale FIXMEs about scroll handling scope that are outside the scope of this change.
Only changed the stale 'make a helper' TODO — replaced it with a proper GTK4 migration note about using gtk_event_controller_get_current_event_state(). Preserved the existing UI/UX FIXMEs about scroll handling placement.
Scroll event controller callbacks receive (dx, dy) but no raw GdkEventScroll *, so they need gtk_get_current_event() to use the smooth-scroll accumulation logic in dt_gui_get_scroll_unit_deltas(). Add fallback helpers that try the current event first and fall back to the raw dx/dy values, reducing the boilerplate from ~7 lines of event-dance to a single call. Also cleans up 3 call sites: - bauhaus.c: _popup_scroll_cb (combobox + slider branches) - imageop.c: _presets_scrolled
GtkDrawingArea (and its dtgtk subclass) is a NO_WINDOW widget — it doesn't have its own GdkWindow. GtkEventController adds event masks via gtk_widget_add_events(), but on NO_WINDOW widgets this may not propagate correctly to the parent's GdkWindow in all GTK3 versions. Restore explicit GDK_POINTER_MOTION_MASK, GDK_BUTTON_PRESS_MASK, GDK_BUTTON_RELEASE_MASK, GDK_ENTER_NOTIFY_MASK, GDK_LEAVE_NOTIFY_MASK on all converted drawing areas that lost them during the event controller conversion. The controllers also request these masks, but explicit gtk_widget_set_events/add_events is the proven path for NO_WINDOW widgets. Affects: ratings, range, colorzones, rgbcurve, tonecurve, monochrome, basecurve, colorcorrection, colorequal, toneequal, zonesystem, and colorpicker drawing areas.
…irk) GtkEventControllerMotion and GtkEventControllerKey don't receive events on GTK_WINDOW_POPUP windows in GTK3. This is a known issue with this window type — motion and key events never reach the controllers even with explicit event masks set. Replace the motion and key controllers on the popup with direct signal handler connections (motion-notify-event, leave-notify-event, key-press-event). Click and scroll controllers are kept since those work fine. GTK4 TODO: the popup should be migrated to GtkPopover which uses proper event controllers.
Replace gesture controller with the GtkButton ::clicked signal for the filter preferences button. Gesture controllers on custom button widgets (dtgtk_button) can conflict with the button's internal event handling. ::clicked is the standard GTK4-compatible way to handle button presses.
The GTK_IS_BUTTON(gtk_get_event_widget(event)) check was lost during the event controller conversion. Without it, clicking on any button inside the module header (presets, reset, enable, multiinstance) also toggles the expander, causing the module to open/close unexpectedly. GTK4: use gtk_gesture_get_last_event(gesture) instead of gtk_get_current_event().
- Fix arrow button: replace gtk_gesture_single_get_button() with _get_current_button() — the arrow was connected via click_all (button=0), so get_button() always returned 0, making the arrow completely unresponsive. - Restore GTK_IS_BUTTON guard in header release callback — prevents button clicks inside the header from toggling the expander. - Switch presets button from gesture (press=reset, release=popup) to GtkButton ::clicked signal, which only does the popup. The old gesture approach reset the module on every press. - Add dt_gui_claim() to the reset callback so the event is consumed, preventing the button's internal handling from also firing.
Use a simple cast (expected_type)(func) instead of the ternary or comma-operator tricks. Casting NULL to a function pointer type is valid C, and G_CALLBACK casts in the actual call already enforce the real type checking.
Arecsu
force-pushed
the
gtk4/event-controllers-all
branch
from
July 27, 2026 21:29
b8a350c to
676138c
Compare
Arecsu
marked this pull request as ready for review
July 27, 2026 21:39
When removing a filtering rule, the same config-shifting code was duplicated between the main panel's close button and the topbar popover's remove button. This pulls it into a shared helper. Along the way, a few issues in the topbar popover's removal function are cleaned up: a redundant data lookup, a GList that was never freed, and a parent widget that was looked up twice.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Huge PR. Needs further testing to see if interactions, keyboard events, mouse, trackpad, scrolls, anything in the UI UX responds ok, across Linux, macOS, Windows.
I've been testing this, polishing code, fixing bugs across the commits. So far so good. But I'm pretty sure I might be missing something, somewhere, deep down a weird module used by a small fraction of people, or could be even obvious issues which I didn't notice.
Mostly mechanical changes, but so many of them had to be made for their particular context. Some code clean up here and there, helpers, macros, but mostly porting to be gtk4 compatible.
Given all changes across files are somewhat related to one another, I concluded that splitting this into many PRs will be more of a time and effort block than anything else. A bug that might happen to a particular module might have its solution (or bug) related to a similar code path somewhere else. So, that's my logic for having this PR in one go.
I need help in testing this!
Skipped in this PR
Focus events (
focus-in-event/focus-out-event, ~30 callers):GtkEventControllerFocusdoesn't exist in GTK 3.24 — it's a GTK4-only class. We can't convert these until we actually switch to GTK4, so they stay asg_signal_connectfor now and will become a mechanical find-and-replace at migration time.Dialog enter key (
dt_handle_dialog_enter, ~6 callers): These bind Enter to "ok" in modal dialogs usingg_signal_connect(dialog, "key-press-event", ...). On GTK4,GtkDialoghandles this natively, so the workaround can simply be deleted — no conversion needed. It's deferred because it touches the same foundation layer ingtk.cthat's being left alone until the switch.Foundation infrastructure in gtk.c itself (~33 signals): These are the remaining event signals inside
src/gui/gtk.cthat cover low-level UI — the panel resize handles (12 signals), notebook tab reordering (3), scrollable containers, toast/log widgets, and most importantly the internals ofdt_gui_connect_click()anddt_gui_connect_double_click()themselves. These can't be converted on GTK 3.24 because they involve window-level event propagation, scrolled-window interaction, and the gesture controller creation code that everything else depends on. They stay as-is until the actual GTK4 switch, when the whole helper layer can be replaced, I guess, with native GTK4 APIs.Related: #20433