Compare commits

...

4 Commits

Author SHA1 Message Date
7ce63499d9 Always request fullscreen and maximized state
The window state may be changed by the window manager without scrcpy
being aware of it (for example the fullscreen mode on macOS).

To avoid problems, request the window state to SDL when needed.
2020-05-07 18:20:27 +02:00
e2d5f0e7fc Send scroll events as a touchscreen
Scroll events were sent with a mouse input device. When scrolling on a
list, this could cause the whole list to be focused, and drawn with the
focus color as background.

Send scroll events with a touchscreen input device instead (like motion
events).

Fixes #1362 <https://github.com/Genymobile/scrcpy/issues/1362>
2020-05-07 15:08:11 +02:00
ead7ee4a03 Revert "Improve resizing workaround"
This reverts commit 92cb3a6661, which
broke the fullscreen/maximized restoration size on Windows.

Fixes #1346 <https://github.com/Genymobile/scrcpy/issues/1346>
2020-05-06 01:10:25 +02:00
74ece9b45b Simplify ScreenEncoder more
Commit 927d655ff6 removed the
iFrameInternal field and constructor argument.

Also remove it from createFormat() arguments.
2020-05-05 19:01:44 +02:00
5 changed files with 28 additions and 24 deletions

View File

@ -109,10 +109,10 @@ static int
event_watcher(void *data, SDL_Event *event) {
(void) data;
if (event->type == SDL_WINDOWEVENT
&& event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
&& event->window.event == SDL_WINDOWEVENT_RESIZED) {
// In practice, it seems to always be called from the same thread in
// that specific case. Anyway, it's just a workaround.
screen_handle_window_event(&screen, &event->window);
screen_render(&screen);
}
return 0;
}

View File

@ -15,6 +15,18 @@
#define DISPLAY_MARGINS 96
static bool
is_maximized(const struct screen *screen) {
uint32_t flags = SDL_GetWindowFlags(screen->window);
return !!(flags & SDL_WINDOW_MAXIMIZED);
}
static bool
is_fullscreen(const struct screen *screen) {
uint32_t flags = SDL_GetWindowFlags(screen->window);
return !!(flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP));
}
static inline struct size
get_rotated_size(struct size size, int rotation) {
struct size rotated_size;
@ -44,7 +56,7 @@ get_window_size(SDL_Window *window) {
// get the windowed window size
static struct size
get_windowed_window_size(const struct screen *screen) {
if (screen->fullscreen || screen->maximized) {
if (is_fullscreen(screen) || is_maximized(screen)) {
return screen->windowed_window_size;
}
return get_window_size(screen->window);
@ -53,7 +65,7 @@ get_windowed_window_size(const struct screen *screen) {
// apply the windowed window size if fullscreen and maximized are disabled
static void
apply_windowed_size(struct screen *screen) {
if (!screen->fullscreen && !screen->maximized) {
if (!is_fullscreen(screen) && !is_maximized(screen)) {
SDL_SetWindowSize(screen->window, screen->windowed_window_size.width,
screen->windowed_window_size.height);
}
@ -471,28 +483,27 @@ screen_render(struct screen *screen) {
void
screen_switch_fullscreen(struct screen *screen) {
uint32_t new_mode = screen->fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP;
bool was_fullscreen = is_fullscreen(screen);
uint32_t new_mode = was_fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP;
if (SDL_SetWindowFullscreen(screen->window, new_mode)) {
LOGW("Could not switch fullscreen mode: %s", SDL_GetError());
return;
}
screen->fullscreen = !screen->fullscreen;
apply_windowed_size(screen);
LOGD("Switched to %s mode", screen->fullscreen ? "fullscreen" : "windowed");
LOGD("Switched to %s mode", was_fullscreen ? "windowed" : "fullscreen");
screen_render(screen);
}
void
screen_resize_to_fit(struct screen *screen) {
if (screen->fullscreen) {
if (is_fullscreen(screen)) {
return;
}
if (screen->maximized) {
if (is_maximized(screen)) {
SDL_RestoreWindow(screen->window);
screen->maximized = false;
}
struct size optimal_size =
@ -504,13 +515,12 @@ screen_resize_to_fit(struct screen *screen) {
void
screen_resize_to_pixel_perfect(struct screen *screen) {
if (screen->fullscreen) {
if (is_fullscreen(screen)) {
return;
}
if (screen->maximized) {
if (is_maximized(screen)) {
SDL_RestoreWindow(screen->window);
screen->maximized = false;
}
struct size content_size = screen->content_size;
@ -527,7 +537,7 @@ screen_handle_window_event(struct screen *screen,
screen_render(screen);
break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
if (!screen->fullscreen && !screen->maximized) {
if (!is_fullscreen(screen) && !is_maximized(screen)) {
// 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
@ -552,10 +562,8 @@ screen_handle_window_event(struct screen *screen,
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;
}

View File

@ -29,8 +29,6 @@ struct screen {
// client rotation: 0, 1, 2 or 3 (x90 degrees counterclockwise)
unsigned rotation;
bool has_frame;
bool fullscreen;
bool maximized;
bool no_window;
bool mipmaps;
};
@ -59,8 +57,6 @@ struct screen {
}, \
.rotation = 0, \
.has_frame = false, \
.fullscreen = false, \
.maximized = false, \
.no_window = false, \
.mipmaps = false, \
}

View File

@ -215,7 +215,7 @@ public class Controller {
MotionEvent event = MotionEvent
.obtain(lastTouchDown, now, MotionEvent.ACTION_SCROLL, 1, pointerProperties, pointerCoords, 0, 0, 1f, 1f, DEVICE_ID_VIRTUAL, 0,
InputDevice.SOURCE_MOUSE, 0);
InputDevice.SOURCE_TOUCHSCREEN, 0);
return injectEvent(event);
}

View File

@ -61,7 +61,7 @@ public class ScreenEncoder implements Device.RotationListener {
}
private void internalStreamScreen(Device device, FileDescriptor fd) throws IOException {
MediaFormat format = createFormat(bitRate, maxFps, DEFAULT_I_FRAME_INTERVAL);
MediaFormat format = createFormat(bitRate, maxFps);
device.setRotationListener(this);
boolean alive;
try {
@ -151,14 +151,14 @@ public class ScreenEncoder implements Device.RotationListener {
return MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
}
private static MediaFormat createFormat(int bitRate, int maxFps, int iFrameInterval) {
private static MediaFormat createFormat(int bitRate, int maxFps) {
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC);
format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
// must be present to configure the encoder, but does not impact the actual frame rate, which is variable
format.setInteger(MediaFormat.KEY_FRAME_RATE, 60);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iFrameInterval);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, DEFAULT_I_FRAME_INTERVAL);
// display the very first frame, and recover from bad quality when no new frames
format.setLong(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, REPEAT_FRAME_DELAY_US); // µs
if (maxFps > 0) {