Commit Graph

5018 Commits

Author SHA1 Message Date
Owen W. Taylor
d203f63641 GdkFrameClockIdle: remove timeouts in dispose
When a frame clock is disposed, remove active timeouts; also get
rid of the last traces of an unused GTimer.
2013-02-15 22:28:52 -05:00
Jasper St. Pierre
61f6463b96 Update gdk.symbols 2013-02-15 19:48:56 -05:00
Jasper St. Pierre
b777a16b06 gdkframeclockidle: Don't expose sleep_source source funcs 2013-02-15 19:48:56 -05:00
Jasper St. Pierre
bf7804db64 gdkframeclock: Fix doc comments 2013-02-15 19:33:10 -05:00
Owen W. Taylor
e2705544ab Don't compress motion events for different devices
A switch of device may be significant for an application, so don't
compress motion events if they are for different devices. This simple
handling isn't sufficient if we have competing event streams from
two different pointer events, but we don't expect this case to be
common.
2013-02-14 17:19:53 -05:00
Owen W. Taylor
ff935c5738 Ignore window manager protocol messages for destroyed windows
If we get, for example, a _NET_WM_FRAME_DRAWN or _NET_WM_PING
message on a destroyed window, then we should just ignore it.
2013-02-14 17:19:53 -05:00
Owen W. Taylor
6e986afbae Small documentation fixes for frame synchronization
Found by Benjamin Otte
2013-02-14 17:19:53 -05:00
Owen W. Taylor
4c9749ee9e gdk_frame_clock_get_frame_time(): use gint64 for time 2013-02-14 17:19:53 -05:00
Owen W. Taylor
815ef1bcc0 GdkFrameClock: update documentation 2013-02-14 17:19:53 -05:00
Owen W. Taylor
c37de57f14 GdkFrameTimings: add documentation 2013-02-14 17:19:52 -05:00
Owen W. Taylor
bb11195ec0 GdkFrameClock: Clean up the public API
* remove gdk_frame_clock_get_frame_time_val(); a convenience
  function that would rarely be used.
* remove gdk_frame_clock_get_requested() and
  ::frame-requested signal; while we might want to eventually
   be able to track the requested phases for a clock, we don't
  have a current use case.
* Make gdk_frame_clock_freeze/thaw() private: they are only
  used within GTK+ and have complex semantics.
* Remove gdk_frame_clock_get_last_complete(). Another convenience
  function that I don't have a current use case for.
* Rename:
  gdk_frame_clock_get_start() => gdk_frame_clock_get_history_start()
  gdk_frame_clocK_get_current_frame_timings() => gdk_frame_clock_get_timings()
2013-02-14 17:19:52 -05:00
Owen W. Taylor
d5edf9c072 GdkFrameTimings: strip down to a minimal public API
Since we're not exporting the ability to create your own frame
clock for now, remove the setters for GdkFrameTimings fields.
Also remove all setters and getters for fields that are more
about implementation than about quantities that are meaningful
to the applcation and just access the fields directly within
GDK.
2013-02-14 17:19:52 -05:00
Owen W. Taylor
515e5f74aa Merge GdkFrameHistory into GdkFrameClock
Now that GdkFrameClock is a  class, not interface, there's no real advantage
to splitting the frame history into an aggregate object, so directly
merge it into GdkFrameClock.
2013-02-14 17:19:52 -05:00
Owen W. Taylor
5f2d1654a5 Change GdkFrameClock from an interface to a class
It's unlikely that anyone will want to have, say, a GtkWidget that
also acts as a GdkFrameClock, so an abstract base class is as
flexible as making GdkFrameClock an interface, but has advantages:

 - If we decide to never make implementing your own frame clock
   possible, we can remove the virtualization.
 - We can put functionality like history into the base class.
 - Avoids the oddity of a interface without a public interface
   VTable, which may cause problems for language bindings.
