Fix rotation while the window is maximized
Keep the windowed window size to handle maximized window the same way as fullscreen window. Fixes <https://github.com/Genymobile/scrcpy/issues/750>
This commit is contained in:
parent
f6f2868868
commit
35c05bb3ce
2 changed files with 73 additions and 34 deletions
|
@ -30,23 +30,28 @@ get_window_size(SDL_Window *window) {
|
||||||
// get the windowed window size
|
// get the windowed window size
|
||||||
static struct size
|
static struct size
|
||||||
get_windowed_window_size(const struct screen *screen) {
|
get_windowed_window_size(const struct screen *screen) {
|
||||||
if (screen->fullscreen) {
|
if (screen->fullscreen || screen->maximized) {
|
||||||
return screen->windowed_window_size;
|
return screen->windowed_window_size;
|
||||||
}
|
}
|
||||||
return get_window_size(screen->window);
|
return get_window_size(screen->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apply the windowed window size if fullscreen and maximized are disabled
|
||||||
|
static void
|
||||||
|
apply_windowed_size(struct screen *screen) {
|
||||||
|
if (!screen->fullscreen && !screen->maximized) {
|
||||||
|
SDL_SetWindowSize(screen->window, screen->windowed_window_size.width,
|
||||||
|
screen->windowed_window_size.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set the window size to be applied when fullscreen is disabled
|
// set the window size to be applied when fullscreen is disabled
|
||||||
static void
|
static void
|
||||||
set_window_size(struct screen *screen, struct size new_size) {
|
set_window_size(struct screen *screen, struct size new_size) {
|
||||||
// setting the window size during fullscreen is implementation defined,
|
// setting the window size during fullscreen is implementation defined,
|
||||||
// so apply the resize only after fullscreen is disabled
|
// so apply the resize only after fullscreen is disabled
|
||||||
if (screen->fullscreen) {
|
screen->windowed_window_size = new_size;
|
||||||
// SDL_SetWindowSize will be called when fullscreen will be disabled
|
apply_windowed_size(screen);
|
||||||
screen->windowed_window_size = new_size;
|
|
||||||
} else {
|
|
||||||
SDL_SetWindowSize(screen->window, new_size.width, new_size.height);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the preferred display bounds (i.e. the screen bounds with some margins)
|
// get the preferred display bounds (i.e. the screen bounds with some margins)
|
||||||
|
@ -194,6 +199,8 @@ screen_init_rendering(struct screen *screen, const char *window_title,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
screen->windowed_window_size = window_size;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,10 +294,6 @@ screen_render(struct screen *screen) {
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_switch_fullscreen(struct screen *screen) {
|
screen_switch_fullscreen(struct screen *screen) {
|
||||||
if (!screen->fullscreen) {
|
|
||||||
// going to fullscreen, store the current windowed window size
|
|
||||||
screen->windowed_window_size = get_window_size(screen->window);
|
|
||||||
}
|
|
||||||
uint32_t new_mode = screen->fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP;
|
uint32_t new_mode = screen->fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
if (SDL_SetWindowFullscreen(screen->window, new_mode)) {
|
if (SDL_SetWindowFullscreen(screen->window, new_mode)) {
|
||||||
LOGW("Could not switch fullscreen mode: %s", SDL_GetError());
|
LOGW("Could not switch fullscreen mode: %s", SDL_GetError());
|
||||||
|
@ -298,11 +301,7 @@ screen_switch_fullscreen(struct screen *screen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->fullscreen = !screen->fullscreen;
|
screen->fullscreen = !screen->fullscreen;
|
||||||
if (!screen->fullscreen) {
|
apply_windowed_size(screen);
|
||||||
// fullscreen disabled, restore expected windowed window size
|
|
||||||
SDL_SetWindowSize(screen->window, screen->windowed_window_size.width,
|
|
||||||
screen->windowed_window_size.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGD("Switched to %s mode", screen->fullscreen ? "fullscreen" : "windowed");
|
LOGD("Switched to %s mode", screen->fullscreen ? "fullscreen" : "windowed");
|
||||||
screen_render(screen);
|
screen_render(screen);
|
||||||
|
@ -310,7 +309,7 @@ screen_switch_fullscreen(struct screen *screen) {
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_resize_to_fit(struct screen *screen) {
|
screen_resize_to_fit(struct screen *screen) {
|
||||||
if (!screen->fullscreen) {
|
if (!screen->fullscreen && !screen->maximized) {
|
||||||
struct size optimal_size = get_optimal_window_size(screen,
|
struct size optimal_size = get_optimal_window_size(screen,
|
||||||
screen->frame_size);
|
screen->frame_size);
|
||||||
SDL_SetWindowSize(screen->window, optimal_size.width,
|
SDL_SetWindowSize(screen->window, optimal_size.width,
|
||||||
|
@ -321,7 +320,7 @@ screen_resize_to_fit(struct screen *screen) {
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_resize_to_pixel_perfect(struct screen *screen) {
|
screen_resize_to_pixel_perfect(struct screen *screen) {
|
||||||
if (!screen->fullscreen) {
|
if (!screen->fullscreen && !screen->maximized) {
|
||||||
SDL_SetWindowSize(screen->window, screen->frame_size.width,
|
SDL_SetWindowSize(screen->window, screen->frame_size.width,
|
||||||
screen->frame_size.height);
|
screen->frame_size.height);
|
||||||
LOGD("Resized to pixel-perfect");
|
LOGD("Resized to pixel-perfect");
|
||||||
|
@ -333,8 +332,39 @@ screen_handle_window_event(struct screen *screen,
|
||||||
const SDL_WindowEvent *event) {
|
const SDL_WindowEvent *event) {
|
||||||
switch (event->event) {
|
switch (event->event) {
|
||||||
case SDL_WINDOWEVENT_EXPOSED:
|
case SDL_WINDOWEVENT_EXPOSED:
|
||||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
|
||||||
screen_render(screen);
|
screen_render(screen);
|
||||||
break;
|
break;
|
||||||
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||||
|
if (!screen->fullscreen && !screen->maximized) {
|
||||||
|
// Backup the previous size: if we receive the MAXIMIZED event,
|
||||||
|
// then the new size must be ignored (it's the maximized size).
|
||||||
|
// We could not rely on the window flags due to race conditions
|
||||||
|
// (they could be updated asynchronously, at least on X11).
|
||||||
|
screen->windowed_window_size_backup =
|
||||||
|
screen->windowed_window_size;
|
||||||
|
|
||||||
|
// Save the windowed size, so that it is available once the
|
||||||
|
// window is maximized or fullscreen is enabled.
|
||||||
|
screen->windowed_window_size = get_window_size(screen->window);
|
||||||
|
}
|
||||||
|
screen_render(screen);
|
||||||
|
break;
|
||||||
|
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||||
|
// The backup size must be non-nul.
|
||||||
|
SDL_assert(screen->windowed_window_size_backup.width);
|
||||||
|
SDL_assert(screen->windowed_window_size_backup.height);
|
||||||
|
// Revert the last size, it was updated while screen was maximized.
|
||||||
|
screen->windowed_window_size = screen->windowed_window_size_backup;
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Reset the backup to invalid values to detect unexpected usage
|
||||||
|
screen->windowed_window_size_backup.width = 0;
|
||||||
|
screen->windowed_window_size_backup.height = 0;
|
||||||
|
#endif
|
||||||
|
screen->maximized = true;
|
||||||
|
break;
|
||||||
|
case SDL_WINDOWEVENT_RESTORED:
|
||||||
|
screen->maximized = false;
|
||||||
|
apply_windowed_size(screen);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,28 +15,37 @@ struct screen {
|
||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
struct size frame_size;
|
struct size frame_size;
|
||||||
//used only in fullscreen mode to know the windowed window size
|
// The window size the last time it was not maximized or fullscreen.
|
||||||
struct size windowed_window_size;
|
struct size windowed_window_size;
|
||||||
|
// Since we receive the event SIZE_CHANGED before MAXIMIZED, we must be
|
||||||
|
// able to revert the size to its non-maximized value.
|
||||||
|
struct size windowed_window_size_backup;
|
||||||
bool has_frame;
|
bool has_frame;
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
|
bool maximized;
|
||||||
bool no_window;
|
bool no_window;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCREEN_INITIALIZER { \
|
#define SCREEN_INITIALIZER { \
|
||||||
.window = NULL, \
|
.window = NULL, \
|
||||||
.renderer = NULL, \
|
.renderer = NULL, \
|
||||||
.texture = NULL, \
|
.texture = NULL, \
|
||||||
.frame_size = { \
|
.frame_size = { \
|
||||||
.width = 0, \
|
.width = 0, \
|
||||||
.height = 0, \
|
.height = 0, \
|
||||||
}, \
|
}, \
|
||||||
.windowed_window_size = { \
|
.windowed_window_size = { \
|
||||||
.width = 0, \
|
.width = 0, \
|
||||||
.height = 0, \
|
.height = 0, \
|
||||||
}, \
|
}, \
|
||||||
.has_frame = false, \
|
.windowed_window_size_backup = { \
|
||||||
.fullscreen = false, \
|
.width = 0, \
|
||||||
.no_window = false, \
|
.height = 0, \
|
||||||
|
}, \
|
||||||
|
.has_frame = false, \
|
||||||
|
.fullscreen = false, \
|
||||||
|
.maximized = false, \
|
||||||
|
.no_window = false, \
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize default values
|
// initialize default values
|
||||||
|
|
Loading…
Reference in a new issue