From 8fdac1f1db4d9ea13c7ac3dbd4e7fd89d34c198e Mon Sep 17 00:00:00 2001 From: Shripal Jain Date: Sun, 17 May 2026 18:04:09 +0200 Subject: [PATCH 1/4] Add `--flex-display` config toggle to virtual display screen --- assets/i18n/en.json | 4 ++++ docs/scrcpy_options/virtualDisplay.md | 1 + .../arguments/virtualDisplay/flex_display.dart | 17 +++++++++++++++++ lib/application/model/scrcpy/scrcpy_arg.dart | 1 + .../scrcpy_config/v4l2/v4l2_screen.dart | 2 +- .../virtualDisplay/virtual_display_screen.dart | 15 +++++++++++++++ .../scrcpy_config/widgets/config_toggle.dart | 5 +++-- 7 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 lib/application/model/scrcpy/arguments/virtualDisplay/flex_display.dart diff --git a/assets/i18n/en.json b/assets/i18n/en.json index 3cc31fa..be8b476 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -287,6 +287,10 @@ "description": "It is recommended to use virtual display with 'Start app' option available in ", "button": "'Device' section" }, + "flex": { + "title": "Flexible", + "description": "Allows the virtual display to be flexibly resizeable according to scrcpy window size" + }, "newDisplay": { "title": "Create virtual display", "description": "Create and mirror a virtual display instead of the main device screen", diff --git a/docs/scrcpy_options/virtualDisplay.md b/docs/scrcpy_options/virtualDisplay.md index 406bfe8..625ca9c 100644 --- a/docs/scrcpy_options/virtualDisplay.md +++ b/docs/scrcpy_options/virtualDisplay.md @@ -6,6 +6,7 @@ | `--new-display=WxH` | Create virtual display with explicit width×height. [1] | Width/height number inputs (when virtual display enabled) | No | | `--new-display=WxH/DPI` | Same as above but with explicit density. [1] | Additional DPI number input | Yes | | `--new-display=/DPI` | Use main display size but explicit density. [1] | DPI number input (size fields disabled) | Yes | +| `--flex-display` | Allows the virtual display to be resizeable according to scrcpy window size | Switch/toggle | No | | `--no-vd-system-decorations` | Disable system decorations in virtual display (no launcher/system UI). [1] | Switch/toggle | Yes | | `--no-vd-destroy-content` | On closing scrcpy, move apps from virtual display back to main display instead of destroying them. [1] | Switch/toggle | Yes | | `--display-ime-policy=local` | Force IME (on‑screen keyboard) to appear on local display for given display/virtual display. [1] | Dropdown (`default` / `local`) or checkbox “IME on local” | Yes | diff --git a/lib/application/model/scrcpy/arguments/virtualDisplay/flex_display.dart b/lib/application/model/scrcpy/arguments/virtualDisplay/flex_display.dart new file mode 100644 index 0000000..0b06eaf --- /dev/null +++ b/lib/application/model/scrcpy/arguments/virtualDisplay/flex_display.dart @@ -0,0 +1,17 @@ +import 'package:scrcpy_buddy/application/model/scrcpy/scrcpy_cli_argument.dart'; +import 'package:scrcpy_buddy/main.dart'; + +@scrcpyArg +class FlexDisplay extends ScrcpyCliArgument { + @override + List toArgs(bool value) => value ? [argument] : []; + + @override + final String argument = '--flex-display'; + + @override + final String label = 'virtualDisplay.flex'; + + @override + final List? values = null; +} diff --git a/lib/application/model/scrcpy/scrcpy_arg.dart b/lib/application/model/scrcpy/scrcpy_arg.dart index e5727f4..2e032a6 100644 --- a/lib/application/model/scrcpy/scrcpy_arg.dart +++ b/lib/application/model/scrcpy/scrcpy_arg.dart @@ -46,6 +46,7 @@ export 'arguments/v4l2/v4l2_sink.dart'; // Virtual Display export 'arguments/virtualDisplay/new_display.dart'; +export 'arguments/virtualDisplay/flex_display.dart'; /// All {ScrcpyCliArgument}s must be annotated with this annotation. class ScrcpyArg extends Reflectable { diff --git a/lib/presentation/scrcpy_config/v4l2/v4l2_screen.dart b/lib/presentation/scrcpy_config/v4l2/v4l2_screen.dart index b6550ab..333de4e 100644 --- a/lib/presentation/scrcpy_config/v4l2/v4l2_screen.dart +++ b/lib/presentation/scrcpy_config/v4l2/v4l2_screen.dart @@ -69,7 +69,7 @@ class _V4l2ScreenState extends AppModuleState { children: [ ConfigItem( icon: FluentIcons.funnel_chart, - hasDefault: true, + hasDefault: false, cliArgument: _sink, child: ConfigTextBox( value: state.getFor(_sink), diff --git a/lib/presentation/scrcpy_config/virtualDisplay/virtual_display_screen.dart b/lib/presentation/scrcpy_config/virtualDisplay/virtual_display_screen.dart index 3d549bd..d2f301d 100644 --- a/lib/presentation/scrcpy_config/virtualDisplay/virtual_display_screen.dart +++ b/lib/presentation/scrcpy_config/virtualDisplay/virtual_display_screen.dart @@ -5,8 +5,10 @@ import 'package:scrcpy_buddy/application/model/scrcpy/scrcpy_arg.dart'; import 'package:scrcpy_buddy/application/profiles_bloc/profiles_bloc.dart'; import 'package:scrcpy_buddy/presentation/extension/translation_extension.dart'; import 'package:scrcpy_buddy/presentation/scrcpy_config/widgets/config_divider.dart'; +import 'package:scrcpy_buddy/presentation/scrcpy_config/widgets/config_item.dart'; import 'package:scrcpy_buddy/presentation/scrcpy_config/widgets/config_item_base.dart'; import 'package:scrcpy_buddy/presentation/scrcpy_config/widgets/config_text_box.dart'; +import 'package:scrcpy_buddy/presentation/scrcpy_config/widgets/config_toggle.dart'; import 'package:scrcpy_buddy/presentation/scrcpy_config/widgets/link_span.dart'; import 'package:scrcpy_buddy/presentation/widgets/app_widgets.dart'; import 'package:scrcpy_buddy/routes.dart'; @@ -24,6 +26,7 @@ class _VirtualDisplayScreenState extends AppModuleState { late final _profilesBloc = context.read(); final _newDisplay = NewDisplay(); + final _flexDisplay = FlexDisplay(); bool isEnabled = false; String? resolutionWidth; String? resolutionHeight; @@ -62,10 +65,16 @@ class _VirtualDisplayScreenState extends AppModuleState { event = UpdateProfileArgEvent(_newDisplay, ""); } else { event = UpdateProfileArgEvent(_newDisplay, null); + _disableFlex(); } _profilesBloc.add(event); } + void _disableFlex() { + final event = UpdateProfileArgEvent(_flexDisplay, null); + _profilesBloc.add(event); + } + void _updateDpi(String? newDpi) { dpi = newDpi; if (dpi != null) { @@ -206,6 +215,12 @@ class _VirtualDisplayScreenState extends AppModuleState { ), ), const ConfigDivider(), + ConfigItem( + cliArgument: _flexDisplay, + icon: WindowsIcons.resize_mouse_small_mirrored, + child: ConfigToggle(cliArgument: _flexDisplay, state: state, isEnabled: isEnabled), + ), + const ConfigDivider(), ConfigItemBase( icon: FluentIcons.image_pixel, titleKey: '${_newDisplay.label}.dpi.title', diff --git a/lib/presentation/scrcpy_config/widgets/config_toggle.dart b/lib/presentation/scrcpy_config/widgets/config_toggle.dart index 7f3f475..60f603a 100644 --- a/lib/presentation/scrcpy_config/widgets/config_toggle.dart +++ b/lib/presentation/scrcpy_config/widgets/config_toggle.dart @@ -6,14 +6,15 @@ import 'package:scrcpy_buddy/application/profiles_bloc/profiles_bloc.dart'; class ConfigToggle extends StatelessWidget { final ScrcpyCliArgument cliArgument; final ProfilesState state; + final bool isEnabled; - const ConfigToggle({super.key, required this.state, required this.cliArgument}); + const ConfigToggle({super.key, required this.state, required this.cliArgument, this.isEnabled = true}); @override Widget build(BuildContext context) { return ToggleSwitch( checked: state.getFor(cliArgument) ?? false, - onChanged: (checked) => _onChanged(context, checked), + onChanged: isEnabled ? (checked) => _onChanged(context, checked) : null, ); } From 957599fed86fc8d86b828f4863d603e4bc4ad808 Mon Sep 17 00:00:00 2001 From: Shripal Jain Date: Sun, 17 May 2026 18:14:04 +0200 Subject: [PATCH 2/4] Add `--keep-active` config toggle to device screen --- assets/i18n/en.json | 4 ++++ docs/scrcpy_options/device.md | 21 ++++++++++--------- .../scrcpy/arguments/device/keep_active.dart | 17 +++++++++++++++ lib/application/model/scrcpy/scrcpy_arg.dart | 1 + .../scrcpy_config/device/device_screen.dart | 7 +++++++ 5 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 lib/application/model/scrcpy/arguments/device/keep_active.dart diff --git a/assets/i18n/en.json b/assets/i18n/en.json index be8b476..dd603bd 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -236,6 +236,10 @@ "title": "Stay awake", "description": "Keep device awake while plugged in\nPrevious value gets restored on exit\nHas no effect is the device is connected through network (Android behavior)" }, + "keepActive": { + "title": "Keep active", + "description": "Prevents the device from turning off or sleeping, by periodically signalling user activity to the system.\nContrary to \"Stay awake\" and \"Screen off timeout\", this does not change any global settings, and it works whether the device is plugged in or not." + }, "turnScreenOff": { "title": "Turn screen off", "description": "Turn device screen off immediately on start\nCan be toggled when scrcpy is running via shortcut: MOD + O / MOD + Shift + O" diff --git a/docs/scrcpy_options/device.md b/docs/scrcpy_options/device.md index c203ab6..838337a 100644 --- a/docs/scrcpy_options/device.md +++ b/docs/scrcpy_options/device.md @@ -1,12 +1,13 @@ # Device options -| CLI option | Description (short) | Suggested GUI control | Advanced? | -|----------------------------|----------------------------------------------------------------------------------------------|--------------------------------------------|-----------| -| `--stay-awake` / `-w` | Keep device awake while plugged in; restore previous value on exit. [1] | Switch/toggle | No | -| `--turn-screen-off` / `-S` | Turn device screen off immediately on start; can be toggled back via shortcut. | Switch/toggle “Start with screen off” | No | -| `--show-touches` / `-t` | Enable “show touches” developer option while running; restore on exit. | Switch/toggle | No | -| `--start-app=PKG` | Start given app (by package) on start; supports `+` force‑stop and `?` name search prefixes. | Text input with app picker & flags (+ / ?) | No | -| `--screen-off-timeout` | Override Android screen‑off timeout (seconds) while running; restore on exit. | Number input (seconds) | Yes | -| `--power-off-on-close` | Turn device screen off when scrcpy exits. | Switch/toggle | Yes | -| `--no-power-on` | Do not automatically power on / wake device on start. | Switch/toggle | Yes | -| `--list-apps` | List installed apps on the device (for use with `--start-app`). | Button “List apps…” (opens chooser UI) | Yes | +| CLI option | Description (short) | Suggested GUI control | Advanced? | +|----------------------------|--------------------------------------------------------------------------------------------------------------------------|--------------------------------------------|-----------| +| `--stay-awake` / `-w` | Keep device awake while plugged in; restore previous value on exit. [1] | Switch/toggle | No | +| `--keep-active` | To prevent the device from turning off due to inactivity, --keep-active periodically signals user activity to the system | Switch/toggle | No | +| `--turn-screen-off` / `-S` | Turn device screen off immediately on start; can be toggled back via shortcut. | Switch/toggle “Start with screen off” | No | +| `--show-touches` / `-t` | Enable “show touches” developer option while running; restore on exit. | Switch/toggle | No | +| `--start-app=PKG` | Start given app (by package) on start; supports `+` force‑stop and `?` name search prefixes. | Text input with app picker & flags (+ / ?) | No | +| `--screen-off-timeout` | Override Android screen‑off timeout (seconds) while running; restore on exit. | Number input (seconds) | Yes | +| `--power-off-on-close` | Turn device screen off when scrcpy exits. | Switch/toggle | Yes | +| `--no-power-on` | Do not automatically power on / wake device on start. | Switch/toggle | Yes | +| `--list-apps` | List installed apps on the device (for use with `--start-app`). | Button “List apps…” (opens chooser UI) | Yes | diff --git a/lib/application/model/scrcpy/arguments/device/keep_active.dart b/lib/application/model/scrcpy/arguments/device/keep_active.dart new file mode 100644 index 0000000..cef7d8b --- /dev/null +++ b/lib/application/model/scrcpy/arguments/device/keep_active.dart @@ -0,0 +1,17 @@ +import 'package:scrcpy_buddy/application/model/scrcpy/scrcpy_cli_argument.dart'; +import 'package:scrcpy_buddy/main.dart'; + +@scrcpyArg +class KeepActive extends ScrcpyCliArgument { + @override + List toArgs(bool value) => value ? [argument] : []; + + @override + final String argument = '--keep-active'; + + @override + final String label = 'device.keepActive'; + + @override + final List? values = null; +} diff --git a/lib/application/model/scrcpy/scrcpy_arg.dart b/lib/application/model/scrcpy/scrcpy_arg.dart index 2e032a6..87b968b 100644 --- a/lib/application/model/scrcpy/scrcpy_arg.dart +++ b/lib/application/model/scrcpy/scrcpy_arg.dart @@ -31,6 +31,7 @@ export 'arguments/device/stay_awake.dart'; export 'arguments/device/turn_screen_off.dart'; export 'arguments/device/show_touches.dart'; export 'arguments/device/start_app.dart'; +export 'arguments/device/keep_active.dart'; // Window export 'arguments/window/no_window.dart'; diff --git a/lib/presentation/scrcpy_config/device/device_screen.dart b/lib/presentation/scrcpy_config/device/device_screen.dart index 67073cb..4830d3c 100644 --- a/lib/presentation/scrcpy_config/device/device_screen.dart +++ b/lib/presentation/scrcpy_config/device/device_screen.dart @@ -20,6 +20,7 @@ class _DeviceScreenState extends AppModuleState { String get module => 'config.device'; final _stayAwake = StayAwake(); + final _keepActive = KeepActive(); final _turnScreenOff = TurnScreenOff(); final _showTouches = ShowTouches(); final _startApp = StartApp(); @@ -43,6 +44,12 @@ class _DeviceScreenState extends AppModuleState { child: ConfigToggle(state: state, cliArgument: _stayAwake), ), const ConfigDivider(), + ConfigItem( + icon: WindowsIcons.touch_pointer, + cliArgument: _keepActive, + child: ConfigToggle(state: state, cliArgument: _keepActive), + ), + const ConfigDivider(), ConfigItem( icon: WindowsIcons.disconnect_display, cliArgument: _turnScreenOff, From e0090e4e6552053b7076aef26331d0b4f44ed355 Mon Sep 17 00:00:00 2001 From: Shripal Jain Date: Sun, 17 May 2026 18:16:21 +0200 Subject: [PATCH 3/4] Add documentation for planned advanced config "background color" --- docs/scrcpy_options/window.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/scrcpy_options/window.md b/docs/scrcpy_options/window.md index 7fe7dde..3aecc95 100644 --- a/docs/scrcpy_options/window.md +++ b/docs/scrcpy_options/window.md @@ -12,3 +12,4 @@ | `--window-height` | Initial window height in pixels. | Number input (px) | Yes | | `--window-borderless` | Disable window decorations (no border, no title bar). | Switch/toggle | Yes | | `--disable-screensaver` | Prevent the computer screensaver while scrcpy is running. | Switch/toggle | Yes | +| `--background-color` | Background color for the scrcpy window | Color picker | Yes | From 94b234bdc543edccebb75209d8ca7702c9498cd3 Mon Sep 17 00:00:00 2001 From: Shripal Jain Date: Sun, 17 May 2026 18:17:31 +0200 Subject: [PATCH 4/4] Update minimum supported scrcpy version --- README.md | 12 ++++++------ lib/main.dart | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 434da29..c3022a9 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ /> Flutter - scrcpy v3.3.4 + scrcpy v4.0 scrcpy-buddy scrcpy-buddy

@@ -30,7 +30,7 @@ To use this app, you need the following: - Run scrcpy on multiple connected devices - ADB Device management (Switch USB Device to network / disconnect device) - - Auto-refresh devices list + - Auto-refresh devices list - Profile management (name, customized scrcpy options, default profile) - Light / Dark theme support - View console output for devices which are running scrcpy @@ -80,7 +80,7 @@ All downloads can be found on the [latest release](https://github.com/Codertainm #### 🍺 Homebrew - `brew tap Codertainment/scrcpy_buddy` - - The tap source is available [here](https://github.com/Codertainment/homebrew-scrcpy_buddy/) + - The tap source is available [here](https://github.com/Codertainment/homebrew-scrcpy_buddy/) - `brew install scrcpy_buddy` #### Installing from DMG @@ -200,8 +200,8 @@ If you have ADB and/or scrcpy setup and installed in your path: can [set the executable in settings manually](#setting-executable-path-manually-in-settings). - To find out the installation path, run this command in the terminal: - e.g. - - For Windows: `where adb` - - For MacOS/Linux: `which adb` + - For Windows: `where adb` + - For MacOS/Linux: `which adb` ## Setting executable path manually in settings diff --git a/lib/main.dart b/lib/main.dart index f6bd6b6..0f36cde 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -20,7 +20,7 @@ import 'package:window_manager/window_manager.dart'; import 'injector.dart'; -const supportedScrcpyVersion = "3.3.4"; +const supportedScrcpyVersion = "4.0"; const scrcpyArg = ScrcpyArg();