diff --git a/AutoLayout/@Resources/ResolutionChecker.lua b/AutoLayout/@Resources/ResolutionChecker.lua new file mode 100644 index 0000000..2a773e3 --- /dev/null +++ b/AutoLayout/@Resources/ResolutionChecker.lua @@ -0,0 +1,72 @@ +function Initialize() + -- Settings + onLoadDelayTime = tonumber(SKIN:GetVariable('OnLoadDelayTime')) + enableDefaultLayout = (tonumber(SKIN:GetVariable('EnableDefaultLayout')) == 1) + defaultLayout = SKIN:GetVariable('DefaultLayout') + layoutMapStr = SKIN:GetVariable('LayoutMap') + layoutMapDelimiter = SKIN:GetVariable('LayoutMapDelimiter') + + -- Convert LayoutMap string to table + layoutMap = {} + for k, v in string.gmatch(layoutMapStr, "(%d+x%d+)=(%w+)" .. layoutMapDelimiter) do + layoutMap[k] = v + end + + -- Internal + startTime = os.time() + isStarted = false + lastvw = -1 + lastvh = -1 +end + +function Update() + -- Delay to prevent instant layout change + if not isStarted then + currentTime = os.time() + elapsedTime = currentTime - startTime + + if elapsedTime < onLoadDelayTime then + message = "Starting resolution monitoring in " .. tostring(onLoadDelayTime - elapsedTime) .. " seconds..." + return message + else + isStarted = true + message = "Started resolution monitoring..." + SKIN:Bang("!Log", message) + end + end + + -- Check resolution + vw = tonumber(SKIN:GetMeasure('MeasureVW'):GetStringValue()) + vh = tonumber(SKIN:GetMeasure('MeasureVH'):GetStringValue()) + + -- Update layout on resolution changes + if ((lastvw ~= -1 and lastvh ~= -1) and (vw ~= lastvw or vh ~= lastvh)) then + resolution = tostring(vw) .. "x" .. tostring(vh) + layout = layoutMap[resolution] + + -- Use default layout if no resolution matches + if layout == nil and enableDefaultLayout then + layout = layoutMap[defaultLayout] + end + + -- Load layout + if layout ~= nil then + message = "Loading layout '" .. layout .. "'..." + SKIN:Bang("!Log", message) + SKIN:Bang("!LoadLayout", layout) + return message + end + + -- No matching resolution and default layout is not enabled + message = "Detected resolution changes from " .. tostring(lastvw) .. "x" .. tostring(lastvh) .. " to " .. tostring(vw) .. "x" .. tostring(vh) .. ", but no matching layout found. " + SKIN:Bang("!Log", message) + lastvw = vw + lastvh = vh + return message + end + + lastvw = vw + lastvh = vh + message = "Last resolution: " .. tostring(vw) .. "x" .. tostring(vh) + return message +end \ No newline at end of file diff --git a/AutoLayout/@Resources/Variables.inc b/AutoLayout/@Resources/Variables.inc new file mode 100644 index 0000000..734a476 --- /dev/null +++ b/AutoLayout/@Resources/Variables.inc @@ -0,0 +1,16 @@ +[Variables] +; Determines whether resolution monitoring is enabled +EnableMonitoring=1 +; Determines whether the debug string meter is displayed +EnableDebugString=0 +; Delay time (in seconds) after the skin is loaded before starting the resolution monitoring +OnLoadDelayTime=5 +; Determines whether to fallback to the DefaultLayout if no resolution layout is found after a resolution change +EnableDefaultLayout=0 +; Specifies the default layout name to fallback to. This is only used if EnableDefaultLayout is set to 1 +DefaultLayout="DefaultLayout" +; Associates resolutions with layouts +; Format: [virtual screen width]x[virtual screen height], separated by LayoutMapDelimiter +LayoutMap="4480x1440=Layout1|2560x1440=Layout2|1920x1080=Layout3" +; The delimiter used in LayoutMap +LayoutMapDelimiter="|" diff --git a/AutoLayout/Main.ini b/AutoLayout/Main.ini new file mode 100644 index 0000000..c479e9d Binary files /dev/null and b/AutoLayout/Main.ini differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..82381a7 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# RainMeterAutoLayout + +A rainmeter skin that will automatically switch to a specific layout on resolution changes. I often need to connect / disconnect multiple monitors, and Rainmeter seems doesn't provide a way to auto switch the layout when that happens, I will need to manually switch layout everytime that happens, which is annoying. + +So far I only found a tool named [RainRez](https://forum.rainmeter.net/viewtopic.php?t=10471) that offers similar functionality, but it only checks the default monitor's resolution, and requires running a separate .exe file, therefore I decided to make my own... + +## Installation + +1. Download the `.rmskin` file from the [Releases](https://github.com/JoeSiu/RainMeterAutoLayout/releases/latest) section. +2. Double click the `.rmskin` file to install the skin. + +## Usage + +1. To utilize AutoLayout, you must first load the `AutoLayout/Main.ini` for each layout you want to switch to, and then save the layout. +2. Edit the configuration files located at `~YourRainMeterSkinFolder\AutoLayout\@Resources\Variables.inc`, specifically the `LayoutMap` variable. + +### Configs + +| Variables | Description | Default | +| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `EnableMonitoring` | Determines whether resolution monitoring is enabled. | 1 | +| `EnableDebugString` | Determines whether the debug string meter is displayed. | 0 | +| `OnLoadDelayTime` | Delay time (in seconds) after the skin is loaded before starting the resolution monitoring. | 5 | +| `EnableDefaultLayout` | Determines whether to fallback to the `DefaultLayout` if no resolution layout is found after a resolution change. | 0 | +| `DefaultLayout` | Specifies the default layout name to fallback to. This is only used if `EnableDefaultLayout` is set to 1. | | +| `LayoutMap` | Associates resolutions with layouts.
Format: `[virtual screen width]x[virtual screen height]`, separated by `LayoutMapDelimiter`. | | +| `LayoutMapDelimiter` | The delimiter used in `LayoutMap`. | "\|" | + +- The term "virtual screen" refers to the screen that encompasses all display monitors. For example, if two horizontally aligned monitors with resolutions of `2560x1440` and `1920x1080`, the virtual screen size would be `4480x1440`. +- In the `LayoutMap` variable, if for example value `"4480x1440=Layout1|2560x1440=Layout2|1920x1080=Layout3"` is provided, it means that if both monitor is connected, then it will switch to `Layout1`; if only the 1440p monitor is connected, then it will switch to `Layout2`; and if only the 1080p monitor is connected, then it will switch to `Layout3`.