diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 2f8784abd..71f0da059 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -320,12 +320,18 @@ decoration_frame_configure(struct libdecor_frame *frame, enum libdecor_window_state window_state; struct libdecor_state *state; + SDL_bool fullscreen = SDL_FALSE; + SDL_bool maximized = SDL_FALSE; + /* window size */ if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { - width = window->w; - height = window->h; + width = wind->floating_width; + height = wind->floating_height; } + width = (width == 0) ? window->w : width; + height = (height == 0) ? window->h : height; + wind->resize.width = width; wind->resize.height = height; @@ -342,38 +348,65 @@ decoration_frame_configure(struct libdecor_frame *frame, window_state = LIBDECOR_WINDOW_STATE_NONE; } - /* Always send maximized/restored/focus events; if the event is redundant it will - * automatically be discarded (see src/events/SDL_windowevents.c). - * - * No, we do not get minimize events from libdecor. - */ - if (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN) { - window->flags |= SDL_WINDOW_FULLSCREEN; - } else { + /* translate libdecor to SDL states */ + switch (window_state) { + case LIBDECOR_WINDOW_STATE_FULLSCREEN: + fullscreen = SDL_TRUE; + break; + case LIBDECOR_WINDOW_STATE_MAXIMIZED: + maximized = SDL_TRUE; + break; + } + + if (!fullscreen) { if (window->flags & SDL_WINDOW_FULLSCREEN) { /* We might need to re-enter fullscreen after being restored from minimized */ SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata; SetFullscreen(window, driverdata->output); - } else { - SDL_SendWindowEvent(window, - (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ? - SDL_WINDOWEVENT_MAXIMIZED : - SDL_WINDOWEVENT_RESTORED, - 0, 0); + fullscreen = SDL_TRUE; + } + + if (width == 0 || height == 0) { + width = wind->floating_width; + height = wind->floating_height; + } + + if ((window->flags & SDL_WINDOW_RESIZABLE)) { + if (window->max_w > 0) { + width = SDL_min(width, window->max_w); + } + width = SDL_max(width, window->min_w); + + if (window->max_h > 0) { + height = SDL_min(height, window->max_h); + } + height = SDL_max(height, window->min_h); + } else { + wind->resize.width = window->w; + wind->resize.height = window->h; + return; } - window->flags &= ~SDL_WINDOW_FULLSCREEN; } - SDL_SendWindowEvent(window, - (window_state & LIBDECOR_WINDOW_STATE_ACTIVE) ? - SDL_WINDOWEVENT_FOCUS_GAINED : - SDL_WINDOWEVENT_FOCUS_LOST, - 0, 0); + + if (!fullscreen) { + SDL_SendWindowEvent(window, + maximized ? + SDL_WINDOWEVENT_MAXIMIZED : + SDL_WINDOWEVENT_RESTORED, + 0, 0); + } /* commit frame state */ state = libdecor_state_new(width, height); libdecor_frame_commit(frame, state, configuration); libdecor_state_free(state); + /* store floating dimensions */ + if (libdecor_frame_is_floating(frame)) { + wind->floating_width = width; + wind->floating_height = height; + } + /* Update the resize capability. Since this will change the capabilities and * commit a new frame state with the last known content dimension, this has * to be called after the new state has been commited and the new content