xdg-shell: Rework the state system
The states system, so far, has been a complicated mix of weird APIs that solved a real race condition, but have been particularly ugly for both compositors and clients to implement.
This commit is contained in:
committed by
Kristian Høgsberg
parent
c815d62b85
commit
ab2c108137
+41
-42
@@ -268,40 +268,39 @@ init_gl(struct window *window)
|
||||
|
||||
static void
|
||||
handle_surface_configure(void *data, struct xdg_surface *surface,
|
||||
int32_t width, int32_t height)
|
||||
int32_t width, int32_t height,
|
||||
struct wl_array *states, uint32_t serial)
|
||||
{
|
||||
struct window *window = data;
|
||||
uint32_t *p;
|
||||
|
||||
if (window->native)
|
||||
wl_egl_window_resize(window->native, width, height, 0, 0);
|
||||
|
||||
window->geometry.width = width;
|
||||
window->geometry.height = height;
|
||||
|
||||
if (!window->fullscreen)
|
||||
window->window_size = window->geometry;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_surface_change_state(void *data, struct xdg_surface *xdg_surface,
|
||||
uint32_t state,
|
||||
uint32_t value,
|
||||
uint32_t serial)
|
||||
{
|
||||
struct window *window = data;
|
||||
|
||||
switch (state) {
|
||||
case XDG_SURFACE_STATE_FULLSCREEN:
|
||||
window->fullscreen = value;
|
||||
|
||||
if (!value)
|
||||
handle_surface_configure(window, window->xdg_surface,
|
||||
window->window_size.width,
|
||||
window->window_size.height);
|
||||
break;
|
||||
window->fullscreen = 0;
|
||||
wl_array_for_each(p, states) {
|
||||
uint32_t state = *p;
|
||||
switch (state) {
|
||||
case XDG_SURFACE_STATE_FULLSCREEN:
|
||||
window->fullscreen = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xdg_surface_ack_change_state(xdg_surface, state, value, serial);
|
||||
if (width > 0 && height > 0) {
|
||||
if (!window->fullscreen) {
|
||||
window->window_size.width = width;
|
||||
window->window_size.height = height;
|
||||
}
|
||||
window->geometry.width = width;
|
||||
window->geometry.height = height;
|
||||
} else if (!window->fullscreen) {
|
||||
window->geometry = window->window_size;
|
||||
}
|
||||
|
||||
if (window->native)
|
||||
wl_egl_window_resize(window->native,
|
||||
window->geometry.width,
|
||||
window->geometry.height, 0, 0);
|
||||
|
||||
xdg_surface_ack_configure(surface, serial);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -322,7 +321,6 @@ handle_surface_delete(void *data, struct xdg_surface *xdg_surface)
|
||||
|
||||
static const struct xdg_surface_listener xdg_surface_listener = {
|
||||
handle_surface_configure,
|
||||
handle_surface_change_state,
|
||||
handle_surface_activated,
|
||||
handle_surface_deactivated,
|
||||
handle_surface_delete,
|
||||
@@ -343,8 +341,8 @@ create_surface(struct window *window)
|
||||
|
||||
window->native =
|
||||
wl_egl_window_create(window->surface,
|
||||
window->window_size.width,
|
||||
window->window_size.height);
|
||||
window->geometry.width,
|
||||
window->geometry.height);
|
||||
window->egl_surface =
|
||||
eglCreateWindowSurface(display->egl.dpy,
|
||||
display->egl.conf,
|
||||
@@ -359,9 +357,8 @@ create_surface(struct window *window)
|
||||
if (!window->frame_sync)
|
||||
eglSwapInterval(display->egl.dpy, 0);
|
||||
|
||||
xdg_surface_request_change_state(window->xdg_surface,
|
||||
XDG_SURFACE_STATE_FULLSCREEN,
|
||||
window->fullscreen, 0);
|
||||
if (window->fullscreen)
|
||||
xdg_surface_set_fullscreen(window->xdg_surface, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -620,11 +617,12 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
||||
{
|
||||
struct display *d = data;
|
||||
|
||||
if (key == KEY_F11 && state)
|
||||
xdg_surface_request_change_state(d->window->xdg_surface,
|
||||
XDG_SURFACE_STATE_FULLSCREEN,
|
||||
!d->window->fullscreen, 0);
|
||||
else if (key == KEY_ESC && state)
|
||||
if (key == KEY_F11 && state) {
|
||||
if (d->window->fullscreen)
|
||||
xdg_surface_unset_fullscreen(d->window->xdg_surface);
|
||||
else
|
||||
xdg_surface_set_fullscreen(d->window->xdg_surface, NULL);
|
||||
} else if (key == KEY_ESC && state)
|
||||
running = 0;
|
||||
}
|
||||
|
||||
@@ -772,8 +770,9 @@ main(int argc, char **argv)
|
||||
|
||||
window.display = &display;
|
||||
display.window = &window;
|
||||
window.window_size.width = 250;
|
||||
window.window_size.height = 250;
|
||||
window.geometry.width = 250;
|
||||
window.geometry.height = 250;
|
||||
window.window_size = window.geometry;
|
||||
window.buffer_size = 32;
|
||||
window.frame_sync = 1;
|
||||
|
||||
|
||||
+3
-10
@@ -117,16 +117,10 @@ create_shm_buffer(struct display *display, struct buffer *buffer,
|
||||
|
||||
static void
|
||||
handle_configure(void *data, struct xdg_surface *surface,
|
||||
int32_t width, int32_t height)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
handle_change_state(void *data, struct xdg_surface *xdg_surface,
|
||||
uint32_t state,
|
||||
uint32_t value,
|
||||
uint32_t serial)
|
||||
int32_t width, int32_t height,
|
||||
struct wl_array *states, uint32_t serial)
|
||||
{
|
||||
xdg_surface_ack_configure(surface, serial);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -147,7 +141,6 @@ handle_delete(void *data, struct xdg_surface *xdg_surface)
|
||||
|
||||
static const struct xdg_surface_listener xdg_surface_listener = {
|
||||
handle_configure,
|
||||
handle_change_state,
|
||||
handle_activated,
|
||||
handle_deactivated,
|
||||
handle_delete,
|
||||
|
||||
+42
-33
@@ -230,6 +230,8 @@ struct window {
|
||||
int fullscreen;
|
||||
int maximized;
|
||||
|
||||
int next_attach_serial;
|
||||
|
||||
enum preferred_format preferred_format;
|
||||
|
||||
window_key_handler_t key_handler;
|
||||
@@ -1338,6 +1340,12 @@ surface_flush(struct surface *surface)
|
||||
surface->input_region = NULL;
|
||||
}
|
||||
|
||||
if (surface->window->next_attach_serial > 0) {
|
||||
xdg_surface_ack_configure(surface->window->xdg_surface,
|
||||
surface->window->next_attach_serial);
|
||||
surface->window->next_attach_serial = 0;
|
||||
}
|
||||
|
||||
surface->toysurface->swap(surface->toysurface,
|
||||
surface->buffer_transform, surface->buffer_scale,
|
||||
&surface->server_allocation);
|
||||
@@ -3849,37 +3857,39 @@ widget_schedule_resize(struct widget *widget, int32_t width, int32_t height)
|
||||
|
||||
static void
|
||||
handle_surface_configure(void *data, struct xdg_surface *xdg_surface,
|
||||
int32_t width, int32_t height)
|
||||
int32_t width, int32_t height,
|
||||
struct wl_array *states, uint32_t serial)
|
||||
{
|
||||
struct window *window = data;
|
||||
uint32_t *p;
|
||||
|
||||
window_schedule_resize(window, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_surface_change_state(void *data, struct xdg_surface *xdg_surface,
|
||||
uint32_t state,
|
||||
uint32_t value,
|
||||
uint32_t serial)
|
||||
{
|
||||
struct window *window = data;
|
||||
|
||||
switch (state) {
|
||||
case XDG_SURFACE_STATE_MAXIMIZED:
|
||||
window->maximized = value;
|
||||
break;
|
||||
case XDG_SURFACE_STATE_FULLSCREEN:
|
||||
window->fullscreen = value;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!window->fullscreen && !window->maximized)
|
||||
if (width > 0 && height > 0) {
|
||||
window_schedule_resize(window, width, height);
|
||||
} else {
|
||||
window_schedule_resize(window,
|
||||
window->saved_allocation.width,
|
||||
window->saved_allocation.height);
|
||||
}
|
||||
|
||||
xdg_surface_ack_change_state(xdg_surface, state, value, serial);
|
||||
window_schedule_redraw(window);
|
||||
window->maximized = 0;
|
||||
window->fullscreen = 0;
|
||||
|
||||
wl_array_for_each(p, states) {
|
||||
uint32_t state = *p;
|
||||
switch (state) {
|
||||
case XDG_SURFACE_STATE_MAXIMIZED:
|
||||
window->maximized = 1;
|
||||
break;
|
||||
case XDG_SURFACE_STATE_FULLSCREEN:
|
||||
window->fullscreen = 1;
|
||||
break;
|
||||
default:
|
||||
/* Unknown state */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
window->next_attach_serial = serial;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3905,7 +3915,6 @@ handle_surface_delete(void *data, struct xdg_surface *xdg_surface)
|
||||
|
||||
static const struct xdg_surface_listener xdg_surface_listener = {
|
||||
handle_surface_configure,
|
||||
handle_surface_change_state,
|
||||
handle_surface_activated,
|
||||
handle_surface_deactivated,
|
||||
handle_surface_delete,
|
||||
@@ -4145,10 +4154,10 @@ window_set_fullscreen(struct window *window, int fullscreen)
|
||||
if (window->fullscreen == fullscreen)
|
||||
return;
|
||||
|
||||
xdg_surface_request_change_state(window->xdg_surface,
|
||||
XDG_SURFACE_STATE_FULLSCREEN,
|
||||
fullscreen ? 1 : 0,
|
||||
0);
|
||||
if (fullscreen)
|
||||
xdg_surface_set_fullscreen(window->xdg_surface, NULL);
|
||||
else
|
||||
xdg_surface_unset_fullscreen(window->xdg_surface);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -4166,10 +4175,10 @@ window_set_maximized(struct window *window, int maximized)
|
||||
if (window->maximized == maximized)
|
||||
return;
|
||||
|
||||
xdg_surface_request_change_state(window->xdg_surface,
|
||||
XDG_SURFACE_STATE_MAXIMIZED,
|
||||
maximized ? 1 : 0,
|
||||
0);
|
||||
if (maximized)
|
||||
xdg_surface_set_maximized(window->xdg_surface);
|
||||
else
|
||||
xdg_surface_unset_maximized(window->xdg_surface);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user