2013-02-14 17:19:52 -05:00
Owen W. Taylor
be22b9fbb9 GdkWindow: make the frame clock an inherent property of the window
Instead of making the frame clock a settable property of a window, make
toplevel windows inherently have a frame clock when created (getting
rid of the default frame clock.) We need to create or destroy frame
clocks when reparenting a window to be a toplevel, or to not be a
toplevel, but otherwise the frame clock for a window is immutable.
2013-02-14 17:19:52 -05:00
Owen W. Taylor
449e8c8856 Add gtk_widget_add_tick_callback(), remove GtkTimeline, etc.
Add a very simple GtkWidget function for an "tick" callback, which
is connected to the ::update signal of GdkFrameClock.

Remove:

 - GtkTimeline. The consensus is that it is too complex.
 - GdkPaintClockTarget. In the rare cases where tick callbacks
    aren't sufficient, it's possible to track the
    paint clock with ::realize/::unrealize/::hierarchy-changed.

GtkTimeline is kept using ::update directly to allow using a GtkTimeline
with a paint clock but no widget.
2013-02-14 17:19:52 -05:00
Owen W. Taylor
06c4598fc5 GdkX11DeviceManagerXI2: handle focus events not on a known window
If we get a focus event for a X window we don't recognize, just
ignore it and avoid a g-critical when
_gdk_device_manager_core_handle_focus() is called with a NULL window.
2013-02-14 17:19:51 -05:00
Owen W. Taylor
645b5f398d Reimplement _NET_WM_SYNC_REQUEST inside X11 backend
Deprecate gdk_window_enable_synchronized_configure() and
gdk_window_configure_done() and make them no-ops. Implement the
handling of _NET_WM_SYNC_REQUEST in terms of the frame cycle -
we know that all processing will be finished in the next frame
cycle after the ConfigureNotify is received.
2013-02-14 17:19:51 -05:00
Owen W. Taylor
8865ebcc80 Fix up for newer draft of wm-spec
* 64-bit quantities are consistently ordered low-32-bits / high-32-bits
* data.l[4] in _NET_WM_SYNC_REQUEST indicates which counter to update
2013-02-14 17:19:51 -05:00
Owen W. Taylor
fb44ea8a85 Add gdk_frame_timings_get_predicted_presentation_time()
For an operation like synchronizing audio to video playback, we need to
be able to predict the time that a frame will be presented. The details
of this depend on the windowing system, so make the backend predict
a presentation time for ::begin-frame and set it on the GdkFrameTimings.

The timing algorithm of GdkFrameClockIdle is adjusted to give predictable
presentation times for frames that are not throttled by the windowing
system.

Helper functions:

 gdk_frame_clock_get_current_frame_timings()
 gdk_frame_clock_get_refresh_info()

are added for operations that would otherwise be needed multiple times
in different locations.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:51 -05:00
Owen W. Taylor
8855bf052d Add GDK_DEBUG=frames
Add a debug option to print out detailed statistics about each frame drawn.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:51 -05:00
Owen W. Taylor
0def26ecf1 GdkWindowX11: Communicate gdk_frame_timings_get_slept_before() to the compositor
We want the compositor to do different things for frames where
"slept before" is TRUE. Communicate to the compositor that
frame is a no-delay frame (slept_before=FALSE) by ending the frame
by increasing the counter value by 1, and that the frame is a
normal frame (slept_before=TRUE) by increasing the counter value
by 3.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:50 -05:00
Owen W. Taylor
58b5811d03 Add gdk_frame_timings_get/set_slept_before()
Add functions that tell us whether the main loop slept before we drew
a frame. Blocking with the frame clock frozen doesn't count as sleeping.
We'll use this to advertise to the compositor whether we
are drawing as fast as possible (and it should do the same) or timing
frames carefully (and it should do the same.)

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:50 -05:00
Owen W. Taylor
dc6dedab4d GdkFrameClockIdle: don't start the tiemout/idle when in a frame
Don't start the idle if we're in the middle of painting a frame -
this will prevent us from getting the timing right when starting
the idle after the frame.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:50 -05:00
Owen W. Taylor
15ee04c66f Add GdkFrameHistory and GdkFrameTimings, handle _NET_WM_FRAME_TIMINGS
In order to be able to track statistics about how well we are drawing,
and in order to be able to do sophisticated things with frame timing
like predicting per-frame latencies and synchronizing audio with video,
we need to be able to track exactly when previous frames were drawn
to the screen.

