When window_attach_surface() calls window_get_resize_dx_dy(),
window->resize_edges is cleared. However if there is already a pending
surface to be attached, the resize won't be done until the following
call to window_attach_surface(). In this next call, since resize_edges
is now zero, the top-left corner of the window will be unchanged. If
the user is resizing from the top or left border, this causes the
resize to happen in the wrong direction.
This patch changes window_attach_surface() to call
window_get_resize_dx_dy() only if an attach will actually happen.
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
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.
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>
With all input events going to widgets now, we can grab an input device
to a widget, so that all events are delivered to that widgets handlers.
This lets us implement the last bit of the menu behaviour, that is
the client side grabbing of events. The result is that we can now pop down
the menu when we receive clicks in the clients own windows and we
don't send motion and button events to other widgets.
This lands the basic behavior of the popup surface type, but there are still
a number of details to be worked out. Mainly there's a hardcoded timeout
to handle the case of releasing the popup button outside any of the
client windows, which triggers popup_end if it happens after the timeout.
Maybe we just need to add that as an argument, or we could add a new event
that fires in this case to let the client decide whether it ends the popup
or not.
Windows are supposed to be destroyed by the application explicitly.
Deferred tasks are not supposed to be added after returning from
display_run().
Destroy remaining wl objects (except input related will be in a
following patch).
Close the epoll fd.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Add a function to destroy the 'struct display', supposedly with all
contained resources, that are not explicitly created by the application.
The implementation at this time is incomplete. It does clean up the
following:
- xkb structure is freed (needs new libxkbcommon from git)
- EGL resources are freed
- wl_display is flushed and destroyed
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Add a function, that schedules the display_run() event loop to break
out.
When display_exit() is called, processing continues as usual, until
currently waiting events and deferred tasks have been processed, and
sent requests are flushed. Then, display_run() will return.
This enables toytoolkit apps to handle their exit instead of just being
killed or call exit().
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
The Cairo documentation tells us to always call cairo_device_flush()
before using other rendering APIs on the cairo surface, especially where
the Cairo device shares state with us (that is, EGL and GL state in this
case).
Add a call to cairo_device_flush() into display_acquire_window_surface(),
which the toytoolkit offers for switching to native (GL) rendering.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Add output_configure_handler as a display property. This exposes only
configured outputs, that is the current mode info is already received,
to applications.
The handler is also called for mode changes on an existing output. This
simplifies the implementation in toytoolkit as we can defer the handler
calls from wl_output binding time to when we receive the current mode.
We do not need separate handlers for "new output" and "mode changed". A
plain "new output" handler would be problematic as the current mode is
not known yet.
Also add delete_handler hook for outputs, but that will never be called
for now, as the protocol lacks a way to signal output disconnections.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Since it is the desktop-shell plugin in the compositor that offers both
wl_shell global interface and wl_shell_surface interface, those are not
available on the tablet-shell plugin.
The tablet-shell client uses the toytoolkit, so toytoolkit must work
somehow even without wl_shell.
Turn all operations in toytoolkit that would require wl_shell or
wl_shell_surface into no-ops.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Change desktop-shell protocol to use wl_shell_surface instead of
wl_surface.
Adapt the desktop-shell client and the shell plugin.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Protocol changes in Wayland core introduced a new interface
wl_shell_surface, and moved all wl_shell surface methods into it. Adapt
the compositor and its Wayland backend, shell plugin, and all clients to
the new interface.
Depends on the Wayland core commit "protocol: introduce wl_shell_surface"
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
When a window destroyed, if any input had the window in keyboard
focus, the keyboard focus is reset to NULL. A new keyboard focus is set
only, if the user clicks something. If the user presses a key instead of
clicking, the key press event is sent to the client which has NULL
keyboard focus, triggering a segfault in window_handle_key().
Fix the segfault by ignoring the key event, if there is no target
window.
I triggered this segfault by clicking the unlock dialog away, and then
pressing a key.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Currently, the way to destroy a window in a response to an event (e.g.
button click), is to put a task into the deferred list with
display_defer(). The task will then call window_destroy() from outside
event handling code.
As events are handled, it is possible that the deferred list contains
also the redraw task for this window. As the execution order of these
tasks is unknown (redrawing a freed window is a bug) and redrawing
something that goes away immediately is not useful, the redraw task must
be removed on window_destroy().
'struct input' contains pointers to windows currently in focus for that
input device. These pointers must also be cleared on window_destroy().
This fixes a use-after-free bug for the unlock dialog in desktop-shell
(future commit).
As an irrelevant minor cleanup, window::grab_device member is not used
anywhere, and is removed.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
I may have missed something, but - since the Wayland compositor
already picks a platform backend, opens a connection and initializes the
backend specific display data structure it doesn't make sense
to let egl pick a platform. If it picks a different one the
display specific data structure will most likely not match.
Thus determine the platform in the Wayland rendering backend by setting
the EGL_PLATFORM env variable.
For the client any other platform than 'wayland' doesn't seem to make
sense.
I'm not sure if I've got the the platform ofr openfwd right.
Signed-off-by: Egbert Eich <eich@freedesktop.org>
fixes valgrind:
==25178== Conditional jump or move depends on uninitialised value(s)
==25178== at 0x409E2C: display_create (window.c:1582)
==25178== by 0x407A43: main (terminal.c:2323)
and
==13793== Conditional jump or move depends on uninitialised value(s)
==13793== at 0x40A2D1: display_handle_global (window.c:1504)
==13793== by 0x4E2C183: display_handle_global (wayland-client.c:281)
==13793== by 0x713FEE7: ffi_call_unix64 (in /usr/lib/libffi.so.5.0.10)
==13793== by 0x713FC83: ffi_call (in /usr/lib/libffi.so.5.0.10)
==13793== by 0x4E2C71A: wl_closure_invoke (connection.c:663)
==13793== by 0x4E2BB7B: wl_display_iterate (wayland-client.c:484)
==13793== by 0x4096CA: display_create (window.c:1664)
==13793== by 0x407A43: main (terminal.c:2321)
Get snapping to character grid working again, avoid crashes when attempting
to resize below 1x1 character cell, only redraw when size actually changes.
Also, rename window_get_child_rectangle() to window_get_child_allocation().
The new map_toplevel() request no longer specifies a position and takes
the size from the attached buffer. The attach request now takes a
position relative to the top-left corner of the old buffer to let
clients specify the relative position of the new buffer.
or if that check is removed - crash (unsurprisingly).
This patch relieves this assumption, and allow some clients (terminal,
image, flower) to run in a non-DRM environment
These two functions are just wrappers around display_create_*_surface
but weren't forwarding along the result of those calls as is implied by
their return value type.
This fixes a compile-time warning.
Signed-off-by: Bryce Harrington <bryce@canonical.com>
In theory, it was possible for an undefined 'surface' to be passed to
window_set_surface(). Instead, explicitly pass NULL.
Signed-off-by: Bryce Harrington <bryce@canonical.com>
The buffer object is created by a 'drm' object, which encapsulates the
buffer sharing and authentication mechanism. Once the buffer is created
it can be attached to a surface.