It is currently May 8th, 2024, 10:58 am

Detect current monitor

Get help with creating, editing & fixing problems with skins
Budgies
Posts: 25
Joined: November 19th, 2014, 4:17 pm

Detect current monitor

Post by Budgies »

I was wondering if there is some magical line of code that would tell me what the current monitor the skin is on. For example the #WindowX@N# I have to manually put the number in, but I would like to automatically detect. I don't even need the WindowX, just the @N.
Last edited by Budgies on June 14th, 2015, 12:59 pm, edited 1 time in total.
User avatar
jsmorley
Developer
Posts: 22631
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Detect current monitor

Post by jsmorley »

This is tricky and a bit complicated.

Rainmeter by default will treat all skins as being on the "virtual screen", which is a screen area made up of the combined width and largest height of all monitors (assuming a horizontal positioning of the monitors).

So if you have two monitors, one 1680 X 1050 and one 1280 X 1024 (for instance) then the virtual screen is 2960 X 1050 and Rainmeter won't care which physical monitor the skin is on.

If you specify which monitor the skin is on in Rainmeter.ini, with WindowX=500@2 for example, then while it won't "keep" the skin on monitor two, it will maintain the number for WindowX as "relative" to the second monitor. So if you drag the skin to monitor one, it might be a negative WindowX=-350@2.

If you set "Auto select based on window position" in Manage, which will set or change the "AutoSelectScreen" option in Rainmeter.ini, then it will automatically set the "@N" number on the end of WindowX/WindowY based on what monitor the skin is actually on at any given time, and make the pixel values absolute to that monitor, rather than relative to the virtual screen.

However, you can't really "know" what monitor the skin is on at any given time in a really simple way, as there is no real mechanism for returning that value to a skin.

There are a bunch of built-in variables for monitor stuff, but they just return the size of the various virtual screens and monitors, and you have to specify which monitor you are interested in.

There are some built-in variables for the size and position of the current skin, but those are ALWAYS relative to the "virtual screen".

Really the only way to know for sure what monitor a skin is on is to do some math and a comparison. In effect you need to know the size of each monitor, then the current position of the skin, and a pretty simple "greater than / less than" comparison can tell you which monitor the skin is on.

I guess I'd have to know what use you plan to make of knowing which monitor the skin is on. What you plan to do with it might make a difference in the best approach to getting it.

While it would be quite difficult indeed to automatically detect how many monitors a user's system has, in any way that would be useful, you can use some variables to know what monitor a skin is on as long as you are using the skin on your system.

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[MeasureMonitor]
Measure=Calc
Formula=#CURRENTCONFIGX# > #SCREENAREAWIDTH@1# ? 2 : 1
DynamicVariables=1

[MeterOne]
Meter=String
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
Text=Current Position: #CURRENTCONFIGX# x #CURRENTCONFIGY##CRLF#Monitor 1: #SCREENAREAWIDTH@1# x #SCREENAREAHEIGHT@1##CRLF#Monitor 2: #SCREENAREAWIDTH@2# x #SCREENAREAHEIGHT@2##CRLF#Current Monitor: [MeasureMonitor]
DynamicVariables=1
1.jpg
You do not have the required permissions to view the files attached to this post.
Budgies
Posts: 25
Joined: November 19th, 2014, 4:17 pm

Re: Detect current monitor

Post by Budgies »

Thanks, I was just planing to make a slideshow, and when you click fullscreen it would auto detect what monitor your skin is on and make the image fullscreen on the same monitor. I guess I could try some math.
Budgies
Posts: 25
Joined: November 19th, 2014, 4:17 pm

Re: Detect current monitor

Post by Budgies »

Woah, you did that fast. Thanks that helped a lot.
User avatar
jsmorley
Developer
Posts: 22631
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Detect current monitor

Post by jsmorley »

Making this automatic for any user, where you don't know how many monitors they have, will add some additional trickiness to this. You can use the SysInfo plugin to get NUM_MONITORS and use that in your calculation, but it will take some thought to get the right set of built-in variables, calculations and comparisons. If the user has more than two monitors, this is likely to be better done in Lua, where doing a For/Next loop might help a lot.
Budgies
Posts: 25
Joined: November 19th, 2014, 4:17 pm

