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
constructors which take an object of the same class as its first argument are
mis-detected as method call with "self" argument by the GIR scanner. Using the
new (constructor) annotation from bug 561264, mark some of them as proper
constuctors, so that you can call them with NULL as first argument from
bindings; in particular, this fixes gdk_window_new() and the
gtk_radio_button_new_with*() constructors.
The previous function gdk_drag_get_protocol_for_display() took native
window handles, so it had to be changed. Because it didn't do what it
was named to do (it didn't return a protocol even though it was named
get_protocol) and because it doesn't operate on the display anymore but
on the actual window, it's now called gdk_window_get_drag_protocol().
Moving the direct-access redefinitions of various macros
to gdkprivate-x11.h and use that header throughout in x11/.
Also remove a workaround for a long-fixed X server bug.
Use the grab and ungrab vfuncs from the frontend instead of the
_gdk_windowing wrappers, and move some things around accordingly.
Again, only the X11 backend has been updated, other backends
need to be updated to match.
This commit hides GdkDragContext and GdkDragContextClass, adds
vfuncs for most drag context functionality, and turns the X11 DND
implementation into GdkDragContextX11. We also add vfuncs to
GdkDisplay for gdk_drag_get_protocol and to GdkWindow for
gdk_drag_begin, and implemenet them for X11.
Other backends need similar treatment and are broken now.
Running gnome-shell under valgrind, I saw the attached invalid write.
Basically we can destroy a window during event processing, and the old
window_remove_filters simply called g_free() on the filter, ignoring
the refcount. Then later in event processing we call filter->refcount--,
which is writing to free()d memory.
Fix this by centralizing list mutation and refcount handling inside
a new shared _gdk_window_filter_unref() function, and using that
everywhere.
==13876== Invalid write of size 4
==13876== at 0x446B181: gdk_event_apply_filters (gdkeventsource.c:86)
==13876== by 0x446B411: _gdk_events_queue (gdkeventsource.c:188)
==13876== by 0x44437EF: gdk_display_get_event (gdkdisplay.c:410)
==13876== by 0x446B009: gdk_event_source_dispatch (gdkeventsource.c:317)
==13876== by 0x4AB7159: g_main_context_dispatch (gmain.c:2436)
==13876== by 0x4AB7957: g_main_context_iterate.clone.5 (gmain.c:3087)
==13876== by 0x4AB806A: g_main_loop_run (gmain.c:3295)
==13876== by 0x8084D6B: main (main.c:722)
==13876== Address 0x1658bcac is 12 bytes inside a block of size 16 free'd
==13876== at 0x4005EAD: free (vg_replace_malloc.c:366)
==13876== by 0x4ABE515: g_free (gmem.c:263)
==13876== by 0x444BCC9: window_remove_filters (gdkwindow.c:1873)
==13876== by 0x4454BA3: _gdk_window_destroy_hierarchy (gdkwindow.c:2043)
==13876== by 0x447BF6E: gdk_window_destroy_notify (gdkwindow-x11.c:1115)
==13876== by 0x43588E2: _gtk_socket_windowing_filter_func (gtksocket-x11.c:518)
==13876== by 0x446B170: gdk_event_apply_filters (gdkeventsource.c:79)
==13876== by 0x446B411: _gdk_events_queue (gdkeventsource.c:188)
==13876== by 0x44437EF: gdk_display_get_event (gdkdisplay.c:410)
==13876== by 0x446B009: gdk_event_source_dispatch (gdkeventsource.c:317)
==13876== by 0x4AB7159: g_main_context_dispatch (gmain.c:2436)
==13876== by 0x4AB7957: g_main_context_iterate.clone.5 (gmain.c:3087)
https://bugzilla.gnome.org/show_bug.cgi?id=637464
The old functions to get core pointer and devices list are gone as
well. This slice is entirely replaced internally by multidevice
handling and may just go.
When setting no shape on an unshaped window, nothing changes,
so return early instead of recomputing lots of visibility
information.
Pointed out by Owen Taylor in bug 637156.
This function will enable events for all devices of a given
GdkInputSource, either these available at the time of the call,
or these that are connected in the future.
This function may be used to know the hardware device that triggered
an event, it could resort to the master device in the few cases there's
not a direct hardware device to relate to the event (i.e.: crossing events
due to grabs)
One less magic function. Also refactored it to make it easier to
implement. It now returns TRUE if it beeped and FALSE if it failed to do
so. A default implementation exists that just returns FALSE for all the
backends that can't beep windows (read: everything but X11 with XKB -
and why on earth do keyboard libs implement beeping?)
Trying to get rid of all the _gdk_windowing_something() functions that
we expect backends to magically know about and instead put them in a
proper interface (mostly GdkWindowImplClass).
... instead of _gdk_drawable_ref_cairo_surface() where appropriate.
Also, don't implement the drawable->create_cairo_surface vfunc anymore.
This is in preparation for the split of GdkWindow from GdkDrawable.
You are not allowed to track surfaces from GDK or draw outside of expose
events. So we can remove ugly hacks needed previously. See
https://bugzilla.gnome.org/show_bug.cgi?id=606009 for the introduction
of this workaround.
This is not strictly an API change as GdkDrawable is typedeffed to
GdkWindow, but it changes the header, so I'm marking it as such.
gdk_cairo_create() can only be used with windows these days, so it makes
sense to pass a window. With that, we can alseo remove the
set_cairo_clip() vfunc from GdkDrawable and implement it inside
gdkwindow.c.
An event filter may add or remove filters itself. This patch does
two things to address this case. The first is to take a temporary
reference to the filter while it is being used. The second is
to wait until after the filter function is run before determining
the next node in the list to process. This guards against
changes to the next node. It also does not run functions
that have been marked as removed. Though I'm not sure if this
case can arise.
https://bugzilla.gnome.org/show_bug.cgi?id=635380
This new function takes a GdkRGBA in order to set the background to
an alpha color. Keep in mind that RGBA visuals and a composited environment
are still necessary to have an alpha background displayed.
Add signal GdkWindow::create-surface which allows to use any
surface type as storage for offscreen windows.
Test the new signal in tests/gdkoffscreenbox.c
This previously caused the x11 code to do a XSetWindowBackgroundPixmap
call on a window that was about to be destroyed. And that's not really
useful.
https://bugzilla.gnome.org/show_bug.cgi?id=630864
The feature can and should be implemented manually using
gdk_window_get_background() and Cairo drawing. A non-cairo drawing API
does not make sense in GDK anymore.
Now that we don't create pixmaps anymore, this function is not needed
anymore. The indirection it did previously is now basically moved to
gdk_window_create_similar_surface()
With Cairo 1.10 now having cairo_surface_create_for_rectangle(), we can
use them. No need to create multiple native surfaces for the same X
window (ugh) anymore.
The notion of a source drawable does not make a lot of sense for windows
that are not backed by a drawable, such as GdkOffscreenWindow after
converting it to cairo_surface_t.
Now the window background is a cairo_pattern_t. The backends will try to
set this as good as they can on the windowing system, but no guarantees
are made on wether the windowing system supports the pattern.
Also gets rid of GDK_NO_BG as undefined behavior is not a good idea to
support, and GDK_NO_BG effectively made the window's contents undefined.
It wasn't effectively used in GTK anyway.
This removes gdk_window_shape_combine_mask() and
gdk_window_input_shape_combine_mask(). GdkBitmap is going away and a
replacement exists via the combine_region() functions and
gdk_cairo_region_create_from_surface().
They were added as accessors for 2.22 even though querying the
background wasn't possible previously. As GTK 3.0 will change background
handling, it doesn't make sense at all to expose these getters.
For windows with alpha channel, the previous contents would otherwise
not be erased. Visible for example in the status icon code.
Thanks to Thomas Wood for noticing.
While X11 surfaces can be resized, this is not the case for Quartz
surfaces. Instead of resizing we will invalidate the surface instead.
By giving _gdk_windowing_set_cairo_surface_size() a boolean return
value, we can signal back whether or not resizing was possible. If not
possible, we invalidate the surface.
The window move code needs special attention for multiple reasons:
- invalid areas for expose events need to be modified
- self-copy is not supported by Cairo
- in X11, copying from an overlapped Window might cause unexposed areas
to be copied in, spo expose events for those need to be generated.
This was all special cased in various parts of the code. By making it an
explicit vfunc, we can work around it.