mirror of
https://github.com/kbumsik/VirtScreen.git
synced 2025-03-09 15:40:18 +00:00
Load JSON settings directly in QML
This commit is contained in:
parent
09cf4cb72f
commit
ce1debd8ad
3 changed files with 69 additions and 131 deletions
60
main.qml
60
main.qml
|
@ -7,28 +7,28 @@ import VirtScreen.Backend 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property alias window: mainLoader.item
|
property alias window: mainLoader.item
|
||||||
|
property var settings: JSON.parse(backend.settings)
|
||||||
|
property bool autostart: settings.vnc.autostart
|
||||||
|
|
||||||
|
function switchVNC () {
|
||||||
|
if ((backend.vncState == Backend.OFF) && backend.virtScreenCreated) {
|
||||||
|
backend.startVNC(settings.vnc.port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAutostartChanged: {
|
||||||
|
if (autostart) {
|
||||||
|
backend.onVirtScreenCreatedChanged.connect(switchVNC);
|
||||||
|
backend.onVncStateChanged.connect(switchVNC);
|
||||||
|
} else {
|
||||||
|
backend.onVirtScreenCreatedChanged.disconnect(switchVNC);
|
||||||
|
backend.onVncStateChanged.disconnect(switchVNC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// virtscreen.py backend.
|
// virtscreen.py backend.
|
||||||
Backend {
|
Backend {
|
||||||
id: backend
|
id: backend
|
||||||
function switchVNC () {
|
|
||||||
if ((backend.vncState == Backend.OFF) && backend.virtScreenCreated) {
|
|
||||||
backend.startVNC();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onVncAutoStartChanged: {
|
|
||||||
if (vncAutoStart) {
|
|
||||||
onVirtScreenCreatedChanged.connect(switchVNC);
|
|
||||||
onVncStateChanged.connect(switchVNC);
|
|
||||||
} else {
|
|
||||||
onVirtScreenCreatedChanged.disconnect(switchVNC);
|
|
||||||
onVncStateChanged.disconnect(switchVNC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
// force emit signal on load
|
|
||||||
vncAutoStart = vncAutoStart;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timer object and function
|
// Timer object and function
|
||||||
|
@ -140,23 +140,24 @@ Item {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
id: virtScreenAction
|
id: virtScreenAction
|
||||||
text: backend.virtScreenCreated ? "Disable Virtual Screen" : "Enable Virtual Screen"
|
text: backend.virtScreenCreated ? "Disable Virtual Screen" : "Enable Virtual Screen"
|
||||||
enabled:backend.vncAutoStart ? true :
|
enabled: autostart ? true :
|
||||||
backend.vncState == Backend.OFF ? true : false
|
backend.vncState == Backend.OFF ? true : false
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
// Give a very short delay to show busyDialog.
|
// Give a very short delay to show busyDialog.
|
||||||
timer.setTimeout (function() {
|
timer.setTimeout (function() {
|
||||||
if (!backend.virtScreenCreated) {
|
if (!backend.virtScreenCreated) {
|
||||||
backend.createVirtScreen();
|
backend.createVirtScreen(settings.virt.width, settings.virt.height,
|
||||||
|
settings.virt.portrait, settings.virt.hidpi);
|
||||||
} else {
|
} else {
|
||||||
// If auto start enabled, stop VNC first then
|
// If auto start enabled, stop VNC first then
|
||||||
if (backend.vncAutoStart && (backend.vncState != Backend.OFF)) {
|
if (autostart && (backend.vncState != Backend.OFF)) {
|
||||||
backend.vncAutoStart = false;
|
autostart = false;
|
||||||
connectOnce(backend.onVncStateChanged, function() {
|
connectOnce(backend.onVncStateChanged, function() {
|
||||||
console.log("autoOff called here", backend.vncState);
|
console.log("autoOff called here", backend.vncState);
|
||||||
if (backend.vncState == Backend.OFF) {
|
if (backend.vncState == Backend.OFF) {
|
||||||
console.log("Yes. Delete it");
|
console.log("Yes. Delete it");
|
||||||
backend.deleteVirtScreen();
|
backend.deleteVirtScreen();
|
||||||
backend.vncAutoStart = true;
|
autostart = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
backend.stopVNC();
|
backend.stopVNC();
|
||||||
|
@ -169,18 +170,21 @@ Item {
|
||||||
}
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
id: vncAction
|
id: vncAction
|
||||||
text: backend.vncAutoStart ? "Auto start enabled" :
|
text: autostart ? "Auto start enabled" :
|
||||||
backend.vncState == Backend.OFF ? "Start VNC Server" : "Stop VNC Server"
|
backend.vncState == Backend.OFF ? "Start VNC Server" : "Stop VNC Server"
|
||||||
enabled: backend.vncAutoStart ? false :
|
enabled: autostart ? false :
|
||||||
backend.virtScreenCreated ? true : false
|
backend.virtScreenCreated ? true : false
|
||||||
onTriggered: backend.vncState == Backend.OFF ? backend.startVNC() : backend.stopVNC()
|
onTriggered: backend.vncState == Backend.OFF ? backend.startVNC(settings.vnc.port) : backend.stopVNC()
|
||||||
}
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
separator: true
|
separator: true
|
||||||
}
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
|
id: quitAction
|
||||||
text: qsTr("&Quit")
|
text: qsTr("&Quit")
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
|
settings.vnc.autostart = autostart;
|
||||||
|
backend.settings = JSON.stringify(settings, null, 4);
|
||||||
backend.quitProgram();
|
backend.quitProgram();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,9 +75,7 @@ ApplicationWindow {
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: qsTr("&Quit")
|
text: qsTr("&Quit")
|
||||||
onTriggered: {
|
onTriggered: quitAction.onTriggered()
|
||||||
backend.quitProgram();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,13 +225,13 @@ ApplicationWindow {
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Label { text: "Width"; Layout.fillWidth: true }
|
Label { text: "Width"; Layout.fillWidth: true }
|
||||||
SpinBox {
|
SpinBox {
|
||||||
value: backend.virt.width
|
value: settings.virt.width
|
||||||
from: 640
|
from: 640
|
||||||
to: 1920
|
to: 1920
|
||||||
stepSize: 1
|
stepSize: 1
|
||||||
editable: true
|
editable: true
|
||||||
onValueModified: {
|
onValueModified: {
|
||||||
backend.virt.width = value;
|
settings.virt.width = value;
|
||||||
}
|
}
|
||||||
textFromValue: function(value, locale) { return value; }
|
textFromValue: function(value, locale) { return value; }
|
||||||
}
|
}
|
||||||
|
@ -241,13 +239,13 @@ ApplicationWindow {
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Label { text: "Height"; Layout.fillWidth: true }
|
Label { text: "Height"; Layout.fillWidth: true }
|
||||||
SpinBox {
|
SpinBox {
|
||||||
value: backend.virt.height
|
value: settings.virt.height
|
||||||
from: 360
|
from: 360
|
||||||
to: 1080
|
to: 1080
|
||||||
stepSize : 1
|
stepSize : 1
|
||||||
editable: true
|
editable: true
|
||||||
onValueModified: {
|
onValueModified: {
|
||||||
backend.virt.height = value;
|
settings.virt.height = value;
|
||||||
}
|
}
|
||||||
textFromValue: function(value, locale) { return value; }
|
textFromValue: function(value, locale) { return value; }
|
||||||
}
|
}
|
||||||
|
@ -255,18 +253,18 @@ ApplicationWindow {
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Label { text: "Portrait Mode"; Layout.fillWidth: true }
|
Label { text: "Portrait Mode"; Layout.fillWidth: true }
|
||||||
Switch {
|
Switch {
|
||||||
checked: backend.portrait
|
checked: settings.virt.portrait
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
backend.portrait = checked;
|
settings.virt.portrait = checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Label { text: "HiDPI (2x resolution)"; Layout.fillWidth: true }
|
Label { text: "HiDPI (2x resolution)"; Layout.fillWidth: true }
|
||||||
Switch {
|
Switch {
|
||||||
checked: backend.hidpi
|
checked: settings.virt.hidpi
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
backend.hidpi = checked;
|
settings.virt.hidpi = checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,8 +325,8 @@ ApplicationWindow {
|
||||||
if (backend.vncState != Backend.OFF) {
|
if (backend.vncState != Backend.OFF) {
|
||||||
console.log("vnc is running");
|
console.log("vnc is running");
|
||||||
var restoreVNC = true;
|
var restoreVNC = true;
|
||||||
if (backend.vncAutoStart) {
|
if (autostart) {
|
||||||
backend.vncAutoStart = false;
|
autostart = false;
|
||||||
var restoreAutoStart = true;
|
var restoreAutoStart = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,10 +334,10 @@ ApplicationWindow {
|
||||||
window.autoClose = true;
|
window.autoClose = true;
|
||||||
busyDialog.close();
|
busyDialog.close();
|
||||||
if (restoreAutoStart) {
|
if (restoreAutoStart) {
|
||||||
backend.vncAutoStart = true;
|
autostart = true;
|
||||||
}
|
}
|
||||||
if (restoreVNC) {
|
if (restoreVNC) {
|
||||||
backend.startVNC();
|
backend.startVNC(settings.vnc.port);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
backend.stopVNC();
|
backend.stopVNC();
|
||||||
|
@ -362,13 +360,13 @@ ApplicationWindow {
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Label { text: "Port"; Layout.fillWidth: true }
|
Label { text: "Port"; Layout.fillWidth: true }
|
||||||
SpinBox {
|
SpinBox {
|
||||||
value: backend.vncPort
|
value: settings.vnc.port
|
||||||
from: 1
|
from: 1
|
||||||
to: 65535
|
to: 65535
|
||||||
stepSize: 1
|
stepSize: 1
|
||||||
editable: true
|
editable: true
|
||||||
onValueModified: {
|
onValueModified: {
|
||||||
backend.vncPort = value;
|
settings.vnc.port = value;
|
||||||
}
|
}
|
||||||
textFromValue: function(value, locale) { return value; }
|
textFromValue: function(value, locale) { return value; }
|
||||||
}
|
}
|
||||||
|
@ -413,13 +411,13 @@ ApplicationWindow {
|
||||||
anchors.topMargin: vncButton.height - 10
|
anchors.topMargin: vncButton.height - 10
|
||||||
Label { text: "Auto start"; }
|
Label { text: "Auto start"; }
|
||||||
Switch {
|
Switch {
|
||||||
checked: backend.vncAutoStart
|
checked: autostart
|
||||||
onToggled: {
|
onToggled: {
|
||||||
|
autostart = checked;
|
||||||
if ((checked == true) && (backend.vncState == Backend.OFF) &&
|
if ((checked == true) && (backend.vncState == Backend.OFF) &&
|
||||||
backend.virtScreenCreated) {
|
backend.virtScreenCreated) {
|
||||||
backend.startVNC();
|
backend.startVNC(settings.vnc.port);
|
||||||
}
|
}
|
||||||
backend.vncAutoStart = checked;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
102
virtscreen.py
102
virtscreen.py
|
@ -359,18 +359,12 @@ class Backend(QObject):
|
||||||
Q_ENUMS(VNCState)
|
Q_ENUMS(VNCState)
|
||||||
# Virtual screen properties
|
# Virtual screen properties
|
||||||
xrandr: XRandR
|
xrandr: XRandR
|
||||||
_virt: Display = Display()
|
|
||||||
_virtProp: DisplayProperty
|
|
||||||
_portrait: bool
|
|
||||||
_hidpi: bool
|
|
||||||
_virtScreenCreated: bool = False
|
_virtScreenCreated: bool = False
|
||||||
screens: List[DisplayProperty]
|
screens: List[DisplayProperty]
|
||||||
_virtScreenIndex: int
|
_virtScreenIndex: int
|
||||||
# VNC server properties
|
# VNC server properties
|
||||||
_vncPort: int
|
|
||||||
_vncUsePassword: bool = False
|
_vncUsePassword: bool = False
|
||||||
_vncState: VNCState
|
_vncState: VNCState = VNCState.OFF
|
||||||
_vncAutoStart: bool
|
|
||||||
# Primary screen and mouse posistion
|
# Primary screen and mouse posistion
|
||||||
_primaryProp: DisplayProperty
|
_primaryProp: DisplayProperty
|
||||||
cursor_x: int
|
cursor_x: int
|
||||||
|
@ -388,53 +382,23 @@ class Backend(QObject):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(Backend, self).__init__(parent)
|
super(Backend, self).__init__(parent)
|
||||||
# Read JSON to load variables
|
|
||||||
try:
|
|
||||||
with open(CONFIG_PATH, "r") as f:
|
|
||||||
settings = json.load(f)
|
|
||||||
self._virt.width = settings['virt']['width']
|
|
||||||
self._virt.height = settings['virt']['height']
|
|
||||||
self._portrait = settings['virt']['portrait']
|
|
||||||
self._hidpi = settings['virt']['hidpi']
|
|
||||||
self._vncPort = settings['vnc']['port']
|
|
||||||
self._vncAutoStart = settings['vnc']['autostart']
|
|
||||||
except (FileNotFoundError, json.JSONDecodeError, KeyError):
|
|
||||||
print("Default Setting used.")
|
|
||||||
with open(DEFAULT_CONFIG_PATH, "r") as f:
|
|
||||||
settings = json.load(f)
|
|
||||||
self._virt.width = settings['virt']['width']
|
|
||||||
self._virt.height = settings['virt']['height']
|
|
||||||
self._portrait = settings['virt']['portrait']
|
|
||||||
self._hidpi = settings['virt']['hidpi']
|
|
||||||
self._vncPort = settings['vnc']['port']
|
|
||||||
self._vncAutoStart = settings['vnc']['autostart']
|
|
||||||
# create objects
|
# create objects
|
||||||
self._virtProp = DisplayProperty(self._virt)
|
|
||||||
self._vncState = self.VNCState.OFF
|
|
||||||
self.xrandr = XRandR()
|
self.xrandr = XRandR()
|
||||||
self._virtScreenIndex = self.xrandr.virt_idx
|
self._virtScreenIndex = self.xrandr.virt_idx
|
||||||
|
|
||||||
# Qt properties
|
# Qt properties
|
||||||
@pyqtProperty(DisplayProperty)
|
@pyqtProperty(str, constant=True)
|
||||||
def virt(self):
|
def settings(self):
|
||||||
return self._virtProp
|
try:
|
||||||
@virt.setter
|
with open(CONFIG_PATH, "r") as f:
|
||||||
def virt(self, virt):
|
return f.read()
|
||||||
self._virtProp = virt
|
except FileNotFoundError:
|
||||||
|
with open(DEFAULT_CONFIG_PATH, "r") as f:
|
||||||
@pyqtProperty(bool)
|
return f.read()
|
||||||
def portrait(self):
|
@settings.setter
|
||||||
return self._portrait
|
def settings(self, json_str):
|
||||||
@portrait.setter
|
with open(CONFIG_PATH, "w") as f:
|
||||||
def portrait(self, portrait):
|
f.write(json_str)
|
||||||
self._portrait = portrait
|
|
||||||
|
|
||||||
@pyqtProperty(bool)
|
|
||||||
def hidpi(self):
|
|
||||||
return self._hidpi
|
|
||||||
@hidpi.setter
|
|
||||||
def hidpi(self, hidpi):
|
|
||||||
self._hidpi = hidpi
|
|
||||||
|
|
||||||
@pyqtProperty(bool, notify=onVirtScreenCreatedChanged)
|
@pyqtProperty(bool, notify=onVirtScreenCreatedChanged)
|
||||||
def virtScreenCreated(self):
|
def virtScreenCreated(self):
|
||||||
|
@ -444,7 +408,7 @@ class Backend(QObject):
|
||||||
self._virtScreenCreated = value
|
self._virtScreenCreated = value
|
||||||
self.onVirtScreenCreatedChanged.emit(value)
|
self.onVirtScreenCreatedChanged.emit(value)
|
||||||
|
|
||||||
@pyqtProperty(QQmlListProperty)
|
@pyqtProperty(QQmlListProperty, constant=True)
|
||||||
def screens(self):
|
def screens(self):
|
||||||
return QQmlListProperty(DisplayProperty, self, [DisplayProperty(x) for x in self.xrandr.screens])
|
return QQmlListProperty(DisplayProperty, self, [DisplayProperty(x) for x in self.xrandr.screens])
|
||||||
|
|
||||||
|
@ -458,13 +422,6 @@ class Backend(QObject):
|
||||||
self.xrandr.virt = self.xrandr.screens[self.xrandr.virt_idx]
|
self.xrandr.virt = self.xrandr.screens[self.xrandr.virt_idx]
|
||||||
self._virtScreenIndex = virtScreenIndex
|
self._virtScreenIndex = virtScreenIndex
|
||||||
|
|
||||||
@pyqtProperty(int)
|
|
||||||
def vncPort(self):
|
|
||||||
return self._vncPort
|
|
||||||
@vncPort.setter
|
|
||||||
def vncPort(self, port):
|
|
||||||
self._vncPort = port
|
|
||||||
|
|
||||||
@pyqtProperty(bool, notify=onVncUsePasswordChanged)
|
@pyqtProperty(bool, notify=onVncUsePasswordChanged)
|
||||||
def vncUsePassword(self):
|
def vncUsePassword(self):
|
||||||
if os.path.isfile(X11VNC_PASSWORD_PATH):
|
if os.path.isfile(X11VNC_PASSWORD_PATH):
|
||||||
|
@ -485,14 +442,6 @@ class Backend(QObject):
|
||||||
def vncState(self, state):
|
def vncState(self, state):
|
||||||
self._vncState = state
|
self._vncState = state
|
||||||
self.onVncStateChanged.emit(self._vncState)
|
self.onVncStateChanged.emit(self._vncState)
|
||||||
|
|
||||||
@pyqtProperty(bool, notify=onVncAutoStartChanged)
|
|
||||||
def vncAutoStart(self):
|
|
||||||
return self._vncAutoStart
|
|
||||||
@vncAutoStart.setter
|
|
||||||
def vncAutoStart(self, vncAutoStart):
|
|
||||||
self._vncAutoStart = vncAutoStart
|
|
||||||
self.onVncAutoStartChanged.emit(vncAutoStart)
|
|
||||||
|
|
||||||
@pyqtProperty('QStringList', notify=onIPAddressesChanged)
|
@pyqtProperty('QStringList', notify=onIPAddressesChanged)
|
||||||
def ipAddresses(self):
|
def ipAddresses(self):
|
||||||
|
@ -522,10 +471,10 @@ class Backend(QObject):
|
||||||
return cursor.y()
|
return cursor.y()
|
||||||
|
|
||||||
# Qt Slots
|
# Qt Slots
|
||||||
@pyqtSlot()
|
@pyqtSlot(int, int, bool, bool)
|
||||||
def createVirtScreen(self):
|
def createVirtScreen(self, width, height, portrait, hidpi):
|
||||||
print("Creating a Virtual Screen...")
|
print("Creating a Virtual Screen...")
|
||||||
self.xrandr.create_virtual_screen(self._virt.width, self._virt.height, self.portrait, self.hidpi)
|
self.xrandr.create_virtual_screen(width, height, portrait, hidpi)
|
||||||
self.virtScreenCreated = True
|
self.virtScreenCreated = True
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
|
@ -560,8 +509,8 @@ class Backend(QObject):
|
||||||
else:
|
else:
|
||||||
print("Failed deleting the password file")
|
print("Failed deleting the password file")
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot(int)
|
||||||
def startVNC(self):
|
def startVNC(self, port):
|
||||||
# Check if a virtual screen created
|
# Check if a virtual screen created
|
||||||
if not self.virtScreenCreated:
|
if not self.virtScreenCreated:
|
||||||
print("Virtual Screen not crated.")
|
print("Virtual Screen not crated.")
|
||||||
|
@ -590,7 +539,6 @@ class Backend(QObject):
|
||||||
atexit.unregister(self.stopVNC)
|
atexit.unregister(self.stopVNC)
|
||||||
logfile = open(X11VNC_LOG_PATH, "wb")
|
logfile = open(X11VNC_LOG_PATH, "wb")
|
||||||
self.vncServer = ProcessProtocol(_onConnected, _onReceived, _onReceived, _onEnded, logfile)
|
self.vncServer = ProcessProtocol(_onConnected, _onReceived, _onReceived, _onEnded, logfile)
|
||||||
port = self.vncPort
|
|
||||||
virt = self.xrandr.get_virtual_screen()
|
virt = self.xrandr.get_virtual_screen()
|
||||||
clip = f"{virt.width}x{virt.height}+{virt.x_offset}+{virt.y_offset}"
|
clip = f"{virt.width}x{virt.height}+{virt.x_offset}+{virt.y_offset}"
|
||||||
arg = f"x11vnc -multiptr -repeat -rfbport {port} -clip {clip}"
|
arg = f"x11vnc -multiptr -repeat -rfbport {port} -clip {clip}"
|
||||||
|
@ -635,18 +583,6 @@ class Backend(QObject):
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def quitProgram(self):
|
def quitProgram(self):
|
||||||
# Save settings first
|
|
||||||
with open(CONFIG_PATH, 'w') as f:
|
|
||||||
settings = {}
|
|
||||||
settings['virt'] = {}
|
|
||||||
settings['virt']['width'] = self._virt.width
|
|
||||||
settings['virt']['height'] = self._virt.height
|
|
||||||
settings['virt']['portrait'] = self._portrait
|
|
||||||
settings['virt']['hidpi'] = self._hidpi
|
|
||||||
settings['vnc'] = {}
|
|
||||||
settings['vnc']['port'] = self._vncPort
|
|
||||||
settings['vnc']['autostart'] = self._vncAutoStart
|
|
||||||
json.dump(settings, f, sort_keys=True, indent=4)
|
|
||||||
self.blockSignals(True) # This will prevent invoking auto-restart or etc.
|
self.blockSignals(True) # This will prevent invoking auto-restart or etc.
|
||||||
QApplication.instance().quit()
|
QApplication.instance().quit()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue