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.
Includes fixing all callers to use the cairo region API instead. This is
usually just replacing the function names, the only difference is
gdk_region_get_rectangles() being replaced by
cairo_region_num_rectangles() and cairo_region_get_rectangle() which
required a bit more work.
https://bugzilla.gnome.org/show_bug.cgi?id=613284
which also works for offscreen windows and their embedder.
Also add gdk_window_get_effective_parent() and
gdk_window_get_effective_toplevel() which are offscreen aware.
This commit was created using a script that searched for all docstrings
containing a parameter and the string 'or %NULL'.
Gdk backends and demos excluded as they are not part of a public API
https://bugzilla.gnome.org/show_bug.cgi?id=610474
We need to do this because otherwise the implicit button grab for this
(native) window will not deliver the button events not selected for
by this window. This is a problem because non-native child windows may
select using a wider event mask, and we can't emulate these events if we
don't get the native events.
Fixes bug #607508
When a cairo surface is requested for direct window access (i.e. not
when double-buffering) we can't really track when the actual drawing happens
as cairo drawing is not virtualized. This means we can't properly flush
any outstanding window moves or implicit paints.
This actually causes problems with e.g. abiword (bug #606009) where they
draw without double-buffering. If you press down it scrolls the window
and then draws the caret, but the caret drawing does not flush the
outstanding move from the scroll, so the caret gets drawn on the wrong
screen.
We fix this by never allowing either implicit paints or outstanding window
moves on impl-windows where any windows related to it has an outstanding
direct cairo surface. Luckily this is not very common so in practice this
doesn't matter much.
It may happen that a window gets destroyed during painting, if so
we should not draw the implicit paint double-buffered pixmap to it
as that will cause a BadDrawable X error.
This fixes bug 600865
The Gdk-custom.c file in gir-repository contained a number of
introspection annotations. Merge those into the GDK source files.
Some documentation was moved from the tmpl/ files to accomodate
the addition of annotations.
https://bugzilla.gnome.org/show_bug.cgi?id=592279
They don't need double buffer combination since they have no
client-side children, and creating pixmaps for them is risky
since they could disappear at any time.
May fix bug 598476 and 603652.
It may happen when turning a client side window into a native window
that the window, or some of its children with the same native parent
have extension events enabled, and thus have an input window enabled
for the native parent which needs to change as the window is made
native.
We fix this by temporarily disabling extension events on all the affected
windows while we create the native window, and then reenable them afterwards.
This fixes: https://bugzilla.redhat.com/show_bug.cgi?id=544624
We don't really need to filter these out, it was just a leftover
safety check to not override the GDK_POINTER_MOTION_MASK.
Furthermore when we changed behaviour to not always select for native
pointer motion it is actually wrong. We'll still get normal motion
events for the toplevel which we will emulate as button motion on the
child, but the button motion mask will not be inherited by implicit
grabs which makes us not get any motion events during grabs.
This fixes bug 601473
When we just invalidate some area from the app we don't need to clear
windows with no exposure mask, because that wouldn't have happened pre-csw
anyway. Additionally we can avoid such clearing for native windows in cases
where the xserver already did the clearing like on exposes or when resizing
toplevels.
This means we don't fully redraw a GtkSocket when it resizes, thus
avoiding flicker in gnome-mplayer as reported in this bug:
https://bugzilla.gnome.org/show_bug.cgi?id=598050
When moving or scrolling a window with native children, there is no
need to expose the areas that are copied by the windowing system
as part of moving/resizing the native windows anyway.
These event types propagate up the hierarchy anyway, so this means
we avoid setting it unnecessarily. This is especially important
for button press event, since only one client can select for this
on each window, causing X errors if two clients do it.
When we grab the pointer we need to request more events than what is
specified, otherwise our event emulation stop working and you won't
e.g. get crossing event unless you specified motion event mask.
F-Spot needs this as it draws on a foreign (screensaver) window, which
used to work.
I believe this is safe, because in all typical cases the expose
mask will not be set, so we won't do anything, and its what we used to
do.
If we move, resize or otherwise change a window from inside a (double
buffered) expose handler we can run into issues with double buffered
paints that have already been ended but have not yet been commited
to the window from the implicit paint pixmap.
For instance, any copies of source regions due to a window scroll need
to take these into account, and any operation that causes some drawing at
a destination covered by the implicit paint region would be overdrawn
when the implicit paint is ended.
So, before we do any window-hierarchy changing operation while an implicit
paint is in effect we flush all moves and already commited paints.
When a window is moved or resized from a double-buffered expose handler
we can't really just copy the window region around, as the window
will be overdrawn with the double buffered region when the expose returns.
Instead we remove all regions with outstanding implicit paints from the
region to be copied and just mark this area as invalid to be redrawn
later.
This fixes bug 594880.
Its not correct for recurse gdk_window_process_updates_internal, as
the outer instance will overdraw the inner. So, protect against
gdk_window_process_updates() being called while in an expose
handler.
This shouldn't be a repaint problem, as eventually the idle handler
will cause the updates to be processed.
We used to handle zero height/width specially in the non-double buffered
case due to the weird behaviour of XClearArea in this case. However
this is undocumented, incompatible with what happens on double-buffered
drawing, and just not a good API. So, we drop this behaviour, having
fixed gtkclist.c which used this.
There are two issues here. First of all an ignored update didn't
use to unset update_idle which could cause all further idle repaints
to be ignored. (Bug #591583)
Secondly, if we ignore the process_all_updates we may end up not updating
the windows in update_windows unless something else triggers an update.
So, we handle this by checking for recursions and scheduling a new update
at the end of the outermost process_all_updates.
The check for a possible implicit paint flush before queueing an
antiexposure was wrong. An implicit flush doesn't actually NULL
the implicit paint, se we have add a flag to explicitly track if
it is flushed.
Passing region into _gdk_gc_set_clip_region_internal takes ownership,
so don't use it after that. We can just as well just move the usage
above the call.
For toplevels, never apply clip as shape, instead apply shape.
This way we don't have to re-set it all the time as the window size
changes. Furthermore, this change fixes unsetting a shape on a
toplevel window which didn't actually unset the shape before.
Additionally we never apply clips as shape if the shape would just
be the same as the regular window size. This means we won't unnecessarily
add a useless shape to most native child windows (and additionally this
helps apps that do weird X stuff that don't expect these shaped windows).
I.e. we use:
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
And then use impl_iface instead of the full macro when calling vfuncs.
Also, in some places we avoid getting the iface multiple times.
For instance, two clients selecting for button events can cause BadAccess.
This fixes bug 592624, where a gdk_window_reparent caused us to re-set
the event mask, breaking the workaround for the mozilla BadAccess bug.
When updating the clip region on cairo context (due to window changes or
paints of different sizes) we reset the old clip region, but this was
erronously done inside a cairo_save/cairo_restore pair, which made the
reset not take effect.
This fixes bug #592263.
Instead of doing some magic in gdk_draw_drawable() to avoid double
offsetting when calling gdk_draw_drawable on the impl we call
the vfunc directly on the impl. Thus removing the weird magic from
gdk_draw_drawable().
I tested this with the testgtk test "text", where if the original magic
code is disabled typing a newline in the middle of a text line causes
the double offset issue to appear.
Some applications make weird assumtions on Gtk+ that do not work anymore
with the new client-side windows support. For instance SWT/Eclipse reorders
the stacking order of the X windows directly without telling gdk this,
which breaks gdk drawing as gdk now relies on knowing the stacking order
for window clipping.
This introduces a GDK_NATIVE_WINDOWS environment variable, which if set
causes Gtk+ to always use native windows. Its more compatible with
pre-csw Gtk+ behaviour if you do weird X-specific hacks, although it does
limit the size of GdkWindows to 65535x65535.
gdk_window_get_geometry calls the native function for all non-native
windows. This returns coords relative to the native parent. We need
to convert this to be relative to the client side parent.
This fixes DnD coordinates in firefox (bug 588437).
If antiexposures are queued and then we do the outstanding moves
we will queue translations that will affect incomming exposes
wrongly wrt the antiexposure. So, make sure we process the outstanding
moves before doing the antiexposure.
Additionally this commit adds a bunch of comments about how the
expose handling works and fixes a small bug that made us always
flush outstanding moves a little to early than necessary.
Apps may change the window hierarchy while recursing over it by
destroying windows from the expose event handler. We need to copy
the children list and ref all the children while recursing.
This fixes some crashers in gedit (bug #589367, bug #591434)
The X11 queue_translation operation uses NextRequest to get the serial
of the XCopyArea operation where the translation should end. However,
if the gc passed to gdk_draw_drawable has a non-flushed clip region
(which it commonly has now for the window clipping) then the next
operation will be the GC flush, not the XCopyArea.
To handle this right we now pass in the GC to be used to
queue_translation and ensure that it is flushed before calling
NextRequest().
When we copy the region we need to also re-expose the areas of
the copied region that was not also in the destination.
And, we need to do this invalidation after the move, as the
move also moves any invalid area.
If there are outstanding moves in an area that intersects
the source of an outstanding move we need to move the invalid
area correspondingly, otherwise we will expose the wrong area
as the outstanding move copy will happen before we expose
the invalid area.
When moving an area we move any invalid region in this area to the
new place, but there really is no need to remove the old invalid
area as it would just be invalidated again (being newly exposed).
This extends the usage of the native clear region call such that its
called also for windows that have parent relative background all the
way up to a native window. That way we get true background relative
background clearing even to a foreign parent, which means that some
transparent notification icons look right again.
This moves the native show/hide calls to the generic code
for calculating viewable rather than in its own separate code
called from gdk_window_show/hide. This simplifies the code a bit,
but most significantly it means things are correctly shown when
they become viewable for other reasons than a show/hide call.
For instance, this fixes bug 590442 (gvim embedding) where the
toplevel GtkPlug is mapped by the embedder and we didn't previously
pick up that the native children became viewable and should be shown.
We used to invalidate the whole window when raised, but this is
unnecessary much, we now just invalidate the visible area minus the
previously visible area.
This also fixes a problem where expose calling raise caused a loop (#588438)
This never worked before csw since the root window is never
set as IS_MAPPED, but with the new viewable check (which is
true for the root window) we could erronously queue exposes
on the root window.
This happened unexpectedly in bug 589369, where metacity
got a GraphicsExpose event on the root window due to some
graphics operation, queueing an expose which would be handled
by clearing that area. That is fixed with this commit.
We get the real pixmap size and use as cairo surface size rather
than doing some magic to try to get clipping on the right hand size
(and the magic looks wrong anyway).
The previous code could result in the width/height being to big for
the cairo 28.4 fix point size and thus not drawing anything.
This fixes bug #588076.