Having at most one transformation object attached to a surface is not
enough anymore. If we have a surface that needs to be scaled to
fullscreen, and then we have the zoom animation, we already need two
transformations combined.
Implement support for multiple transformations by adding a transformation
list. The final transformation is the ordered composite of those in the
list. To avoid traversing the list every single time, add a dirty flag,
and cache the final transformation.
The existing transformation users (only zoom) are converted.
Note: surface drawing should honour all kinds of transformations, but
not damage region code nor input event translating code take
transformations into account, AFAICT. Therefore anything but translation
will probably behave badly until they are fixed.
Cc: Juan Zhao <juan.j.zhao@linux.intel.com>
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
This removes more special cases from weston_output_repaint() and we
avoid creating and destroying the surface for each animation frame.
We gain another special case in weston_compositor_top(), but that's
less of a problem, and we'll fix that later.
We've trimmed down the actual repaint loop to just iterating through the
surface list and calling weston_surface_draw(), so we push that to the
backend without too much code duplication.
This was supposed to draw black borders around a fullscreen surface that
was smaller than the output. We don't want to special case that in the
repaint loop, but may use a different shader or such. And we want the
surface to have an opaque region that covers the output so that that
will eliminate overdraw of lower surfaces.
This reverts commit fc6ccb868f.
We still need root permissions for drmDrop/SetMaster. Without
integration with ConsoleKit or systemd we also don't have access
to /dev/dri/cardX in the case where we open a new VT.
The code which sends the button events was checking whether there is a
focus widget with a button handler but then always sending the button
event to the grab widget. If the grab widget is different from the
focus widget at this point then it will check the wrong widget for a
button handler and potentially crash. It is also possible for there to
be no grab widget here in the following situation:
1. Press and hold down the left mouse button
2. Press and hold down the right mouse button
3. Release the left mouse button
4. Release the right mouse button
In this case the grab will be released at step 3 because the code only
keeps track of the grab for one button. Then it will try to send the
release event for the right mouse button to a NULL widget so it will
crash.
==30224== Conditional jump or move depends on uninitialised value(s)
==30224== at 0x40EE3A0: evdev_flush_motion (evdev.c:284)
==30224== by 0x40EE6DC: evdev_input_device_data (evdev.c:352)
==30224== by 0x4034710: wl_event_source_fd_dispatch (event-loop.c:76)
==30224== by 0x4035171: wl_event_loop_dispatch (event-loop.c:462)
==30224== by 0x4032F76: wl_display_run (wayland-server.c:785)
==30224== by 0x8050972: main (compositor.c:2183)
Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
I could crash Weston by trying to open another menu from a panel while
one menu from it was already showing.
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff40a9872 in popup_grab_focus (grab=0x761968, time=4130706528, surface=0x0, x=-227, y=15) at shell.c:440
440 if (surface->resource.client == client) {
(gdb) bt
0 0x00007ffff40a9872 in popup_grab_focus (grab=0x761968, time=4130706528, surface=0x0, x=-227, y=15) at shell.c:440
1 0x0000000000406977 in weston_device_repick (device=0x70b4e0, time=4130706528) at compositor.c:360
2 0x0000000000406a36 in weston_compositor_repick (compositor=0x619960) at compositor.c:382
3 0x0000000000406ac8 in destroy_surface (resource=0x6fc6f0) at compositor.c:397
4 0x00007ffff7bd33d8 in destroy_resource (element=0x6fc6f0, data=0x7fffffffd9fc) at wayland-server.c:355
5 0x00007ffff7bd8d98 in for_each_helper (entries=0x757808, func=0x7ffff7bd332c <destroy_resource>, data=0x7fffffffd9fc)
at wayland-util.c:264
6 0x00007ffff7bd8dd4 in wl_map_for_each (map=0x757808, func=0x7ffff7bd332c <destroy_resource>, data=0x7fffffffd9fc)
at wayland-util.c:270
7 0x00007ffff7bd34dc in wl_client_destroy (client=0x7577d0) at wayland-server.c:385
8 0x00007ffff7bd2e36 in wl_client_connection_data (fd=17, mask=1, data=0x7577d0) at wayland-server.c:187
9 0x00007ffff7bd5bde in wl_event_source_fd_dispatch (source=0x74cda0, ep=0x7fffffffdae0) at event-loop.c:76
10 0x00007ffff7bd665b in wl_event_loop_dispatch (loop=0x618900, timeout=-1) at event-loop.c:462
11 0x00007ffff7bd42a9 in wl_display_run (display=0x6188b0) at wayland-server.c:785
12 0x000000000040b1e1 in main (argc=1, argv=0x7fffffffdef8) at compositor.c:2182
Modify popup_grab_focus() to deal with a NULL surface.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
When a menu self-destructs, free also the widget and struct menu.
As menus are self-destructing, it does not make sense to store the
window pointer, since we cannot clear it automatically. Therefore,
rename window_create_menu() to window_show_menu() that does not return
the window pointer. It also calls window_schedule_redraw() internally.
Fixes Valgrind reported memory leaks.
The alternative would be to explicitly destroy the menu in application's
menu callback.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Input devices may hold a pointer to the widget being destroyed. Reset
such pointers in widget_destroy().
This fixes a use-after-free in window_destroy(), if an application
destroys its widgets before the window.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Fix a memory leak reported by Valgrind, by destroying the window
decorations widget, if it exists.
All widget pointers returned from toytoolkit to the application should
be destroyed by the application explicitly.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
When we destroy a surface, we damage the surface below so that the area
exposed by the disappearing surface will be repainted. However, if that
surface also is destroyed, the damage information is lost and we fail to
repaint that area.
This commit introduces weston_surface_flush_damage(), which flushes the
surface damage the the surface below when a surface is destroyed. When
multiple surfaces are destroyed at the same time, the damage now accumulates
and sinks down through the surface stack as it should.
gbm_bo_create_from_egl_image() should catch this based on the
GBM_BO_USE_CURSOR_64X64 flag. It currently doesn't so we end up with
a cursor buffer with invalid stride.
The decorations were not responding, could not move or resize the
dialog, and it painted with a black shade.
When the dialog is created, schedule a resize instead of a repaint. The
resize will initialise the widget tree, and let everything draw and work
as it should.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
If we don't cancel the repaint, we end up pointlessly redrawing the output.
What's worse is that pageflipping to the new buffer eventually fails and
we miss the finish_frame callback, leaving the compositor stuck when we
re-enter the vt.
Normally the repaint will trigger a pageflip, which flips back to our
fb, but that doesn't work if the kms output has been turned off or
set to a different mode.