How to monitor focus changes?
One way would be to use the windows UI Automation API. It exposes a global focus changed event. Here is a quick sample I came up with (in C#). Note, you need to add references to UIAutomationClient and UIAutomationTypes.
using System.Windows.Automation;
using System.Diagnostics;
namespace FocusChanged
{
class Program
{
static void Main(string[] args)
{
Automation.AddAutomationFocusChangedEventHandler(OnFocusChangedHandler);
Console.WriteLine("Monitoring... Hit enter to end.");
Console.ReadLine();
}
private static void OnFocusChangedHandler(object src, AutomationFocusChangedEventArgs args)
{
Console.WriteLine("Focus changed!");
AutomationElement element = src as AutomationElement;
if (element != null)
{
string name = element.Current.Name;
string id = element.Current.AutomationId;
int processId = element.Current.ProcessId;
using (Process process = Process.GetProcessById(processId))
{
Console.WriteLine(" Name: {0}, Id: {1}, Process: {2}", name, id, process.ProcessName);
}
}
}
}
}
Detect window focus changes with XCB
The focus events are only sent when the window that you selected these events on receives or loses the focus, see https://www.x.org/releases/X11R7.5/doc/x11proto/proto.html:
FocusIn
FocusOut[...]
These events are generated when the input focus changes and are reported to clients selecting FocusChange on the window.
To use this, you would have to select this event mask on all windows and also watch for the creation of new windows.
I would suggest a different approach: Watch for PropertyChangeNotify events on the root window to see when the _NET_ACTIVE_WINDOW
property changes. This property should be kept up to date by the WM, according to EWMH.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xcb/xcb.h>
static xcb_atom_t intern_atom(xcb_connection_t *conn, const char *atom)
{
xcb_atom_t result = XCB_NONE;
xcb_intern_atom_reply_t *r = xcb_intern_atom_reply(conn,
xcb_intern_atom(conn, 0, strlen(atom), atom), NULL);
if (r)
result = r->atom;
free(r);
return result;
}
int main (int argc, char **argv)
{
xcb_connection_t* conn = xcb_connect(NULL, NULL);
if (xcb_connection_has_error(conn)) {
printf("Cannot open daemon connection.");
return 0;
}
xcb_atom_t active_window = intern_atom(conn, "_NET_ACTIVE_WINDOW");
xcb_screen_t* screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
uint32_t values[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
xcb_change_window_attributes(
conn,
screen->root,
XCB_CW_EVENT_MASK,
values);
xcb_flush(conn);
xcb_generic_event_t *ev;
while ((ev = xcb_wait_for_event(conn))) {
printf("IN LOOP\n");
switch (ev->response_type & 0x7F) {
case XCB_PROPERTY_NOTIFY: {
xcb_property_notify_event_t *e = (void *) ev;
if (e->atom == active_window)
puts("active window changed");
break;
}
default:
printf("IN DEFAULT\n");
break;
}
free(ev);
}
return 0;
}
How to monitor active window changes using xcb?
If you set PropertyChange
mask on root window you'll start getting PropertyNotify
events to your code. See example in my answer here: Linux get notification on focused gui window change
Is there a cross-browser solution for monitoring when the document.activeElement changes?
While @James's answer above is correct. I've added more details to make it a completely working solution along with the use of focus
event too.
<html>
<body>
<input type="text" id="Text1" name ="Text1" value=""/>
<input type="text" id="Text2" name ="Text2" value=""/>
<SELECT><OPTION>ASDASD</OPTION><OPTION>A232</OPTION></SELECT>
<INPUT TYPE="CHECKBOX" id="Check1"/>
<INPUT type="TEXT" id="text3"/>
<input type="radio"/>
<div id="console"> </div>
<textarea id="textarea1"> </textarea>
<script>
var lastActiveElement = document.activeElement;
function detectBlur() {
// Do logic related to blur using document.activeElement;
// You can do change detection too using lastActiveElement as a history
}
function isSameActiveElement() {
var currentActiveElement = document.activeElement;
if(lastActiveElement != currentActiveElement) {
lastActiveElement = currentActiveElement;
return false;
}
return true;
}
function detectFocus() {
// Add logic to detect focus and to see if it has changed or not from the lastActiveElement.
}
function attachEvents() {
window.addEventListener ? window.addEventListener('focus', detectFocus, true) : window.attachEvent('onfocusout', detectFocus);
window.addEventListener ? window.addEventListener('blur', detectBlur, true) : window.attachEvent('onblur', detectBlur);
}
attachEvents();
</script>
</body>
</html>
Related Topics
C# Call C++ Dll Passing Pointer-To-Pointer Argument
How to Remove Specific Style Tag in HTML Using C#
C# Equivalent to PHP Associative Array
Pass Byte Array from Unity C# to C++ Plugin
C# Httpwebrequest and JavaScript
Deserialize JSON Object Sent from Android App to Wcf Webservice
Is C# Really Slower Than Say C++
How to Determine a Timezone by The Utc Offset
Webapi Cannot Parse Multipart/Form-Data Post
Xamarin: How to Get HTML from Page in Webview
What Is the Fastest Way to Compute Sin and Cos Together
How to Configure ASP.NET Kestrel for Low Latency
Asp.Net Vnext Kestrel + Windows Authentication
Is There a Linux Equivalent of Dllimport in .Net Core
Sort Collection by First Item of Sub List in Entity Framework