Re: Detect current monitor

Post by Budgies »

Quick question, is there a way to force add AutoSelectScreen=1 to the Rainmeter.ini so you don't have to manually do it yourself?
User avatar
jsmorley
Developer
Posts: 22631
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Detect current monitor

Post by jsmorley »

Budgies wrote:Quick question, is there a way to force add AutoSelectScreen=1 to the Rainmeter.ini so you don't have to manually do it yourself?
There is no "bang" for that, but you could use an OnRefreshAction in the [Rainmeter] section of the skin to write it with !WriteKeyValue.

OnRefreshAction=[!WriteKeyValue #CURRENTCONFIG# AutoSelectScreen "1" "#SETTINGSPATH#Rainmeter.ini"]
User avatar
jsmorley
Developer
Posts: 22631
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Detect current monitor

Post by jsmorley »

Although, in thinking about it, I'm not sure AutoSelectScreen=1 adds much to what you are trying to do. The variables for the position of the skin itself are ALWAYS relative to the "virtual screen", so I'm not sure setting "auto detect" will add much.

I'm also not sure that "manually" adding that setting to Rainmeter.ini, outside of Manage, will actually trigger the correct behavior unless you unload and reload the skin. Writing to Rainmeter.ini manually is a nasty business generally, as much of what Rainmeter does is "in memory" and it only reads what is in Rainmeter.ini when the skin is loaded or refreshed.

Do NOT put a !Refresh in OnRefrshAction... ;-)

My take on this is that you need to get and define some "ranges" for the various monitors. By that I mean define the left edge of monitor 1, monitor 2... monitor N and then do some comparison of the current X of the skin which will be relative to the virtual screen, and then I think you can know which monitor it is on. Then use the variables for the size of the target monitor when you do your !SetOption on the width and height of your image.
Budgies
Posts: 25
Joined: November 19th, 2014, 4:17 pm

Re: Detect current monitor

Post by Budgies »

Alright, I will figure it out, I got a few hours to kill. Thanks for all your help, I am sure I will find some silly question later down the road.
User avatar
jsmorley
Developer
Posts: 22631
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Detect current monitor

Post by jsmorley »

I'd be tempted to do something like:

CurrentMonitor.ini:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Variables]
CurrentMonitorNum=0
CurrentMonitorW=0
CurrentMonitorH=0

[MeasureNumMonitors]
Measure=Plugin
Plugin=SysInfo
SysInfoType=NUM_MONITORS

[MeasureScript]
Measure=Script
ScriptFile=CurrentMonitor.lua

[MeterCurrent]
Meter=String
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
DynamicVariables=1
Text=Current Monitor: #CurrentMonitorNum##CRLF##CurrentMonitorW# X #CurrentMonitorH#
CurrentMonitor.lua:

Code: Select all

function Initialize()

	measureNumMonitors = SKIN:GetMeasure('MeasureNumMonitors')
	
end

function Update()
	
	currentMonitor = 0
	numMonitors = measureNumMonitors:GetValue()
	
	currentSkinLeft = tonumber(SKIN:GetVariable('CURRENTCONFIGX'))

	for i = numMonitors, 1, -1 do
		if currentSkinLeft >= tonumber(SKIN:GetVariable('SCREENAREAX@'..i)) then
			currentMonitor = i
			break
		end
	end
	
	SKIN:Bang('!SetVariable', 'CurrentMonitorW', '#SCREENAREAWIDTH@'..currentMonitor..'#')
	SKIN:Bang('!SetVariable', 'CurrentMonitorH', '#SCREENAREAHEIGHT@'..currentMonitor..'#')
	SKIN:Bang('!SetVariable', 'CurrentMonitorNum', currentMonitor)
	
end
1.jpg
That should properly be able to know the W and H of the monitor the skin is currently on, no matter how many monitors there are...
You do not have the required permissions to view the files attached to this post.