diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..64ffe4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,76 @@ +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ +target/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +# Ignore self-extracted stuff +config.yml +restart.sh diff --git a/.idea/artifacts/ScreenScalingFixer_jar.xml b/.idea/artifacts/ScreenScalingFixer_jar.xml new file mode 100644 index 0000000..601f5a1 --- /dev/null +++ b/.idea/artifacts/ScreenScalingFixer_jar.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/out/artifacts/ScreenScalingFixer_jar + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..77809bf --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/description.html b/.idea/description.html new file mode 100644 index 0000000..db5f129 --- /dev/null +++ b/.idea/description.html @@ -0,0 +1 @@ +Simple Java application that includes a class with main() method \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..78bf31c --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d2b574f --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..4e87bac --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/project-template.xml b/.idea/project-template.xml new file mode 100644 index 0000000..1f08b88 --- /dev/null +++ b/.idea/project-template.xml @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/ScreenScalingFixer.iml b/ScreenScalingFixer.iml new file mode 100644 index 0000000..e75f198 --- /dev/null +++ b/ScreenScalingFixer.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/buildNumber.properties b/buildNumber.properties new file mode 100644 index 0000000..14f379e --- /dev/null +++ b/buildNumber.properties @@ -0,0 +1,3 @@ +#maven.buildNumber.plugin properties file +#Sun Oct 18 16:52:03 CEST 2020 +buildNumber=43 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..345c7ad --- /dev/null +++ b/pom.xml @@ -0,0 +1,100 @@ + + + 4.0.0 + + groupId + ScreenScalingFixer + 1.0-SNAPSHOT + + scm:svn:http://127.0.0.1/dummy + scm:svn:https://127.0.0.1/dummy + HEAD + http://127.0.0.1/dummy + + + + + org.apache.maven.plugins + maven-jar-plugin + + + src/main/resources/META-INF/MANIFEST.MF + + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.1 + + + buildnumber + validate + + create + + + + + {0,number} + + buildNumber + + false + false + unknownbuild + + + + maven-assembly-plugin + + + package + + single + + + + + + + net.mindoverflow.tools.ssf.Main + + + false + + jar-with-dependencies + + + + + + + + src/main/resources + true + + *.yml + *.sh + + + + + + + 1.8 + 1.8 + UTF-8 + ${project.version} + + + + org.yaml + snakeyaml + 1.21 + + + + \ No newline at end of file diff --git a/src/main/java/net/mindoverflow/tools/ssf/Main.java b/src/main/java/net/mindoverflow/tools/ssf/Main.java new file mode 100644 index 0000000..ca5f823 --- /dev/null +++ b/src/main/java/net/mindoverflow/tools/ssf/Main.java @@ -0,0 +1,183 @@ +package net.mindoverflow.tools.ssf; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import org.yaml.snakeyaml.Yaml; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.*; +import java.nio.file.Files; +import java.util.Map; + +public class Main { + + private static int restartDelay; + private static String monitorConnector; + private static double monitorScale; + private static boolean enable; + + public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException, TransformerException, InterruptedException { + File monitorConfig = new File(System.getProperty("user.home") + "/.config/monitors.xml"); + + if(!monitorConfig.exists()) + { + System.out.println("File \"monitors.xml\" does not exist! Quitting..."); + System.exit(1); + } + + if(!loadConfig()) + { + System.out.println("Error loading \"config.yml\"! Quitting..."); + System.exit(1); + } + + if(!enable) + { + System.out.println("Script disabled! Enable it by setting \"enabled: true\" in config.yml!"); + System.exit(0); + } + + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document doc = documentBuilder.parse(monitorConfig); + + Element rootElement = doc.getDocumentElement(); + System.out.println("Main element: " + rootElement.getNodeName()); + + NodeList rootNodes = rootElement.getElementsByTagName("configuration"); + Node configuration = rootNodes.item(0); + System.out.println("1 - Current node: " + configuration.getNodeName()); + NodeList logicalMonitors = configuration.getChildNodes(); + for(int pos = 0; pos < logicalMonitors.getLength(); pos++) + { + Node logicalMonitor = logicalMonitors.item(pos); + if(!logicalMonitor.getNodeName().equalsIgnoreCase("logicalmonitor")) continue; + System.out.println(" 2 - Current node: " + logicalMonitor.getNodeName()); + Node scale = getNodeByName("scale", logicalMonitor.getChildNodes()); + System.out.println(" 3A - current node: " + scale.getNodeName()); + System.out.println(" Current scale: " + scale.getTextContent()); + Node monitor = getNodeByName("monitor", logicalMonitor.getChildNodes()); + System.out.println(" 3B - current node: " + monitor.getNodeName()); + Node monitorspec = getNodeByName("monitorspec", monitor.getChildNodes()); + System.out.println(" 4 - current node: " + monitorspec.getNodeName()); + Node connector = getNodeByName("connector", monitorspec.getChildNodes()); + System.out.println(" 5 - current node: " + connector.getNodeName()); + System.out.println(" Current connector: " + connector.getTextContent()); + + String connectorValue = connector.getTextContent(); + + if(connectorValue.equalsIgnoreCase(monitorConnector)) + { + scale.setTextContent("1"); + saveFile(doc, monitorConfig); + restartGnome(); + + Thread.sleep(restartDelay); + scale.setTextContent(monitorScale + ""); + saveFile(doc, monitorConfig); + restartGnome(); + + return; + } + + } + } + + private static Node getNodeByName(String name, NodeList list) + { + for(int pos = 0; pos < list.getLength(); pos++) + { + Node current = list.item(pos); + if(current.getNodeName().equalsIgnoreCase(name)) return current; + } + + return null; + } + + private static void restartGnome() throws IOException, InterruptedException { + String s; + + InputStream stream = Main.class.getResourceAsStream("/restart.sh"); + File script = new File("restart.sh"); + if(!script.exists()) + { + System.out.println("Extracting restart script..."); + Files.copy(stream, script.getAbsoluteFile().toPath()); + System.out.println("Done!"); + } + + System.out.println("Restarting GNOME..."); + script.setExecutable(true); + Process process = Runtime.getRuntime().exec(script.getAbsolutePath()); + + BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); + + while((s = br.readLine()) != null) + { + System.out.println("line: " + s); + } + + process.waitFor(); + System.out.println ("exit: " + process.exitValue()); + process.destroy(); + } + + private static void saveFile(Document doc, File file) throws TransformerException { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + transformer.transform(new DOMSource(doc), new StreamResult(file)); + } + + private static boolean loadConfig() + { + InputStream stream = Main.class.getResourceAsStream("/config.yml"); + File config = new File("config.yml"); + if(!config.exists()) + { + System.out.println("Extracting config..."); + try + { + Files.copy(stream, config.getAbsoluteFile().toPath()); + } catch (IOException e) + { + e.printStackTrace(); + return false; + } + System.out.println("Done!"); + } + + System.out.println("Loading config..."); + Yaml configYaml = new Yaml(); + Map contents; + try + { + contents = configYaml.load(new FileInputStream(config)); + } catch (FileNotFoundException e) + { + e.printStackTrace(); + return false; + } + enable = (boolean) contents.get("enable"); + restartDelay = (int) contents.get("delay"); + monitorScale = (double) contents.get("scale"); + monitorConnector = (String) contents.get("monitor-connector"); + System.out.println("Done!"); + System.out.println("Enabled: " + enable); + System.out.println("Delay: " + restartDelay); + System.out.println("Monitor name: " + monitorConnector); + System.out.println("Monitor scale: " + monitorScale); + return true; + } +} diff --git a/src/main/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000..375f545 --- /dev/null +++ b/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: net.mindoverflow.tools.ssf.Main +