When we have pending motion events, instead of delivering them
directly, request the new FLUSH_EVENTS phase of the frame clock.
This allows us to compress repeated motion events sent to the
same window.
In the FLUSH_EVENTS phase, which occur at priority GDK_PRIORITY_EVENTS + 1,
we deliver any pending motion events then turn off event delivery
until the end of the next frame. Turning off event delivery means
that we'll reliably paint the compressed motion events even if more
have arrived.
Add a motion-compression test case which demonstrates behavior when
an application takes too long handle motion events. It is unusable
without this patch but behaves fine with the patch.
https://bugzilla.gnome.org/show_bug.cgi?id=685460
Add the ability to freeze a frame clock, which pauses its operation,
then thaw it again later to resume.
Initially this is used to implement freezing updates when we are
waiting for ConfigureNotify in response to changing the size of
a toplevel.
We need a per-window clock for this to work properly, so add that
for the X11 backend.
https://bugzilla.gnome.org/show_bug.cgi?id=685460
Instead of having gdk_frame_clock_request_frame() have
gdk_frame_clock_request_phase() where we can say what phase we need.
This allows us to know if we get a frame-request during layout whether
it's just a request for drawing from the layout, or whether another
layout phase is needed.
https://bugzilla.gnome.org/show_bug.cgi?id=685460
Some backends do not have slave devices, which means last_slave may be
NULL. Use the current device as the source device if last_slave is NULL
when synthesizing a crossing event.
https://bugzilla.gnome.org/show_bug.cgi?id=692411
We now store the current opacity for all windows. For native windows
we just call into the native implementation whenever the opacity changes.
However, for non-native windows we implement opacity by pushing a
second implicit paint that "stacks" on the existing one, acting as
an opacity group while rendering the window and its children.
This works well in general, although any native child windows will of
course not be opaque. However, there is no way to implement
implicit paint flushing (i.e. draw the currently drawn double buffer
to the window in order to allow direct drawing to the window).
We can't flush in the stacked implicit paint case because there
is no way to get the right drawing behaviour when drawing directly
to the window. We *must* draw to the opacity group to get the right
behaviour.
We currently flush if:
* A widget disables double buffering
* You call move/resize/scroll a window and it has non-native children
during the expose handler
In case this happens we warn and flush the outermost group, so there may
be drawing errors.
https://bugzilla.gnome.org/show_bug.cgi?id=687842
_gdk_display_device_grab_update does not support passing in NULL for the
source device. If we don't have a slave device (saved in the pointer info)
then do not try and use that NULL pointer for the source_device.
This bug appeared in the Wayland backend where we (currently) only have master
devices exposed and as such no slave device is ever saved.
Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=692411
and gdk_window_get_fullscreen_mode() API to allow
applications to specify if a fullscreen window should
span across all monitors in a multi-monitor setup or
remain on the current monitor where the window is
placed.
Fullscreen mode can be either GDK_FULLSCREEN_ON_ALL_MONITORS
or GDK_FULLSCREEN_ON_CURRENT_MONITOR.
https://bugzilla.gnome.org/show_bug.cgi?id=691856
There are cases where crossing events aren't generated by input devices themselves
but rather through programmatical means (windows being moved/hidden/destroyed while
the pointer is on top).
Those events come from X as sourceid=deviceid, and GDK does its deal at lessening
this by setting a meaningful source device on such events, although this caused
some confusion on the mechanism to block/synthesize touch crossing events that
could possibly cause bogus enter events on the new window below the pointer.
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=691572
We no longer support modifying GdkWindow hierarchies during
expose events. This is not working anymore anyway as the
flush operation now does not push already rendered pixels
in the flushed window from the double buffer to the window.
https://bugzilla.gnome.org/show_bug.cgi?id=679144
Avoid copying back partially drawn double-buffer data
when flushing to avoid flicker. This means non double
buffered widgets must draw opaque pixels in its expose
handlers, and that you are not allowed to use direct
rendering (or modify GdkWindow pos/size/order) from
inside the expose handler of a double buffered widget.
See https://bugzilla.gnome.org/show_bug.cgi?id=679144 for more
details
The code was calling _gdk_window_ref_cairo_surface in a few places
where the intent was not to read/write to the surface, but just look
at its type (to e.g. create a similar surface). This is bad, as that
operation causes a flush which may cause unnecessary work and/or
flashing. Instead we just get the impl surface in these cases.
GtkRange was using GDK_POINTER_MOTION_MASK, and it was not
getting any emulated motion events, because we only translate
from GDK_BUTTON_MOTION_MASK to GDK_POINTER_MOTION_MASK, but not
the other way around, and emulated_mask only had
GDK_BUTTON_MOTION_MASK in it. Now we put GDK_POINTER_MOTION_MASK
in emulated_mask and successfully match for windows that
have GDK_POINTER_MOTION_MASK or any of the button motion masks
selected.
This fixes range sliders not following the finger and jumping
to the last position upon release.
Events of type GDK_SCROLL will be received if the client side window
event mask has either GDK_SCROLL_MASK or GDK_SMOOTH_SCROLL_MASK.
GDK_BUTTON_PRESS_MASK has been removed from type_masks[GDK_SCROLL]
as that bit is often set for other-than-scrolling purposes, and
yet have the window receive scroll events. In GTK+, this forces
non-smooth events bubbling, even if the widgets above want smooth
events, and legitimately set GDK_[SMOOTH_]SCROLL_MASK.
If a device provides both smooth and non-smooth events, the latter will be
flagged with _gdk_event_set_pointer_emulated() so the client side window
receives one or the other. If a device is only able to deliver non-smooth
events, those will be sent, so both direction/deltas may need to be handled.
get_event_window() just checked on GDK_TOUCH_MASK, including for emulated
pointer events, so at the very least those should also match evmasks with
no touch events whatsoever
If an active grab kicks in on a different window, _gdk_display_has_device_grab()
would still find the former implicit grab for the window below the pointer, thus
sending events to an unrelated place.
If a grab with GDK_TOUCH_MASK kicks in due to a touch sequence emulating pointer
events, don't mutate the sequence into emitting touch events right away.
Create the backing GdkTouchGrabInfo for touches even if the pointer
emulating touch sequence is already holding an implicit grab on a
window that didn't select for touch events.
the backing GdkTouchGrabInfo will be needed if the overriding device
grab finishes before the touch does in order to send events back to
the implicit grab window. Instead, wait until the touch is physically
finished before removing the matching GdkTouchGrabInfo
GDK will only receive touch events when dealing with a multitouch
device, so these must be transformed to pointer events if the
client-side window receiving the event doesn't listen to touch
events, and the touch sequence the event is from does emulate
the pointer.
If a sequence emulates pointer events, it will result in a
button-press, N motions with GDK_BUTTON1_MASK set and a
button-release event, and it will deliver crossing events
as specified by the current device grab.
These are equivalent to an implicit grab (with !owner_events), so
if the touch leaves or enters the grab window, the other window
won't receive the corresponding counter-event.
If the touch sequence happens on a window with GDK_TOUCH_MASK set,
a GdkTouchGrabInfo is created to back it up. Else a device grab is
only created if the sequence emulates the pointer.
If both a device and a touch grab are present on a window, the later
of them both is obeyed, Any grab on the device happening after a
touch grab generates grab-broken on all the windows an implicit
touch grab was going on.
Anytime a touch device interacts, the crossing events generation
will change to a touch mode where only events with mode
GDK_CROSSING_TOUCH_BEGIN/END are handled, and those are sent
around touch begin/end. Those are virtual as the master
device may still stay on the window.
Whenever there is a switch of slave device (the user starts
using another non-touch device), a crossing event with mode
GDK_CROSSING_DEVICE_SWITCH may generated if needed, and the normal
crossing event handling is resumed.
This commit introduces GDK_TOUCH_BEGIN/UPDATE/END/CANCEL
and a separate GdkEventTouch struct that they use. This
is closer to the touch event API of other platforms and
matches the xi2 events closely, too.
My previous fix for this broke the progress bar in epiphany. This fix
makes it work again, and keeps the gimp bug fixed.
Basically, whenever we do a non-double-buffered rendering we have to
flush the entire window as it might be drawn outside the double
buffering machinery.
This last slave device (stored per master) is used to fill
in the missing slave device in synthesized crossing events
that are not directly caused by a device event (ie due to
configure events or grabs).
We used to set a flushed boolean whenever we flushing double buffered
areas to the window due to a non-db draw. We then read back from the
window if this was set. This broke when we were doing multiple paints
of the same area after a flush as we were re-reading the window each
time, overdrawing what was previously draw.
Sometimes we need to read back the window content into our double
buffer due to rendering a window with alpha when there is
no implicit paint or it has been flushed due to non-db drawing
before.
However, in this case we can't use gdk_cairo_set_source_window as
it might trigger an implicit paint flush as we detect what we
think is a direct non-double buffered window draw operation, which
will flush the implicit paint operation that we're just setting up.
To fix this we use the raw gdk_window_ref_impl_surface operation
to get the source surface.
There was a sign issue in a coordinate transform that made us
flush the wrong region when flushing an implicit paint.
The non-double buffered drawing would then be drawn over the
right area, but then at the end of the implicit paint this
would be overdrawn with the area we didn't properly remove
from the implicit paint.
Also, the translation from window coords to impl window
coords is now done before removing any active double
buffered paints, as these are also in impl window coords.
With the changes in default CSS to make the default background transparent
we ran into issues where intermediate GdkWindow (for instance the
view_window in GtkViewport) where we didn't set an explicit background
(because before they were always covered). So instead of showing throught
the transparent windows were showing the default backgroind of the intermediate
window (i.e. black).
With this change we also needed to fix GtkViewport, as it was previously
relying on the bin and view windows to cover widget->window so that the
border was not visible if shadow_type was NONE.
==23282== 64 bytes in 2 blocks are definitely lost in loss record 8,069 of 13,389
==23282== at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==23282== by 0x39A1C3E2EA: cairo_region_create (cairo-region.c:196)
==23282== by 0x6D9AF3D: recompute_visible_regions_internal (gdkwindow.c:964)
==23282== by 0x6D9B4B8: recompute_visible_regions (gdkwindow.c:1126)
==23282== by 0x6DA3450: gdk_window_hide (gdkwindow.c:5689)
==23282== by 0x6D9CED9: _gdk_window_destroy_hierarchy (gdkwindow.c:2042)
==23282== by 0x6D9D040: gdk_window_destroy (gdkwindow.c:2109)
==23282== by 0x655B5E4: gtk_entry_unrealize (gtkentry.c:3012)
==23282== by 0x7068BF3: g_cclosure_marshal_VOID__VOID (gmarshal.c:85)
==23282== by 0x706710B: g_type_class_meta_marshal (gclosure.c:885)
==23282== by 0x7066DF9: g_closure_invoke (gclosure.c:774)
==23282== by 0x7080585: signal_emit_unlocked_R (gsignal.c:3340)
==23282== by 0x707F619: g_signal_emit_valist (gsignal.c:3033)
==23282== by 0x707FB71: g_signal_emit (gsignal.c:3090)
==23282== by 0x679E243: gtk_widget_unrealize (gtkwidget.c:4458)
==23282== by 0x64E83C7: gtk_bin_forall (gtkbin.c:172)
==23282== by 0x6548BBD: gtk_container_forall (gtkcontainer.c:2014)
==23282== by 0x67A966D: gtk_widget_real_unrealize (gtkwidget.c:10253)
==23282== by 0x672D002: gtk_tool_item_unrealize (gtktoolitem.c:474)
==23282== by 0x7068BF3: g_cclosure_marshal_VOID__VOID (gmarshal.c:85)
https://bugzilla.gnome.org/show_bug.cgi?id=666552
When an implicit paint is flushed during expose, e.g. because a
non-double buffered widget is painting, make sure to copy the existing
data from the window surface we rendered before flushing back to the
paint surface, instead of using an empty base.
Code was already handling that (and said so in the comment), but only
when no implicit paint was used at all, and not in the case when it's
flushed mid-expose.
gdk_window_get_update_area is supposed to get the area where things
need painting, and remove them from the update areas. However, if
some area is covered by other windows with an alpha background we
can't just expect whatever the app choses to render in the update
area as correct, so we don't actually remove these areas, meaning
they will get correctly rendered when we get to the expose handlers.
gdk_window_move_region doesn't move children, so we can't copy
transparent child window regions with copyarea, so we remove these
from the copy region.
We track the areas that have alpha coverage so that we can
avoid using these as sources when copying window contents.
We also don't remove such areas from the clipping regions so
that they are painted both by parent and child.
This cleans up the expose handling a bit by using the existing
clip regions, and it allows us later to use painters algorithm
to do transparent windows.
This state means that the toplevel window is presented as focused to the user,
i.e with active decorations under an X11 window manager.
If the GDK backend doesn't implement this flag, it will just remain set after
mapping the window.
https://bugzilla.gnome.org/show_bug.cgi?id=661428
The new file defines GDK_DISABLE_DEPRECATION_WARNINGS so it can happily
use deprecated APIs.
This commit moves those functions there that use deprecated functions
and currently cause warnings.
With this commit, GDK compiles without deprecation warnings.
Those if() blocks don't have any reason being there, as x and y are not
pointers. If the window is destroyed, just set the out values to zero
and return.
As seen in valgrind:
==3306== Conditional jump or move depends on uninitialised value(s)
==3306== at 0x624C74F: gdk_window_get_root_coords (gdkwindow.c:6933)
==3306== by 0x5E193C3: gtk_tooltip_show_tooltip (gtktooltip.c:1160)
==3306== by 0x5E19C05: tooltip_popup_timeout (gtktooltip.c:1282)
==3306== by 0x623B102: gdk_threads_dispatch (gdk.c:754)
==3306== by 0x8592F3A: g_timeout_dispatch (gmain.c:3907)
==3306== by 0x859174C: g_main_context_dispatch (gmain.c:2441)
==3306== by 0x8591F47: g_main_context_iterate (gmain.c:3089)
==3306== by 0x8592494: g_main_loop_run (gmain.c:3297)
==3306== by 0x5D2E501: gtk_main (gtkmain.c:1362)
==3306== by 0x5C5652F: gtk_application_run_mainloop
(gtkapplication.c:115)
==3306== by 0x7C47C9D: g_application_run (gapplication.c:1323)
==3306== by 0x447B5F: main (nautilus-main.c:102)
==3306== Uninitialised value was created by a stack allocation
==3306== at 0x624D48A: gdk_window_get_device_position
(gdkwindow.c:4952)
For client-side windows, we need to queue a repaint when the background
changes. For native windows, the windowing system does take care of it,
but client-side windows are our own, so we gotta do it manually.
https://bugzilla.gnome.org/show_bug.cgi?id=652102
It could be the case that gdk_window_set_cursor() is called on
pointers not yet known to the device tracking code in GdkDisplay,
so update the cursor on all master pointers.
The code actually updating the cursor for the given window has
been refactored out to gdk_window_set_cursor_internal(), used
in gdk_window_set_device_cursor() as well, which makes it handle
root/foreign windows too.
https://bugzilla.gnome.org/show_bug.cgi?id=649313
This incorrect assignment would cause asynchronous aborts from the X server
(they would occur if for instance, an offscreen GtkTreeView calls
gtk_widget_error_bell()).
GDK_NATIVE_WINDOWS was a way to keep some old apps running that did weird
things in gtk2. We should not have to carry this forwards in gtk 3.x.
We do however keep a g_warning() call reminding people of this fact to
ease debugging when they try to port their applications.
https://bugzilla.gnome.org/show_bug.cgi?id=644119