This is a lump commit that is fairly difficult to break down without
either breaking bisecting or breaking the test cases.
The new design for handling X11 event translation works this way:
- ClutterBackend::translate_event() has been added as the central
point used by a ClutterBackend implementation to translate a
native event into a ClutterEvent;
- ClutterEventTranslator is a private interface that should be
implemented by backend-specific objects, like stage
implementations and ClutterDeviceManager sub-classes, and
allows dealing with class-specific event translation;
- ClutterStageX11 implements EventTranslator, and deals with the
stage-relative X11 events coming from the X11 event source;
- ClutterStageGLX overrides EventTranslator, in order to
deal with the INTEL_GLX_swap_event extension, and it chains up
to the X11 default implementation;
- ClutterDeviceManagerX11 has been split into two separate classes,
one that deals with core and (optionally) XI1 events, and the
other that deals with XI2 events; the selection is done at run-time,
since the core+XI1 and XI2 mechanisms are mutually exclusive.
All the other backends we officially support still use their own
custom event source and translation function, but the end goal is to
migrate them to the translate_event() virtual function, and have the
event source be a shared part of Clutter core.
When we handle Expose events we try and queue a clipped redraw of the
stage, but for some reason we were also redundantly calling
clutter_actor_queue_redraw for the stage which would negate the request
to queue a clipped redraw.
* private-cleanup:
Add copyright notices
Clean up clutter-private.h/6
Clean up clutter-private.h/5
Clean up clutter-private.h/4
Clean up clutter-private.h/3
Clean up clutter-private.h/2
Clean up clutter-private.h/1
This is a workaround for a race condition when resizing windows while
there are in-flight glXCopySubBuffer blits happening.
The problem stems from the fact that rectangles for the blits are
described relative to the bottom left of the window and because we can't
guarantee control over the X window gravity used when resizing so the
gravity is typically NorthWest not SouthWest.
This means if you grow a window vertically the server will make sure to
place the old contents of the window at the top-left/north-west of your
new larger window, but that may happen asynchronous to GLX preparing to
do a blit specified relative to the bottom-left/south-west of the window
(based on the old smaller window geometry).
When the GLX issued blit finally happens relative to the new bottom of
your window, the destination will have shifted relative to the top-left
where all the pixels you care about are so it will result in a nasty
artefact making resizing look very ugly!
We can't currently fix this completely, in-part because the window
manager tends to trample any gravity we might set. This workaround
instead simply disables blits for a while if we are notified of any
resizes happening so if the user is resizing a window via the window
manager then they may see an artefact for one frame but then we will
fallback to redrawing the full stage until the cooling off period is
over.
Instead of triggering a full stage redraw for Expose events we use the
geometry of the exposed region given in the event to queue a clipped
redraw of the stage.
If we have XKB support then we should be using it to turn on the
detectable auto-repeat; this allows avoiding the peeking trick
that emulates it inside the event handling code.
Now that we have private, per-event platform data, we can start putting
it to good use. The first, most simple use is to store the key group
given the event's modifiers. Since we assume a modern X11, we use XKB
to retrieve it, or we simply fall back to 0 by default.
The data is exposed as a ClutterX11-specific function, within the
sanctioned clutter_x11_* namespace.
A typo in clutter-event.c meant that the wrong struct location could be
used for the input device of key events. Also, a typo in the X11 event
code meant that key-presses would come from the pointer device (releases
would still come from the keyboard device).
The Clutter X11 backend now passes all events through
_cogl_xlib_handle_event. This function can now internally be hooked
with _cogl_xlib_add_filter. These are added to a list of callbacks
which are all called in turn by _cogl_xlib_handle_event. This is
intended to be used internally in Cogl by any parts that need to see
Xlib events.
Cogl now also has an internally exposed function to set a pointer to
the Xlib display. This is stored in a global variable. The Clutter X11
backend sets this.
_cogl_xlib_handle_event and _cogl_xlib_set_display can be removed once
Cogl gains a proper window system abstraction.
Whether events come from the main loop source or from
clutter_x11_handle_event(), we need to feed them to the backend
virtual handle_event function. This fixes problems with clients
using clutter_x11_handle_event() hanging because
GLXBufferSwapComplete events aren't received.
http://bugzilla.openedhand.com/show_bug.cgi?id=2101
Since using addresses that might change is something that finally
the FSF acknowledge as a plausible scenario (after changing address
twice), the license blurb in the source files should use the URI
for getting the license in case the library did not come with it.
Not that URIs cannot possibly change, but at least it's easier to
set up a redirection at the same place.
As a side note: this commit closes the oldes bug in Clutter's bug
report tool.
http://bugzilla.openedhand.com/show_bug.cgi?id=521
The DeviceManager class should be abstract in Clutter, and implemented
by each backend, as different backends will have different ways to
detect, initialize and list devices; the X11 backend alone has *two*
ways of dealing with devices.
This commit makes DeviceManager an abstract class and delegates the
device initialization and enumeration to per-backend sub-classes.
The responsible for creating the device manager is, obviously, the
backend singleton.
The X11 and Win32 backends have been updated to the new layout; the
Win32 backend has been updated blindly, so it might require additional
testing.
ConfigureNotify is delivered on window movements too, but there is no
need to queue a relayout on these as the viewport hasn't changed size.
Check for the window actually changing size on ConfigureNotify before
queueing a relayout.
This fixes laggy window movement when moving a window in response to
Clutter mouse motion events.
Setting/unsetting fullscreen on a mapped or unmapped window now works
correctly.
If you unfullscreen a window that was initially full-screened, it will
unset the fullscreen hint and the WM will likely push the size down to
the largest valid size.
If the window was previously un-fullscreened, Clutter will restore the
previous size.
Fullscreening also now works if the WM switches the hint without the
application's knowledge (as happens when you resize a window to the size
of the screen, for example, with stock metacity).
When we resize, we relied on the stage's allocate to re-initialise the
GL viewport. Unfortunately, if we resized within Clutter, the new size
was cached before the window is actually resized, so glViewport wasn't
being called after resizing (some of the time, it's a race condition).
Change the way resizing works slightly so that we only resize when the
geometry size doesn't match our preferred size, and queue a relayout on
ConfigureNotify so the glViewport gets called.
Also change window creation slightly so that setting the size of a
window before it's realized works correctly.
If your OpenGL driver supports GLX_INTEL_swap_event that means when
glXSwapBuffers is called it returns immediatly and an XEvent is sent when
the actual swap has finished.
Clutter can use the events that notify swap completion as a means to
throttle rendering in the master clock without blocking the CPU and so it
should help improve the performance of CPU bound applications.
The extension keyboard support in XInput 1.x is hopelessly broken.
Nevertheless, it's possible to use some bits of it, as we prefer the
core keyboard events to the XInput events, thus at least having proper
handling for X11 key events on the Stage window.
The XI 1.0 layer is complementary to the X11 core devices handling; this
means that core events will still be emitted for the core pointer and
keyboard devices, and that secondary (floating) devices should be
handled on top of that.
Thus, the XI event handling code should be executed (if explicitly
compiled in and enabled) if the core device events have not been parsed.
Note: this is going away with XI2, which completely replaces both core and
XI1 events.
Even with XInput support we should always register core devices. This
allows us to handle enter and leave events correctly on the Stage and
to have a working XInput 1.x support in Clutter.
Instead of overloading the device id of 0 and 1 we should treat the core
devices as special, and have a pointer inside the X11 backend singleton
structure, for fast access.
If the user presses a button on a pointer device and then moves out the
Stage X11 will emit the following events:
LeaveNotify ➔ MotionNotify ... ➔ ButtonRelease ➔ LeaveNotify
The second LeaveNotify differs from the first by the state field.
Unfortunately, ClutterCrossingEvent doesn't have a modifier_state field
like other events, so we cannot provide a way for programmatically
distinguishing them from a Clutter perspective. This is also an X11-ism
we might not even want to replicate on every backend with sane
enter/leave semantics.
For this reason we should check inside the X11 event processing if the
pointer device has already left the Stage and ignore the second
LeaveNotify.
The InputDevice objects stores pointer coordinates, state, stage and
the actor under the cursor, so if the current backend provides us with
one attached to the Event structure then we want the InputDevice itself
to update its state and give us the ClutterActor underneath the
pointer's cursor.
Even when we are not using XInput we now have fallback devices; the
X11 backend should always assign the default devices when translating
the X events to Clutter events.
Use the device manager to store the input devices. Also, provide
two fallback devices when initializing the X11 backend: device 0
for the pointer and device 1 for the keyboard.
Old-style X11 terminals require that even modern X11 send KeyPress
and KeyRelease pairs when auto-repeating. For this reason modern(-ish)
API like XKB has a way to detect auto-repeat and do a single KeyRelease
at the end of a KeyPress sequence.
The newly added check emulates XKB's detectable auto-repeat by peeking
the next event after a KeyRelease and checking if it's a KeyPress for
the same key and timestamp - and then ignoring the KeyRelease if it
matches.
The user-initiated resize is conflicting with the allocated size. This
happens because we change the size of the stage's X Window behind the
back of the size allocation machinery.
Instead, we should change the size of the actor whenever we receive a
ConfigureNotify event to reflect the new size of the actor.
The race we were experiencing in the X11 backends is apparently
back after the fix in commit 00a3c698.
This time, just delaying the setting of the SYNC_MATRICES flag
is not enough, so we can resume the use of a STAGE_IN_RESIZE
private flag.
This should also fix bug:
http://bugzilla.openedhand.com/show_bug.cgi?id=1668
The input device API is split halfway thorugh the backends in a very
weird way. The data structures are private, as they should, but most
of the information should be available in the main API since it's
generic enough.
The device type enumeration, for instance, should be common across
every backend; the accessors for device type and id should live in the
core API. The internal API should always use ClutterInputDevice and
not the private X11 implementation when dealing with public structures
like ClutterEvent.
By adding accessors for the device type and id, and by moving the
device type enumeration into the core API we can cut down the amount
of symbols private and/or visible only to the X11 backends; this way
when other backends start implementing multi-pointer support we can
share the same API across the code.
The clutter_context_get_default() function is private, but shared
across Clutter. For this reason, it should be prefixed by '_' so
that the symbol is hidden from the shared object.
The XInput support in Clutter is still using XI 1.x. This will never
work correctly, and we are all waiting for XInput 2 anyway. The changes
internally should be minimal, so we can leave everything in place, but
it's better to disable XInput support by default -- at least for the
time being.
The mapping and unmapping of the X11 stage implementation is
a bit bong. It's asynchronous, for starters, when it really
can avoid it by tracking the state internally.
The ordering of the map/unmap sequence is also broken with
respect to the resizing.
By tracking the state internally into StageX11 we can safely
remove the MapNotify and UnmapNotify X event handling.
In theory, we should use _NET_WM_STATE a lot more, and reuse
the X11 state flags for fullscreening as well.
Apparently, the XInput extension is using the same pkg-config
file ('xi') for both the 1.x and the 2.x API, so we need to
check for both the 1.x XGetExtensionVersion and the 2.x
XQueryInputVersion.
The clutter_get_current_event_time() function will return the event
timestamp coming from a Clutter event. Clutter might synthesize or
throttle events, so the function cannot be used when dealing with
backend-specific use cases.
The X11 backend is the only backend supported by Clutter that makes
use of timestamps, so it's altogether fitting that it should come
with a specific function to deal with the timestamps of the X events.
Bug 1178 - No enter / leave events on actors when pointer leaves the
stage window
The patch is mostly thanks to Johan Bilien with small modifications
based on suggestions by Owen Taylor.
The X11 backend now listens for enter and leave notifications. Leave
notifications get translated directly to a CLUTTER_LEAVE
event. Clutter can detect these special events because the source
actor is NULL in which case it sets the source actor to the last known
actor and then sets the last known actor to NULL.
Enter notifications just get translated to CLUTTER_MOTION events which
will cause Clutter to generate an enter event through the usual code
path.