All backends follow the same pattern of queueing events first in
ClutterMainContext, then copying them to a ClutterStage queue and
immediately free them. Instead, we can just pass ownership of events
directly to ClutterStage thus avoiding the allocation and copy in
between.
https://bugzilla.gnome.org/show_bug.cgi?id=711857
The ClutterEventSequence structure is a fully opaque type; on X11, it is
just an unsigned integer that gets converted into a pointer, but in the
future it may become a fully fledged data structure.
Obviously, we cannot tell people to just dereference the pointer into an
integer in order to use it, and still retain the ability to change the
type; for this reason, we need a proper accessor function to convert the
EventSequence into a touch detail, to be used with the XInput API.
Acquiring the Clutter lock to mark critical sections is not portable,
and not recommended to implement threaded applications with Clutter.
The recommended pattern is to use worker threads, and schedule UI
updates inside idle or timeout handlers within the main loop. We should
enforce this pattern by deprecating the threads_enter()/leave()
functions. For compatibility concerns, we need internal API to acquire
the main lock during frame processing dispatch.
https://bugzilla.gnome.org/show_bug.cgi?id=679450
Input backends are, in some cases, independent from the windowing system
backends; we can initialize input handling using a model similar to what
we use for windowing backends, including an environment variable and
compile-/run-time checks.
This model allows us to remove the backend-specific init_events(), and
use a generic implementation directly inside the base ClutterBackend
class, thus further reducing the backend-specific code that every
platform has to implement.
This requires some minor surgery to every single backend, to make sure
that the function exposed to initialize the event loop is similar and
performs roughly the same operations.
https://bugzilla.gnome.org/show_bug.cgi?id=654656
Clutter may be used together with GTK+, which indirectly may use
XInput2 too, so the cookie data must persist when both are handling
events.
What happens now in a nutshell is, Clutter is only guaranteed to allocate
the cookie itself after XNextEvent(), and only frees the cookie if its
XGetEventData() call allocated the cookie data.
The X[Get|Free]EventData() calls happen now in clutter-event-x11.c as
hypothetically different event translators could also handle other set
of X Generic Events, or other libraries handling events for that matter.
Event translation is now done where it belongs: we don't need a massive
switch in a file with direct access to private structure members.
So long, event_translate(); and thanks for all the fish.
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.