diff --git a/doc.md b/doc.md index 2e42b28..9cd4d0b 100644 --- a/doc.md +++ b/doc.md @@ -49,6 +49,7 @@ #####[ShowAlert(support linux as soon as possible)](#ShowAlert) #####[CloseWindow](#CloseWindow) #####[IsValid](#IsValid) +#####[SetActive](#SetActive) #####[GetActive](#GetActive) #####[GetHandle](#GetHandle) #####[GetTitle](#GetTitle) @@ -438,6 +439,17 @@ func main() { Returns true if a window has been selected +###

.SetActive()

+ + Set the Active Window + +####Arguments: + hwnd + +####Return: + void + + ###

.GetActive()

Get the Active Window diff --git a/robotgo.go b/robotgo.go index 5b88335..7da4c0d 100644 --- a/robotgo.go +++ b/robotgo.go @@ -561,6 +561,10 @@ func IsValid() bool { return gbool } +func SetActive(win C.MData) { + C.aSetActive(win) +} + func GetActive() C.MData { mdata := C.aGetActive() // Println("active----", mdata) diff --git a/window/goWindow.h b/window/goWindow.h index 33fcaa0..a37f79d 100644 --- a/window/goWindow.h +++ b/window/goWindow.h @@ -37,6 +37,10 @@ uintptr aGetHandle(){ return hwnd; } +void aSetActive(const MData win){ + SetActive(win); +} + MData aGetActive(){ MData mdata=GetActive(); return mdata; diff --git a/window/window.h b/window/window.h index a20b39b..0a5d945 100644 --- a/window/window.h +++ b/window/window.h @@ -219,13 +219,50 @@ void aWindow(); return NULL; } - //////////////////////////////////////////////////////////////////////////////// + ////// #define STATE_TOPMOST 0 #define STATE_MINIMIZE 1 #define STATE_MAXIMIZE 2 + ////// + static void SetDesktopForWindow (MData win){ + Display *rDisplay = XOpenDisplay(NULL); + // Validate every atom that we want to use + if (WM_DESKTOP != None && WM_CURDESK != None){ + // Get desktop property + long* desktop = (long*) + GetWindowProperty (win, WM_DESKTOP,NULL); + + // Check result value + if (desktop != NULL){ + // Retrieve the screen number + XWindowAttributes attr = { 0 }; + XGetWindowAttributes (rDisplay, win.XWin, &attr); + int s = XScreenNumberOfScreen (attr.screen); + Window root = XRootWindow(rDisplay, s); + + // Prepare an event + XClientMessageEvent e = { 0 }; + e.window = root; e.format = 32; + e.message_type = WM_CURDESK; + e.display = rDisplay; + e.type = ClientMessage; + e.data.l[0] = *desktop; + e.data.l[1] = CurrentTime; + + // Send the message + XSendEvent(rDisplay, + root, False, SubstructureNotifyMask | + SubstructureRedirectMask, (XEvent*) &e); + + XFree(desktop); + } + } + } + + #elif defined(IS_WINDOWS) // #endif @@ -461,6 +498,144 @@ bool IsTopMost (void){ #endif } +bool IsMinimized(void){ + // Check the window validity + if (!IsValid()) return false; +#if defined(IS_MACOSX) + + CFBooleanRef data = NULL; + + // Determine whether the window is minimized + if (AXUIElementCopyAttributeValue (mData.AxID, + kAXMinimizedAttribute, (CFTypeRef*) &data) + == kAXErrorSuccess && data != NULL) + { + // Convert resulting data into a bool + bool result = CFBooleanGetValue(data); + CFRelease (data); return result; + } + + return false; + +#elif defined(USE_X11) + + // Ignore X errors + // XDismissErrors(); + // return GetState (mData.XWin, STATE_MINIMIZE); + +#elif defined(IS_WINDOWS) + + return (GetWindowLongPtr (mData.HWnd, + GWL_STYLE) & WS_MINIMIZE) != 0; + +#endif +} + +////// + +bool IsMaximized(void){ + // Check the window validity + if (!IsValid()) return false; +#if defined(IS_MACOSX) + + return false; // WARNING: Unavailable + +#elif defined(USE_X11) + + // Ignore X errors + // XDismissErrors(); + // return GetState (mData.XWin, STATE_MAXIMIZE); + +#elif defined(IS_WINDOWS) + + return (GetWindowLongPtr (mData.HWnd, + GWL_STYLE) & WS_MAXIMIZE) != 0; + +#endif +} + +void SetActive(const MData win){ + // Check if the window is valid + if (!IsValid()) return; +#if defined(IS_MACOSX) + + // Attempt to raise the specified window object + if (AXUIElementPerformAction (win.AxID, + kAXRaiseAction) == kAXErrorSuccess) + { + pid_t pid = 0; + // Attempt to retrieve the PID of the window + if (AXUIElementGetPid (win.AxID, &pid) + != kAXErrorSuccess || !pid) return; + + // Ignore deprecated warnings + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + + // NOTE: Until Apple actually removes + // these functions, there's no real + // reason to switch to the NS* flavor + + ProcessSerialNumber psn; + // Attempt to retrieve the process psn + if (GetProcessForPID (pid, &psn) == 0){ + // Gracefully activate process + SetFrontProcessWithOptions (&psn, + kSetFrontProcessFrontWindowOnly); + } + + #pragma clang diagnostic pop + } + +#elif defined(USE_X11) + + // Ignore X errors + XDismissErrors(); + + // Go to the specified window's desktop + SetDesktopForWindow(win); + Display *rDisplay = XOpenDisplay(NULL); + // Check the atom value + if (WM_ACTIVE != None){ + // Retrieve the screen number + XWindowAttributes attr = { 0 }; + XGetWindowAttributes (rDisplay, + win.XWin, &attr); + int s = XScreenNumberOfScreen(attr.screen); + + // Prepare an event + XClientMessageEvent e = { 0 }; + e.window = win.XWin; + e.format = 32; + e.message_type = WM_ACTIVE; + e.display = rDisplay; + e.type = ClientMessage; + e.data.l[0] = 2; + e.data.l[1] = CurrentTime; + + // Send the message + XSendEvent(rDisplay, XRootWindow (rDisplay, s), False, + SubstructureNotifyMask | SubstructureRedirectMask, + (XEvent*) &e); + }else{ + // Attempt to raise the specified window + XRaiseWindow(rDisplay, win.XWin); + + // Set the specified window's input focus + XSetInputFocus(rDisplay, win.XWin, + RevertToParent, CurrentTime); + } + +#elif defined(IS_WINDOWS) + + if (IsMinimized()) + ShowWindow(win.HWnd, SW_RESTORE); + + SetForegroundWindow (win.HWnd); + +#endif +} + MData GetActive (void){ #if defined(IS_MACOSX) diff --git a/zh_doc.md b/zh_doc.md index c64d62d..0f6c555 100644 --- a/zh_doc.md +++ b/zh_doc.md @@ -49,6 +49,7 @@ #####[ShowAlert(support linux as soon as possible)](#ShowAlert) #####[CloseWindow](#CloseWindow) #####[IsValid](#IsValid) +#####[SetActive](#SetActive) #####[GetActive](#GetActive) #####[GetHandle](#GetHandle) #####[GetTitle](#GetTitle) @@ -451,6 +452,17 @@ func main() { Returns true if a window has been selected +###

.SetActive()

+ + Set the Active Window + +####参数: + hwnd + +####返回值: + void + + ###

.GetActive()

Get the Active Window