It is currently March 28th, 2024, 11:49 pm

Focus Plugin

Share and get help with Plugins and Addons
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Focus Plugin

Post by death.crafter »

A Rainmeter plugin to bring skins to focus.

⚠️⚠️⚠️⚠️⚠️
Please do not use if not absolutely necessary. Quoting Brian, "Window focus should almost always lie with the user."
⚠️⚠️⚠️⚠️⚠️

Usage:
Measure:

Code: Select all

[MeasureName]
Measure=Plugin
Plugin=Focus
FocusOnRefresh=0
Options:

Code: Select all

FocusOnRefresh : brings focus to the current config on refresh
- 0(default)
- 1
Return value:
0 : if current config is not in focus
1 : if current config is in focus
Commands:

Code: Select all

[!CommandMeasure MeasureName "config"]
Example: [!CommandMeasure Focus "JSMeter\System"]
Example:
Code:

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
OnFocusAction=[!SetOption Image SolidColor 00BBFF][!UpdateMeter Image][!Redraw]
OnUnfocusAction=[!SetOption Image SolidColor 00FF00][!UpdateMeter Image][!Redraw]

[Focus]
Measure=Plugin
Plugin=Focus
FocusOnRefresh=0

[Image]
Meter=Image
H=100
W=200
SolidColor=FF00FF
MouseOverAction=[!CommandMeasure Focus "[#CURRENTCONFIG]"]
Example skin:
FocusPluginExample_1.0.0.1.rmskin
Plugin:
Zip:
Focus_1.0.0.1.zip
Installer:
FocusPluginExample_1.0.0.1.rmskin
Cautions:
Do not use like:

Code: Select all

OnRefreshAction=[!CommandMeasure MeasureName "config1"][!CommandMeasure MeasureName "config2"]
or

Code: Select all

FocusOnRefresh=1
;and
OnRefreshAction=[!CommandMeasure MeasureName "other config"]
Source code(C++):

Code: Select all

#include <Windows.h>
#include <stdio.h>
#include "../../API/RainmeterAPI.h"
#include <string>

struct Measure
{
	HWND windowHandle;

	int focusOnRefresh;
	Measure() : windowHandle(NULL), focusOnRefresh()
	{
	};
};

PLUGIN_EXPORT void Initialize(void** data, void* rm)
{
	Measure* measure = new Measure;
	*data = measure;

	measure->windowHandle = RmGetSkinWindow(rm);

	measure->focusOnRefresh = RmReadInt(rm, L"FocusOnRefresh", 0);

	if (measure->focusOnRefresh == 1) {
		while (measure->windowHandle != GetForegroundWindow()) {
			SetForegroundWindow(measure->windowHandle);
		}
	}
}

PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
{
	Measure* measure = (Measure*)data;
}

PLUGIN_EXPORT double Update(void* data)
{
	Measure* measure = (Measure*)data;

	if (measure->windowHandle != GetForegroundWindow()) {
		return 0.0;
	} else {
		return 1.0;
	}
}

HWND GetSkinWindow(const wchar_t* configName)
{
	HWND trayWnd = FindWindow(L"RainmeterTrayClass", NULL);
	if (trayWnd)
	{
		COPYDATASTRUCT cds;
		cds.dwData = 5101;
		cds.cbData = (DWORD)(wcslen(configName) + 1) * sizeof(wchar_t);
		cds.lpData = (void*)configName;
		return (HWND)SendMessage(trayWnd, WM_COPYDATA, 0, (LPARAM)&cds);
	}

	return NULL;
}

PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args)
{
	Measure* measure = (Measure*)data;
	HWND hwnd = GetSkinWindow(args);
	if (!hwnd) {
		RmLog(LOG_ERROR, L"Focus.dll: Invalid config. Make sure config is loaded!");
	}
	else {
		while (hwnd != GetForegroundWindow()) {
			SetForegroundWindow(hwnd);
		}
	}
}

