Skip to content

Commit 1e2075a

Browse files
authored
Merge pull request #1719 from dbwiddis/add-coregraphics-bindings
Add CoreGraphics bindings and macOS getAllWindows() implementation
2 parents c59d194 + 8678fe1 commit 1e2075a

4 files changed

Lines changed: 655 additions & 0 deletions

File tree

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Features
1111
* [#1697](https://github.com/java-native-access/jna/pull/1697): Add WlanApi module - [@eranl](https://github.com/eranl).
1212
* [#1718](https://github.com/java-native-access/jna/pull/1718): Add `Cups` to `c.s.j.p.unix` providing CUPS printing system bindings for destinations, jobs, options, and server configuration - [@dbwiddis](https://github.com/dbwiddis).
1313
* [#1720](https://github.com/java-native-access/jna/pull/1720): Add `groupCount` and `groupMasks` fields to `CACHE_RELATIONSHIP` in `c.s.j.p.win32.WinNT`, matching the updated Windows struct layout - [@dbwiddis](https://github.com/dbwiddis).
14+
* [#1719](https://github.com/java-native-access/jna/pull/1719): Add `CoreGraphics` to `c.s.j.p.mac` with Quartz Window Services and Display Services bindings; implement `getAllWindows()` in `MacWindowUtils` - [@dbwiddis](https://github.com/dbwiddis).
1415

1516
Bug Fixes
1617
---------

contrib/platform/src/com/sun/jna/platform/WindowUtils.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@
9797
import com.sun.jna.platform.win32.WinDef.HICON;
9898
import com.sun.jna.platform.win32.WinDef.HRGN;
9999
import com.sun.jna.platform.win32.WinDef.HWND;
100+
import com.sun.jna.platform.mac.CoreFoundation;
101+
import com.sun.jna.platform.mac.CoreFoundation.CFArrayRef;
102+
import com.sun.jna.platform.mac.CoreFoundation.CFDictionaryRef;
103+
import com.sun.jna.platform.mac.CoreFoundation.CFStringRef;
104+
import com.sun.jna.platform.mac.CoreGraphics;
100105
import com.sun.jna.platform.win32.WinDef.LPARAM;
101106
import com.sun.jna.platform.win32.WinDef.LRESULT;
102107
import com.sun.jna.platform.win32.WinDef.POINT;
@@ -1560,6 +1565,91 @@ private void setBackgroundTransparent(Window w, boolean transparent, String cont
15601565
}
15611566
fixWindowDragging(w, context);
15621567
}
1568+
1569+
@Override
1570+
protected List<DesktopWindow> getAllWindows(final boolean onlyVisibleWindows) {
1571+
final List<DesktopWindow> result = new LinkedList<>();
1572+
int options = onlyVisibleWindows
1573+
? CoreGraphics.kCGWindowListOptionOnScreenOnly | CoreGraphics.kCGWindowListExcludeDesktopElements
1574+
: CoreGraphics.kCGWindowListOptionAll;
1575+
CFArrayRef windowList = CoreGraphics.INSTANCE.CGWindowListCopyWindowInfo(
1576+
options, CoreGraphics.kCGNullWindowID);
1577+
if (windowList == null) {
1578+
return result;
1579+
}
1580+
try {
1581+
CFStringRef kName = CFStringRef.createCFString(CoreGraphics.kCGWindowName);
1582+
CFStringRef kOwnerName = CFStringRef.createCFString(CoreGraphics.kCGWindowOwnerName);
1583+
CFStringRef kBounds = CFStringRef.createCFString(CoreGraphics.kCGWindowBounds);
1584+
CFStringRef kNumber = CFStringRef.createCFString(CoreGraphics.kCGWindowNumber);
1585+
CFStringRef kLayer = CFStringRef.createCFString(CoreGraphics.kCGWindowLayer);
1586+
try {
1587+
int count = windowList.getCount();
1588+
for (int i = 0; i < count; i++) {
1589+
Pointer p = windowList.getValueAtIndex(i);
1590+
if (p == null) {
1591+
continue;
1592+
}
1593+
CFDictionaryRef dict = new CFDictionaryRef(p);
1594+
1595+
// Skip non-normal windows (layer != 0)
1596+
Pointer layerPtr = CoreFoundation.INSTANCE.CFDictionaryGetValue(dict, kLayer);
1597+
if (layerPtr != null) {
1598+
CoreFoundation.CFNumberRef layerNum = new CoreFoundation.CFNumberRef(layerPtr);
1599+
if (layerNum.intValue() != 0) {
1600+
continue;
1601+
}
1602+
}
1603+
1604+
// Window title (may be null)
1605+
String title = "";
1606+
Pointer namePtr = CoreFoundation.INSTANCE.CFDictionaryGetValue(dict, kName);
1607+
if (namePtr != null) {
1608+
title = new CFStringRef(namePtr).stringValue();
1609+
}
1610+
1611+
// Owner name as filePath equivalent
1612+
String ownerName = "";
1613+
Pointer ownerPtr = CoreFoundation.INSTANCE.CFDictionaryGetValue(dict, kOwnerName);
1614+
if (ownerPtr != null) {
1615+
ownerName = new CFStringRef(ownerPtr).stringValue();
1616+
}
1617+
1618+
// Window ID as HWND
1619+
HWND hwnd = null;
1620+
Pointer numPtr = CoreFoundation.INSTANCE.CFDictionaryGetValue(dict, kNumber);
1621+
if (numPtr != null) {
1622+
int windowId = new CoreFoundation.CFNumberRef(numPtr).intValue();
1623+
hwnd = new HWND(Pointer.createConstant(windowId));
1624+
}
1625+
1626+
// Bounds
1627+
Rectangle locAndSize = new Rectangle();
1628+
Pointer boundsPtr = CoreFoundation.INSTANCE.CFDictionaryGetValue(dict, kBounds);
1629+
if (boundsPtr != null) {
1630+
CoreGraphics.CGRect rect = new CoreGraphics.CGRect();
1631+
if (0 != CoreGraphics.INSTANCE.CGRectMakeWithDictionaryRepresentation(
1632+
new CFDictionaryRef(boundsPtr), rect)) {
1633+
locAndSize = new Rectangle(
1634+
(int) rect.origin.x, (int) rect.origin.y,
1635+
(int) rect.size.width, (int) rect.size.height);
1636+
}
1637+
}
1638+
1639+
result.add(new DesktopWindow(hwnd, title, ownerName, locAndSize));
1640+
}
1641+
} finally {
1642+
kName.release();
1643+
kOwnerName.release();
1644+
kBounds.release();
1645+
kNumber.release();
1646+
kLayer.release();
1647+
}
1648+
} finally {
1649+
windowList.release();
1650+
}
1651+
return result;
1652+
}
15631653
}
15641654
private static class X11WindowUtils extends NativeWindowUtils {
15651655
private static Pixmap createBitmap(final Display dpy,

0 commit comments

Comments
 (0)