diff --git a/README.md b/README.md
index ea5731a7..09cb27b8 100644
--- a/README.md
+++ b/README.md
@@ -396,6 +396,18 @@ The list of display ids can be retrieved by:
 adb shell dumpsys display   # search "mDisplayId=" in the output
 ```
 
+#### Stay awake
+
+To prevent the device to sleep after some delay:
+
+```bash
+scrcpy --stay-awake
+scrcpy -w
+```
+
+The initial state is restored when scrcpy is closed.
+
+
 #### Turn screen off
 
 It is possible to turn the device screen off while mirroring on start with a
@@ -410,6 +422,14 @@ Or by pressing `Ctrl`+`o` at any time.
 
 To turn it back on, press `POWER` (or `Ctrl`+`p`).
 
+It can be useful to also prevent the device to sleep:
+
+```bash
+scrcpy --turn-screen-off --stay-awake
+scrcpy -Sw
+```
+
+
 #### Render expired frames
 
 By default, to minimize latency, _scrcpy_ always renders the last decoded frame
diff --git a/app/scrcpy.1 b/app/scrcpy.1
index 15200460..02389159 100644
--- a/app/scrcpy.1
+++ b/app/scrcpy.1
@@ -144,6 +144,10 @@ It only shows physical touches (not clicks from scrcpy).
 .B \-v, \-\-version
 Print the version of scrcpy.
 
+.TP
+.B \-w, \-\-stay-awake
+Keep the device on while scrcpy is running.
+
 .TP
 .B \-\-window\-borderless
 Disable window decorations (display borderless window).
diff --git a/app/src/cli.c b/app/src/cli.c
index d49301ac..0c68279f 100644
--- a/app/src/cli.c
+++ b/app/src/cli.c
@@ -137,6 +137,9 @@ scrcpy_print_usage(const char *arg0) {
         "    -v, --version\n"
         "        Print the version of scrcpy.\n"
         "\n"
+        "    -w, --stay-awake\n"
+        "        Keep the device on while scrcpy is running.\n"
+        "\n"
         "    --window-borderless\n"
         "        Disable window decorations (display borderless window).\n"
         "\n"
@@ -497,6 +500,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
         {"rotation",               required_argument, NULL, OPT_ROTATION},
         {"serial",                 required_argument, NULL, 's'},
         {"show-touches",           no_argument,       NULL, 't'},
+        {"stay-awake",             no_argument,       NULL, 'w'},
         {"turn-screen-off",        no_argument,       NULL, 'S'},
         {"version",                no_argument,       NULL, 'v'},
         {"window-title",           required_argument, NULL, OPT_WINDOW_TITLE},
@@ -514,7 +518,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
     optind = 0; // reset to start from the first argument in tests
 
     int c;
-    while ((c = getopt_long(argc, argv, "b:c:fF:hm:nNp:r:s:StTv", long_options,
+    while ((c = getopt_long(argc, argv, "b:c:fF:hm:nNp:r:s:StTvw", long_options,
                             NULL)) != -1) {
         switch (c) {
             case 'b':
@@ -594,6 +598,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
             case 'v':
                 args->version = true;
                 break;
+            case 'w':
+                opts->stay_awake = true;
+                break;
             case OPT_RENDER_EXPIRED_FRAMES:
                 opts->render_expired_frames = true;
                 break;
@@ -676,5 +683,10 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
         return false;
     }
 
+    if (!opts->control && opts->stay_awake) {
+        LOGE("Could not request to stay awake if control is disabled");
+        return false;
+    }
+
     return true;
 }
diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c
index 015dec08..c085e769 100644
--- a/app/src/scrcpy.c
+++ b/app/src/scrcpy.c
@@ -278,6 +278,7 @@ scrcpy(const struct scrcpy_options *options) {
         .control = options->control,
         .display_id = options->display_id,
         .show_touches = options->show_touches,
+        .stay_awake = options->stay_awake,
     };
     if (!server_start(&server, options->serial, &params)) {
         return false;
diff --git a/app/src/scrcpy.h b/app/src/scrcpy.h
index d6b0a0f6..99e72ef0 100644
--- a/app/src/scrcpy.h
+++ b/app/src/scrcpy.h
@@ -38,6 +38,7 @@ struct scrcpy_options {
     bool prefer_text;
     bool window_borderless;
     bool mipmaps;
+    bool stay_awake;
 };
 
 #define SCRCPY_OPTIONS_DEFAULT { \
@@ -72,6 +73,7 @@ struct scrcpy_options {
     .prefer_text = false, \
     .window_borderless = false, \
     .mipmaps = true, \
+    .stay_awake = false, \
 }
 
 bool
diff --git a/app/src/server.c b/app/src/server.c
index 5399d269..b98cec2f 100644
--- a/app/src/server.c
+++ b/app/src/server.c
@@ -269,6 +269,7 @@ execute_server(struct server *server, const struct server_params *params) {
         params->control ? "true" : "false",
         display_id_string,
         params->show_touches ? "true" : "false",
+        params->stay_awake ? "true" : "false",
     };
 #ifdef SERVER_DEBUGGER
     LOGI("Server debugger waiting for a client on device port "
diff --git a/app/src/server.h b/app/src/server.h
index 33e99bea..13d0b451 100644
--- a/app/src/server.h
+++ b/app/src/server.h
@@ -52,6 +52,7 @@ struct server_params {
     bool control;
     uint16_t display_id;
     bool show_touches;
+    bool stay_awake;
 };
 
 // init default values
diff --git a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
index ccbca275..74555636 100644
--- a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
+++ b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
@@ -19,18 +19,18 @@ public final class CleanUp {
         // not instantiable
     }
 
-    public static void configure(boolean disableShowTouches) throws IOException {
-        boolean needProcess = disableShowTouches;
+    public static void configure(boolean disableShowTouches, int restoreStayOn) throws IOException {
+        boolean needProcess = disableShowTouches || restoreStayOn != -1;
         if (needProcess) {
-            startProcess(disableShowTouches);
+            startProcess(disableShowTouches, restoreStayOn);
         } else {
             // There is no additional clean up to do when scrcpy dies
             unlinkSelf();
         }
     }
 
-    private static void startProcess(boolean disableShowTouches) throws IOException {
-        String[] cmd = {"app_process", "/", CleanUp.class.getName(), String.valueOf(disableShowTouches)};
+    private static void startProcess(boolean disableShowTouches, int restoreStayOn) throws IOException {
+        String[] cmd = {"app_process", "/", CleanUp.class.getName(), String.valueOf(disableShowTouches), String.valueOf(restoreStayOn)};
 
         ProcessBuilder builder = new ProcessBuilder(cmd);
         builder.environment().put("CLASSPATH", SERVER_PATH);
@@ -58,12 +58,19 @@ public final class CleanUp {
         Ln.i("Cleaning up");
 
         boolean disableShowTouches = Boolean.parseBoolean(args[0]);
+        int restoreStayOn = Integer.parseInt(args[1]);
 
-        if (disableShowTouches) {
+        if (disableShowTouches || restoreStayOn != -1) {
             ServiceManager serviceManager = new ServiceManager();
             try (ContentProvider settings = serviceManager.getActivityManager().createSettingsProvider()) {
-                Ln.i("Disabling \"show touches\"");
-                settings.putValue(ContentProvider.TABLE_SYSTEM, "show_touches", "0");
+                if (disableShowTouches) {
+                    Ln.i("Disabling \"show touches\"");
+                    settings.putValue(ContentProvider.TABLE_SYSTEM, "show_touches", "0");
+                }
+                if (restoreStayOn != -1) {
+                    Ln.i("Restoring \"stay awake\"");
+                    settings.putValue(ContentProvider.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(restoreStayOn));
+                }
             }
         }
     }
diff --git a/server/src/main/java/com/genymobile/scrcpy/Options.java b/server/src/main/java/com/genymobile/scrcpy/Options.java
index 838416c8..152aa2f7 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Options.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Options.java
@@ -13,6 +13,7 @@ public class Options {
     private boolean control;
     private int displayId;
     private boolean showTouches;
+    private boolean stayAwake;
 
     public int getMaxSize() {
         return maxSize;
@@ -93,4 +94,12 @@ public class Options {
     public void setShowTouches(boolean showTouches) {
         this.showTouches = showTouches;
     }
+
+    public boolean getStayAwake() {
+        return stayAwake;
+    }
+
+    public void setStayAwake(boolean stayAwake) {
+        this.stayAwake = stayAwake;
+    }
 }
diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java
index 43ab0f55..73776c3e 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Server.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Server.java
@@ -4,6 +4,7 @@ import com.genymobile.scrcpy.wrappers.ContentProvider;
 
 import android.graphics.Rect;
 import android.media.MediaCodec;
+import android.os.BatteryManager;
 import android.os.Build;
 
 import java.io.IOException;
@@ -20,15 +21,32 @@ public final class Server {
         final Device device = new Device(options);
 
         boolean mustDisableShowTouchesOnCleanUp = false;
-        if (options.getShowTouches()) {
+        int restoreStayOn = -1;
+        if (options.getShowTouches() || options.getStayAwake()) {
             try (ContentProvider settings = device.createSettingsProvider()) {
-                String oldValue = settings.getAndPutValue(ContentProvider.TABLE_SYSTEM, "show_touches", "1");
-                // If "show touches" was disabled, it must be disabled back on clean up
-                mustDisableShowTouchesOnCleanUp = !"1".equals(oldValue);
+                if (options.getShowTouches()) {
+                    String oldValue = settings.getAndPutValue(ContentProvider.TABLE_SYSTEM, "show_touches", "1");
+                    // If "show touches" was disabled, it must be disabled back on clean up
+                    mustDisableShowTouchesOnCleanUp = !"1".equals(oldValue);
+                }
+
+                if (options.getStayAwake()) {
+                    int stayOn = BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS;
+                    String oldValue = settings.getAndPutValue(ContentProvider.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(stayOn));
+                    try {
+                        restoreStayOn = Integer.parseInt(oldValue);
+                        if (restoreStayOn == stayOn) {
+                            // No need to restore
+                            restoreStayOn = -1;
+                        }
+                    } catch (NumberFormatException e) {
+                        restoreStayOn = 0;
+                    }
+                }
             }
         }
 
-        CleanUp.configure(mustDisableShowTouchesOnCleanUp);
+        CleanUp.configure(mustDisableShowTouchesOnCleanUp, restoreStayOn);
 
         boolean tunnelForward = options.isTunnelForward();
         try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) {
@@ -91,7 +109,7 @@ public final class Server {
                     "The server version (" + BuildConfig.VERSION_NAME + ") does not match the client " + "(" + clientVersion + ")");
         }
 
-        final int expectedParameters = 11;
+        final int expectedParameters = 12;
         if (args.length != expectedParameters) {
             throw new IllegalArgumentException("Expecting " + expectedParameters + " parameters");
         }
@@ -129,6 +147,9 @@ public final class Server {
         boolean showTouches = Boolean.parseBoolean(args[10]);
         options.setShowTouches(showTouches);
 
+        boolean stayAwake = Boolean.parseBoolean(args[11]);
+        options.setStayAwake(stayAwake);
+
         return options;
     }