Information about each frame is stored in a new GdkFrameTimings object.
A new GdkFrameHistory object is added which keeps a queue of recent
GdkFrameTimings (this is added to avoid further complicating the
implementation of GdkFrameClock.)

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:50 -05:00
Owen W. Taylor
d761df7e0c GdkWindowX11: Only start a frame when we emit damage
Instead of communicating the start of a frame to the window manager
as soon as we begin a frame, start a frame only when we know we've
actually created damage to the contents of a window.

(This uses cairo_set_mime_data() as a notification mechanism - a
clever suggestion from Uli Schlachter.)

The advantage of this is that we aren't forcing the compositor to
do a frame cycle and send _NET_WM_FRAME_DRAWN - depending on how the
compositor is structured that might either cause it to do extra
work or it might send _NET_WM_FRAME_DRAWN early and upset frame
timing.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:50 -05:00
Owen W. Taylor
e4aa9f05ae GdkDisplay: handle multiple calls to _gdk_display_pause_events()
Since events can be paused independently for each window during processing,
make _gdk_display_pause_events() count how many times it is called
and only unpause when unpause_events() is called the same number of
times.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:50 -05:00
Owen W. Taylor
d446dda920 gdk_display_get_event: don't unqueue events from the windowing system when paused
Unqueuing events from the windowing system when paused could result
in weird reordering if event filters resulted in application-visible
behavior. Since we now resume events when the frame clock is frozen,
we now no longer count on low-level event handling running while
event handling is paused.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:50 -05:00
Owen W. Taylor
3cef97f10d GdkFrameClock: Reverse order of resume-events and afterpaint
Keeping events paused after the end of a frame put us in a
weird state where we had to process and queue events - so that
we would get the message from the compositor - but not deliver
them. Instead resume events before ending the frame.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:49 -05:00
Owen W. Taylor
a69285da08 Compress motion synchronized with the paint cycle
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
2013-02-14 17:19:49 -05:00
Owen W. Taylor
344a69880a Add an UPDATE phase and GdkFrameClockTarget, use for GtkStyleContext
Switch GtkStyleContext to using GdkFrameClock. To do this, add a new
UPDATE phase to GdkFrameClock.

Add a GdkFrameClockTarget interface with a single set_clock() method,
and use this to deal with the fact that GtkWidget only has a frame
clock when realized.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:48 -05:00
Owen W. Taylor
7dfa412188 GdkFrameClockIdle: add throttling to 60fps
If the backend is throttling paints, then the frame clock will be
frozen at the end of the frame. If not, then we need to add throttling,
so wait until 16ms after the start of the frame before beginning the
next frame.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:48 -05:00
Owen W. Taylor
6557a775df GdkWindowX11: start off with an odd frame-counter value
By starting with an odd frame counter value, we make the mapping
and initial paint of the window an atomic operation, avoiding
any visual artifacts from an unpainted window.

Possible improvement: start the frame when doing gdk_window_show(),
so that the same improvement occurs for windows that were previously
shown and are being mapped again.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:48 -05:00
Owen W. Taylor
355e305c16 Freeze the update counter for unmapped windows
When a window is unmapped, freeze its frame clock. This avoids doing
unnecessary work, but also means that we won't block waiting for
_NET_WM_FRAME_DRAWN messages that will never be received since the
frame ended while the window was withdrawn.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:48 -05:00
Owen W. Taylor
8a6895fe52 Use _NET_WM_FRAME_DRAWN to synchronize frame drawing
As part of the extended _NET_WM_SYNC_REQUEST_COUNTER protocol,
we get a _NET_WM_FRAME_DRAWN message for each frame we draw. Use this
to synchronize the updates we are doing with the compositing manager's
drawing, and ultimately with with display refresh.

