Add an Apply button to the Web UI when running as a Win32 Service (#700)
This commit is contained in:
@@ -494,6 +494,7 @@ void getConfig(resp_https_t response, req_https_t request) {
|
|||||||
|
|
||||||
outputTree.put("status", "true");
|
outputTree.put("status", "true");
|
||||||
outputTree.put("platform", SUNSHINE_PLATFORM);
|
outputTree.put("platform", SUNSHINE_PLATFORM);
|
||||||
|
outputTree.put("restart_supported", platf::restart_supported());
|
||||||
|
|
||||||
auto vars = config::parse_config(read_file(config::sunshine.config_file.c_str()));
|
auto vars = config::parse_config(read_file(config::sunshine.config_file.c_str()));
|
||||||
|
|
||||||
@@ -537,6 +538,37 @@ void saveConfig(resp_https_t response, req_https_t request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void restart(resp_https_t response, req_https_t request) {
|
||||||
|
if(!authenticate(response, request)) return;
|
||||||
|
|
||||||
|
print_req(request);
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
std::stringstream configStream;
|
||||||
|
ss << request->content.rdbuf();
|
||||||
|
pt::ptree outputTree;
|
||||||
|
auto g = util::fail_guard([&]() {
|
||||||
|
std::ostringstream data;
|
||||||
|
|
||||||
|
pt::write_json(data, outputTree);
|
||||||
|
response->write(data.str());
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!platf::restart_supported()) {
|
||||||
|
outputTree.put("status", false);
|
||||||
|
outputTree.put("error", "Restart is not currently supported on this platform");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!platf::restart()) {
|
||||||
|
outputTree.put("status", false);
|
||||||
|
outputTree.put("error", "Restart failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputTree.put("status", true);
|
||||||
|
}
|
||||||
|
|
||||||
void savePassword(resp_https_t response, req_https_t request) {
|
void savePassword(resp_https_t response, req_https_t request) {
|
||||||
if(!config::sunshine.username.empty() && !authenticate(response, request)) return;
|
if(!config::sunshine.username.empty() && !authenticate(response, request)) return;
|
||||||
|
|
||||||
@@ -678,6 +710,7 @@ void start() {
|
|||||||
server.resource["^/api/apps$"]["POST"] = saveApp;
|
server.resource["^/api/apps$"]["POST"] = saveApp;
|
||||||
server.resource["^/api/config$"]["GET"] = getConfig;
|
server.resource["^/api/config$"]["GET"] = getConfig;
|
||||||
server.resource["^/api/config$"]["POST"] = saveConfig;
|
server.resource["^/api/config$"]["POST"] = saveConfig;
|
||||||
|
server.resource["^/api/restart$"]["POST"] = restart;
|
||||||
server.resource["^/api/password$"]["POST"] = savePassword;
|
server.resource["^/api/password$"]["POST"] = savePassword;
|
||||||
server.resource["^/api/apps/([0-9]+)$"]["DELETE"] = deleteApp;
|
server.resource["^/api/apps/([0-9]+)$"]["DELETE"] = deleteApp;
|
||||||
server.resource["^/api/clients/unpair$"]["POST"] = unpairAll;
|
server.resource["^/api/clients/unpair$"]["POST"] = unpairAll;
|
||||||
|
|||||||
@@ -318,6 +318,9 @@ void adjust_thread_priority(thread_priority_e priority);
|
|||||||
void streaming_will_start();
|
void streaming_will_start();
|
||||||
void streaming_will_stop();
|
void streaming_will_stop();
|
||||||
|
|
||||||
|
bool restart_supported();
|
||||||
|
bool restart();
|
||||||
|
|
||||||
input_t input();
|
input_t input();
|
||||||
void move_mouse(input_t &input, int deltaX, int deltaY);
|
void move_mouse(input_t &input, int deltaX, int deltaY);
|
||||||
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y);
|
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y);
|
||||||
|
|||||||
@@ -165,6 +165,16 @@ void streaming_will_stop() {
|
|||||||
// Nothing to do
|
// Nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool restart_supported() {
|
||||||
|
// Restart not supported yet
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool restart() {
|
||||||
|
// Restart not supported yet
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
namespace source {
|
namespace source {
|
||||||
enum source_e : std::size_t {
|
enum source_e : std::size_t {
|
||||||
#ifdef SUNSHINE_BUILD_CUDA
|
#ifdef SUNSHINE_BUILD_CUDA
|
||||||
|
|||||||
@@ -143,6 +143,16 @@ void streaming_will_stop() {
|
|||||||
// Nothing to do
|
// Nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool restart_supported() {
|
||||||
|
// Restart not supported yet
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool restart() {
|
||||||
|
// Restart not supported yet
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace platf
|
} // namespace platf
|
||||||
|
|
||||||
namespace dyn {
|
namespace dyn {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <csignal>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -522,4 +523,16 @@ void streaming_will_stop() {
|
|||||||
DwmEnableMMCSS(false);
|
DwmEnableMMCSS(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool restart_supported() {
|
||||||
|
// Restart is supported if we're running from the service
|
||||||
|
return (GetConsoleWindow() == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool restart() {
|
||||||
|
// Raise SIGINT to trigger the graceful exit logic. The service will
|
||||||
|
// restart us in a few seconds.
|
||||||
|
std::raise(SIGINT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace platf
|
} // namespace platf
|
||||||
@@ -765,11 +765,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-success my-4" v-if="success">
|
<div class="alert alert-success my-4" v-if="saved && restart_supported">
|
||||||
<b>Success!</b> Restart Sunshine to apply changes
|
<b>Success!</b> Click 'Apply' to restart Sunshine and apply changes. This will terminate any running sessions.
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-success my-4" v-if="saved && !restart_supported">
|
||||||
|
<b>Success!</b> Restart Sunshine to apply changes.
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-success my-4" v-if="restarted">
|
||||||
|
<b>Success!</b> Sunshine is restarting to apply changes.
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3 buttons">
|
<div class="mb-3 buttons">
|
||||||
<button class="btn btn-primary" @click="save">Save</button>
|
<button class="btn btn-primary" @click="save">Save</button>
|
||||||
|
<button class="btn btn-success" @click="apply" v-if="saved && restart_supported && !restarted">Apply</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -779,7 +786,9 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
platform: "",
|
platform: "",
|
||||||
success: false,
|
restart_supported: false,
|
||||||
|
saved: false,
|
||||||
|
restarted: false,
|
||||||
config: null,
|
config: null,
|
||||||
fps: [],
|
fps: [],
|
||||||
resolutions: [],
|
resolutions: [],
|
||||||
@@ -836,6 +845,7 @@
|
|||||||
.then((r) => {
|
.then((r) => {
|
||||||
this.config = r;
|
this.config = r;
|
||||||
this.platform = this.config.platform;
|
this.platform = this.config.platform;
|
||||||
|
this.restart_supported = (this.config.restart_supported === "true");
|
||||||
|
|
||||||
var app = document.getElementById("app");
|
var app = document.getElementById("app");
|
||||||
if (this.platform == "windows") {
|
if (this.platform == "windows") {
|
||||||
@@ -856,6 +866,7 @@
|
|||||||
|
|
||||||
delete this.config.status;
|
delete this.config.status;
|
||||||
delete this.config.platform;
|
delete this.config.platform;
|
||||||
|
delete this.config.restart_supported;
|
||||||
//Populate default values if not present in config
|
//Populate default values if not present in config
|
||||||
this.config.key_rightalt_to_key_win =
|
this.config.key_rightalt_to_key_win =
|
||||||
this.config.key_rightalt_to_key_win || "disabled";
|
this.config.key_rightalt_to_key_win || "disabled";
|
||||||
@@ -895,8 +906,7 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
save() {
|
serialize() {
|
||||||
this.success = false;
|
|
||||||
let nl = this.config === "windows" ? "\r\n" : "\n";
|
let nl = this.config === "windows" ? "\r\n" : "\n";
|
||||||
this.config.resolutions =
|
this.config.resolutions =
|
||||||
"[" +
|
"[" +
|
||||||
@@ -906,12 +916,31 @@
|
|||||||
nl +
|
nl +
|
||||||
"]";
|
"]";
|
||||||
this.config.fps = JSON.stringify(this.fps);
|
this.config.fps = JSON.stringify(this.fps);
|
||||||
|
},
|
||||||
|
save() {
|
||||||
|
this.saved = this.restarted = false;
|
||||||
|
this.serialize();
|
||||||
fetch("/api/config", {
|
fetch("/api/config", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(this.config),
|
body: JSON.stringify(this.config),
|
||||||
}).then((r) => {
|
}).then((r) => {
|
||||||
if (r.status == 200) this.success = true;
|
if (r.status == 200) this.saved = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
apply() {
|
||||||
|
this.saved = this.restarted = false;
|
||||||
|
this.serialize();
|
||||||
|
fetch("/api/config", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(this.config),
|
||||||
|
}).then((r) => {
|
||||||
|
if (r.status == 200) {
|
||||||
|
fetch("/api/restart", {
|
||||||
|
method: "POST",
|
||||||
|
}).then((r) => {
|
||||||
|
if (r.status == 200) this.restarted = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<br />
|
<br />
|
||||||
<p>
|
<p>
|
||||||
If Moonlight complains about an app currently running, force closing the
|
If Moonlight complains about an app currently running, force closing the
|
||||||
app should fix the issue
|
app should fix the issue.
|
||||||
</p>
|
</p>
|
||||||
<div class="alert alert-success" v-if="closeAppStatus === true">
|
<div class="alert alert-success" v-if="closeAppStatus === true">
|
||||||
Application Closed Successfuly!
|
Application Closed Successfully!
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-danger" v-if="closeAppStatus === false">
|
<div class="alert alert-danger" v-if="closeAppStatus === false">
|
||||||
Error while closing Appplication
|
Error while closing Appplication
|
||||||
@@ -22,6 +22,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!--Restart Sunshine-->
|
||||||
|
<div class="card p-2 my-4" v-if="restartSupported">
|
||||||
|
<div class="card-body">
|
||||||
|
<h2>Restart Sunshine</h2>
|
||||||
|
<br />
|
||||||
|
<p>
|
||||||
|
If Sunshine isn't working properly, you can try restarting it.
|
||||||
|
This will terminate any running sessions.
|
||||||
|
</p>
|
||||||
|
<div class="alert alert-success" v-if="restartStatus === true">
|
||||||
|
Sunshine is restarting
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-danger" v-if="restartStatus === false">
|
||||||
|
Error restarting Sunshine
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button class="btn btn-warning" :disabled="restartPressed" @click="restart">
|
||||||
|
Restart Sunshine
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!--Unpair all Clients-->
|
<!--Unpair all Clients-->
|
||||||
<div class="card p-2 my-4">
|
<div class="card p-2 my-4">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -68,6 +90,9 @@
|
|||||||
closeAppStatus: null,
|
closeAppStatus: null,
|
||||||
unpairAllPressed: false,
|
unpairAllPressed: false,
|
||||||
unpairAllStatus: null,
|
unpairAllStatus: null,
|
||||||
|
restartSupported: false,
|
||||||
|
restartPressed: false,
|
||||||
|
restartStatus: null,
|
||||||
logs: 'Loading...',
|
logs: 'Loading...',
|
||||||
logFilter: null,
|
logFilter: null,
|
||||||
logInterval: null,
|
logInterval: null,
|
||||||
@@ -86,6 +111,11 @@
|
|||||||
this.refreshLogs();
|
this.refreshLogs();
|
||||||
}, 5000);
|
}, 5000);
|
||||||
this.refreshLogs();
|
this.refreshLogs();
|
||||||
|
fetch("/api/config")
|
||||||
|
.then((r) => r.json())
|
||||||
|
.then((r) => {
|
||||||
|
this.restartSupported = (r.restart_supported === "true");
|
||||||
|
});
|
||||||
},
|
},
|
||||||
beforeDestroy(){
|
beforeDestroy(){
|
||||||
clearInterval(this.logInterval);
|
clearInterval(this.logInterval);
|
||||||
@@ -124,7 +154,22 @@
|
|||||||
},
|
},
|
||||||
copyLogs(){
|
copyLogs(){
|
||||||
navigator.clipboard.writeText(this.actualLogs);
|
navigator.clipboard.writeText(this.actualLogs);
|
||||||
}
|
},
|
||||||
|
restart() {
|
||||||
|
this.restartPressed = true;
|
||||||
|
fetch("/api/restart", {
|
||||||
|
method: "POST",
|
||||||
|
}).then((r) => {
|
||||||
|
this.restartPressed = false;
|
||||||
|
|
||||||
|
// We won't get a response in the success case
|
||||||
|
this.restartStatus = r.status.toString() !== "false";
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.restartStatus = null;
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user