PLUGIN_EXPORT void Finalize(void* data)
{
	Measure* measure = (Measure*)data;
	delete measure;
}
And this is my first plugin. So please be kind and tell me if I am doing something wrong.
You do not have the required permissions to view the files attached to this post.
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Focus Plugin

Post by Yincognito »

Didn't try it yet, but well done. :thumbup:
Two things though:
- you should explain what effect will have doing any of the things you cautioned against (e.g. crash, other side effect, no effect at all other that the thing being illogical, etc)
- you should try to eliminate the need for these things to be cautioned against, if possible, from your code (e.g. some check against or some ignore approach if any of those situations happen), since most users will expect the plugin to "just work" irrespective of what they're trying to do (and if not, simply display a log error or notice)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: Focus Plugin

Post by death.crafter »

Yincognito wrote: July 25th, 2021, 11:58 am Didn't try it yet, but well done. :thumbup:
Two things though:
- you should explain what effect will have doing any of the things you cautioned against (e.g. crash, other side effect, no effect at all other that the thing being illogical, etc)
- you should try to eliminate the need for these things to be cautioned against, if possible, from your code (e.g. some check against or some ignore approach if any of those situations happen), since most users will expect the plugin to "just work" irrespective of what they're trying to do (and if not, simply display a log error or notice)
It wouldn't crash. It would just focus on the second config right away. You wouldn't notice when the first one was focused(it would be focused). Same for more bangs. If you use delay, you can notice the focus shifting.
It should have been an notice instead. But I don't want it used like this, that's all. One can make a loop out of these and make life hard for the user.
And similar for FocusOnRefresh=1 and OnRefreshAction=[!CommandMeasure MeasureName "other config"]. Other config will be focused right away, leaving FocusOnRefresh=1 useless.
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Focus Plugin

Post by Yincognito »

death.crafter wrote: July 25th, 2021, 4:01 pm It wouldn't crash. It would just focus on the second config right away. You wouldn't notice when the first one was focused(it would be focused). Same for more bangs. If you use delay, you can notice the focus shifting.
It should have been an notice instead. But I don't want it used like this, that's all. One can make a loop out of these and make life hard for the user.
And similar for FocusOnRefresh=1 and OnRefreshAction=[!CommandMeasure MeasureName "other config"]. Other config will be focused right away, leaving FocusOnRefresh=1 useless.
Ah, well, then that's ok. No need for code updates, since it's already handling these the same way everything else in Rainmeter works. I thought it was more serious, hence my previous reply. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
StArL0rd84
Posts: 424
Joined: February 8th, 2015, 10:07 pm
Location: EU, Denmark.

Re: Focus Plugin

Post by StArL0rd84 »

Does not take focus when mousing over my skin.
When I click on the skin the measure outputs a 1 though, so it's doing something.

Code: Select all

[mFocus]
Measure=Plugin
Plugin=Focus
FocusOnRefresh=0

[Bg0]
Meter=Shape
MouseOverAction=[!CommandMeasure mFocus "Panels\Torrents"]
or
MouseOverAction=[!CommandMeasure mFocus "[#CURRENTCONFIG]"]
or
MouseOverAction=[!CommandMeasure mFocus "#CURRENTCONFIG#"]
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: Focus Plugin

Post by death.crafter »

StArL0rd84 wrote: June 7th, 2022, 4:16 pm Does not take focus when mousing over my skin.
When I click on the skin the measure outputs a 1 though, so it's doing something.

Code: Select all

[mFocus]
Measure=Plugin
Plugin=Focus
FocusOnRefresh=0

[Bg0]
Meter=Shape
MouseOverAction=[!CommandMeasure mFocus "Panels\Torrents"]
or
MouseOverAction=[!CommandMeasure mFocus "[#CURRENTCONFIG]"]
or
MouseOverAction=[!CommandMeasure mFocus "#CURRENTCONFIG#"]
How do you know it's not gaining focus? Also the example you have given isn't a valid skin. Tho I assume you have just used an example and have decided to omit the rest parts.
from the Realm of Death
User avatar
StArL0rd84
Posts: 424
Joined: February 8th, 2015, 10:07 pm
Location: EU, Denmark.