We now set the sync request counters on all windows, including
override-redirect windows, since it is also useful to do synchronized,
atomic updates for such windows.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:48 -05:00
Owen W. Taylor
69f457426a Switch to an extended form of _NET_WM_SYNC_REQUEST_COUNTER
By exporting two XSync counters on a toplevel window, we subscribe
to an extended form of the _NET_WM_SYNC_REQUEST_COUNTER protocol,
where the window manager can initiate an atomic frame, as previously,
but the application can also do so by incrementing the new counter to
an odd value, and then to an even value to finish the frame.

See:
https://mail.gnome.org/archives/wm-spec-list/2011-October/msg00006.html

The support for 64-bit integers that GLib requires is used to
simplify the logic.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:48 -05:00
Owen W. Taylor
1824796bfb GdkFrameClock: add freeze/thaw
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
2013-02-14 17:19:48 -05:00
Owen W. Taylor
c4545cc5d4 GdkFrameClock: Make the phase explicit when requesting the frame
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
2013-02-14 17:19:48 -05:00
Owen W. Taylor
7753883add Use GdkFrameClock for relayout
Add a ::layout signal to GdkFrameClock and use it instead of an idle
handler to drive the restyling and relayout of containers.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:47 -05:00
Owen W. Taylor
77bac0d6ae Add GdkFrameClock
Add an object GdkFrameClock that we associate with a GdkWindow.
This tracks when the window needs to be repainted, and will also
be used for other operations in the future like relayout and
updating animations.

Based on a patch from Havoc Pennington:

 https://mail.gnome.org/archives/gtk-devel-list/2010-October/msg00004.html

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:47 -05:00
Owen W. Taylor
001f960a43 GdkDisplayX11: Don't use substructure events in internal accounting
We may receive events because SubstructureNotifyMask has been selected
for the root window. (Most likely, this would occur because GTK+
is being used inside a window manager like Metacity or Mutter.)
This can confuse various types of internal accounting, so detect
such events and comprehensively ignore them for GDK's internal
purposes. We still need to generate GDK events for these cases
because you can select for substructure events with
GDK_SUBSTRUCTURE_MASK.

https://bugzilla.gnome.org/show_bug.cgi?id=685460
2013-02-14 17:19:47 -05:00
Rob Bradford
4e1d999940 wayland: Add support for output device removal
Since we only receive an object id for the removed object we must try and
remove that from the list of devices based on that id.
2013-02-14 13:28:07 +00:00
Rob Bradford
fab808f92c wayland: Add basic multiple output support
Store the wl_output pointer within the the GdkWaylandMonitor structure.
2013-02-14 13:02:27 +00:00
Cosimo Cecchi
c896adc9e9 settings: add a gtk-recent-files-enabled GtkSetting
Backed by an XSetting, so g-s-d can set it according to the GSettings
value.

https://bugzilla.gnome.org/show_bug.cgi?id=693724
2013-02-13 12:06:43 -05:00
Jan Arne Petersen
ff2a387154 wayland: Handle wl_output in GdkWaylandScreen
Expose information about outputs in GdkScreen (gdk_screen_get_n_monitors
and gdk_screen_get_monitor_*).
2013-02-13 15:52:05 +00:00
Thomas Wood
bfd7137ffb wayland: skip pointer and keyboard events without a surface
Pointer and keyboard events can be received after the surface has been
destroyed, in which case the surface will be NULL.

https://bugzilla.gnome.org/show_bug.cgi?id=693338
2013-02-12 15:30:56 +00:00
Thomas Wood
8568d66a73 gdkwindow: don't use last_slave for the source device if it is NULL
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
2013-02-12 15:30:56 +00:00
Thomas Wood
a8862727c9 wayland: set the "transient inactive" flag on tooltip surfaces
This prevents the tooltip surfaces from taking the focus away from the
parent surface.

https://bugzilla.gnome.org/show_bug.cgi?id=693313
2013-02-12 15:30:56 +00:00
Alexander Larsson
4d3c77f920 gdkwindow: Allow gdk_window_set_opacity on non-native children
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
2013-02-07 11:11:37 +01:00
Alexander Larsson
ada6d81247 gdkwindow: Store the implicit paint in a list
This changes nothing, but lets us later have multiple
implicit paints

https://bugzilla.gnome.org/show_bug.cgi?id=687842
2013-02-07 11:11:37 +01:00