Re: Focus Plugin

Post by StArL0rd84 »

death.crafter wrote: June 7th, 2022, 5:36 pm How do you know it's not gaining focus? Also the example you have given isn't a valid skin. Tho I assume you have just used an example and have decided to omit the rest parts.
Yes, for simplicity's sake I chose to omit the rest of the skin.

The skin does not move to the foreground when I mouse over it, and the measure does not return a 1, indicating it has focus.
Tried to add it in other skins too to see if something interfered, but still can't get it to give a skin focus over other open windows.
Not even your example skin.

Maybe I have missed the point of your plugin.
Does it only show if a skin HAS focus, and not TAKE focus?

Was hoping to use this plugin to replace the command line program called RainFocus by ~Faradey~.
https://forum.rainmeter.net/viewtopic.php?t=22839#p120520

Rainmeter version 4.5.13.3632
Windows 11 21H2
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Focus Plugin

Post by Yincognito »

StArL0rd84 wrote: June 8th, 2022, 4:18 pm Yes, for simplicity's sake I chose to omit the rest of the skin.

The skin does not move to the foreground when I mouse over it, and the measure does not return a 1, indicating it has focus.
Tried to add it in other skins too to see if something interfered, but still can't get it to give a skin focus over other open windows.
Not even your example skin.

Maybe I have missed the point of your plugin.
Does it only show if a skin HAS focus, and not TAKE focus?

Was hoping to use this plugin to replace the command line program called RainFocus by ~Faradey~.
https://forum.rainmeter.net/viewtopic.php?t=22839#p120520

Rainmeter version 4.5.13.3632
Windows 11 21H2
Well, it does work ... usually. Except when it doesn't or when it "hangs" Rainmeter (it's the 6th time it does the latter for me, since testing the example skin and writing this post, but don't be scared, more details on what "hang" means below). :D

In my case, the example skin works as expected after loading, when it's colored magenta and has Focus=0. If I hover over, it turns cyan and Focus=1 so all good till now. If I click on another window or object on the screen (like the Rainmeter Log window or another skin), it correctly turns to green and Focus becomes 0. I can go like this, i.e. hover on the skin then click another window and it will work forever, as desired.

However, if I click on the bare desktop instead of on another window in order to test the focus thing, not only it doesn't turn green apart from the first time clicking on the desktop, but it also "sort of hangs" Rainmeter, i.e. the "always working" cursor of Windows is triggered and the animation in my skin suite pauses (aka hangs as well). I used quotes when mentioning the hanging because apparently you can "unhang" everything just by right clicking the example skin and choosing to Refresh from the context menu. Initially, I had to forcefully kill Rainmeter when the hang happened, but after noticing the above, I just refresh the skin and the hang is magically gone (until next time I try the above), LMAO.

Anyway, back to your point, it does SET the focus on any skin, including itself, I tested it. Obviously, when something gets focused, the focus is TAKEN AWAY from other things, if that's what you meant by TAKE. However, like I mentioned, it has some "quirks" like the desktop thing above or the fact that Focus stays 1 after refreshing the skin, so getting the color change from magenta to cyan on hover won't produce the expected result anymore (as it did before the refresh), unless of course you click something other window or skin to reset Focus to 0 and get back on track with the normal usage scenario.

Bottom line, it is functional and does what you want, bar the 2 cases I referred to above. My impression is that those are probably fixable with minor adjustments to the plugin code. I love the unhang "feature" though, it's something I never saw anywhere else, really. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: Focus Plugin

Post by death.crafter »

Seems I got a bug to squash. I'll try your skin out first tho. And I'll get my hands dirty with this when I get a little more free time.
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Focus Plugin

Post by Yincognito »

death.crafter wrote: June 8th, 2022, 6:01 pm Seems I got a bug to squash. I'll try your skin out first tho. And I'll get my hands dirty with this when I get a little more free time.
No worries, dc - take your time. Things should always be done when comfortable and time is available. I just revealed my experience with the sample skin when trying to figure out the things StArLOrd84 talked about. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth