revised: new App class implementation

This commit is contained in:
RaiMan
2021-04-29 16:18:51 +02:00
parent 7322e2484e
commit b49d74a210
5 changed files with 193 additions and 157 deletions

View File

@@ -4,15 +4,14 @@
package org.sikuli.natives;
import java.io.File;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public abstract class GenericOsUtil implements OSUtil {
protected static class GenericOsProcess implements OsProcess {
@@ -30,8 +29,7 @@ public abstract class GenericOsUtil implements OSUtil {
@Override
public String getName() {
Optional<String> command = process.info().command();
return command.orElse("");
return process.info().command().orElse("");
}
@Override
@@ -82,11 +80,20 @@ public abstract class GenericOsUtil implements OSUtil {
throw new UnsupportedOperationException("getWindows not implemented");
}
@Override
public List<OsWindow> getWindows() {
throw new UnsupportedOperationException("getWindows not implemented");
}
@Override
public List<OsProcess> getProcesses() {
return allProcesses().collect(Collectors.toList());
}
public OsProcess getProcess() {
return thisProcess();
}
@Override
public OsProcess open(String[] cmd, String workDir) {
try {
@@ -115,4 +122,7 @@ public abstract class GenericOsUtil implements OSUtil {
return ProcessHandle.allProcesses().map((h) -> new GenericOsProcess(h));
}
protected static OsProcess thisProcess() {
return new GenericOsProcess(ProcessHandle.current());
}
}

View File

@@ -21,167 +21,179 @@ import org.sikuli.script.support.Commons;
public class MacUtil extends GenericOsUtil {
@Override
public boolean isUserProcess(OsProcess process) {
if (process == null) {
return false;
} else {
if (process.getPid() > 0) {
String name = process.getName();
Commons.debug("");
return true;
}
}
return false;
}
@Override
public boolean isUserProcess(OsProcess process) {
if (process == null) {
return false;
} else {
if (process.getPid() > 0) {
String name = process.getName();
if (name.isEmpty()) {
return false;
}
if (!name.startsWith("/Applications/")
&& !name.startsWith("/System/Applications/")
&& !name.startsWith("/Library/Java/JavaVirtualMachines/")) {
return false;
}
return true;
}
}
return false;
}
private static final class MacWindow implements OsWindow {
private long number;
private String title;
private long pid;
private Rectangle bounds;
private static final class MacWindow implements OsWindow {
private long number;
private String title;
private long pid;
private Rectangle bounds;
public MacWindow(long number, String title, long pid, Rectangle bounds) {
this.number = number;
this.title = title;
this.pid = pid;
this.bounds = bounds;
}
public MacWindow(long number, String title, long pid, Rectangle bounds) {
this.number = number;
this.title = title;
this.pid = pid;
this.bounds = bounds;
}
@Override
public OsProcess getProcess() {
Optional<ProcessHandle> handle = ProcessHandle.of(pid);
if (handle.isPresent()) {
return new GenericOsProcess(handle.get());
}
return null;
}
@Override
public OsProcess getProcess() {
Optional<ProcessHandle> handle = ProcessHandle.of(pid);
if (handle.isPresent()) {
return new GenericOsProcess(handle.get());
}
return null;
}
@Override
public String getTitle() {
return title;
}
@Override
public String getTitle() {
return title;
}
@Override
public Rectangle getBounds() {
return bounds;
}
@Override
public Rectangle getBounds() {
return bounds;
}
@Override
public boolean focus() {
NSRunningApplication app = NSRunningApplication.CLASS.runningApplicationWithProcessIdentifier((int) pid);
@Override
public boolean focus() {
NSRunningApplication app = NSRunningApplication.CLASS.runningApplicationWithProcessIdentifier((int) pid);
if (app != null) {
return app.activateWithOptions(NSRunningApplication.NSApplicationActivationOptions.NSApplicationActivateAllWindows | NSRunningApplication.NSApplicationActivationOptions.NSApplicationActivateIgnoringOtherApps);
}
if (app != null) {
return app.activateWithOptions(NSRunningApplication.NSApplicationActivationOptions.NSApplicationActivateAllWindows | NSRunningApplication.NSApplicationActivationOptions.NSApplicationActivateIgnoringOtherApps);
}
return false;
}
return false;
}
@Override
public boolean minimize() {
throw new UnsupportedOperationException("minimize not implemented");
}
@Override
public boolean minimize() {
throw new UnsupportedOperationException("minimize not implemented");
}
@Override
public boolean maximize() {
throw new UnsupportedOperationException("maximize not implemented");
}
@Override
public boolean maximize() {
throw new UnsupportedOperationException("maximize not implemented");
}
@Override
public boolean restore() {
throw new UnsupportedOperationException("restore not implemented");
}
@Override
public boolean restore() {
throw new UnsupportedOperationException("restore not implemented");
}
@Override
public boolean equals(Object other) {
return other != null && other instanceof MacWindow && this.number == (((MacWindow) other).number);
}
}
@Override
public boolean equals(Object other) {
return other != null && other instanceof MacWindow && this.number == (((MacWindow) other).number);
}
}
@Override
public List<OsWindow> findWindows(String title) {
return allWindows().stream().filter((w) -> w.getTitle().contains(title)).collect(Collectors.toList());
}
@Override
public List<OsWindow> findWindows(String title) {
return allWindows().stream().filter((w) -> w.getTitle().contains(title)).collect(Collectors.toList());
}
@Override
public OsWindow getFocusedWindow() {
return allWindows().stream().filter((w) -> {
OsProcess process = w.getProcess();
@Override
public OsWindow getFocusedWindow() {
return allWindows().stream().filter((w) -> {
OsProcess process = w.getProcess();
if (process != null) {
NSRunningApplication app = NSRunningApplication.CLASS
.runningApplicationWithProcessIdentifier((int) w.getProcess().getPid());
if (process != null) {
NSRunningApplication app = NSRunningApplication.CLASS
.runningApplicationWithProcessIdentifier((int) w.getProcess().getPid());
if (app != null) {
if (app.isActive()) {
return true;
}
}
}
return false;
}).findFirst().orElse(null);
}
if (app != null) {
if (app.isActive()) {
return true;
}
}
}
return false;
}).findFirst().orElse(null);
}
@Override
public List<OsWindow> getWindows(OsProcess process) {
if (process != null) {
return allWindows().stream().filter((w) -> process.equals(w.getProcess())).collect(Collectors.toList());
}
return new ArrayList<>(0);
}
@Override
public List<OsWindow> getWindows(OsProcess process) {
if (process != null) {
return allWindows().stream().filter((w) -> process.equals(w.getProcess())).collect(Collectors.toList());
}
return new ArrayList<>(0);
}
private static List<OsWindow> allWindows() {
ArrayList<OsWindow> windows = new ArrayList<>();
@Override
public List<OsWindow> getWindows() {
return allWindows();
}
CFArrayRef windowInfo = CoreGraphics.INSTANCE.CGWindowListCopyWindowInfo(
CoreGraphics.kCGWindowListExcludeDesktopElements | CoreGraphics.kCGWindowListOptionOnScreenOnly, 0);
private static List<OsWindow> allWindows() {
ArrayList<OsWindow> windows = new ArrayList<>();
try {
int numWindows = windowInfo.getCount();
for (int i = 0; i < numWindows; i++) {
Pointer pointer = windowInfo.getValueAtIndex(i);
CFDictionaryRef windowRef = new CFDictionaryRef(pointer);
CFArrayRef windowInfo = CoreGraphics.INSTANCE.CGWindowListCopyWindowInfo(
CoreGraphics.kCGWindowListExcludeDesktopElements | CoreGraphics.kCGWindowListOptionOnScreenOnly, 0);
Pointer numberPointer = windowRef.getValue(CoreGraphics.kCGWindowNumber);
long windowNumber = new CFNumberRef(numberPointer).longValue();
try {
int numWindows = windowInfo.getCount();
for (int i = 0; i < numWindows; i++) {
Pointer pointer = windowInfo.getValueAtIndex(i);
CFDictionaryRef windowRef = new CFDictionaryRef(pointer);
Pointer pidPointer = windowRef.getValue(CoreGraphics.kCGWindowOwnerPID);
long windowPid = new CFNumberRef(pidPointer).longValue();
Pointer numberPointer = windowRef.getValue(CoreGraphics.kCGWindowNumber);
long windowNumber = new CFNumberRef(numberPointer).longValue();
String windowName = "";
Pointer namePointer = windowRef.getValue(CoreGraphics.kCGWindowName);
Pointer pidPointer = windowRef.getValue(CoreGraphics.kCGWindowOwnerPID);
long windowPid = new CFNumberRef(pidPointer).longValue();
if (namePointer != null) {
CFStringRef nameRef = new CFStringRef(namePointer);
String windowName = "";
Pointer namePointer = windowRef.getValue(CoreGraphics.kCGWindowName);
if (CoreFoundation.INSTANCE.CFStringGetLength(nameRef).intValue() > 0) {
windowName = new CFStringRef(namePointer).stringValue();
}
}
if (namePointer != null) {
CFStringRef nameRef = new CFStringRef(namePointer);
Pointer boundsPointer = windowRef.getValue(CoreGraphics.kCGWindowBounds);
CoreGraphics.CGRectRef rect = new CoreGraphics.CGRectRef();
if (CoreFoundation.INSTANCE.CFStringGetLength(nameRef).intValue() > 0) {
windowName = new CFStringRef(namePointer).stringValue();
}
}
boolean result = CoreGraphics.INSTANCE.CGRectMakeWithDictionaryRepresentation(boundsPointer, rect);
Pointer boundsPointer = windowRef.getValue(CoreGraphics.kCGWindowBounds);
CoreGraphics.CGRectRef rect = new CoreGraphics.CGRectRef();
Rectangle javaRect = null;
boolean result = CoreGraphics.INSTANCE.CGRectMakeWithDictionaryRepresentation(boundsPointer, rect);
if (result) {
int x = (int) rect.origin.x;
int y = (int) rect.origin.y;
int width = (int) rect.size.width;
int height = (int) rect.size.height;
Rectangle javaRect = null;
javaRect = new Rectangle(x, y, width, height);
}
if (result) {
int x = (int) rect.origin.x;
int y = (int) rect.origin.y;
int width = (int) rect.size.width;
int height = (int) rect.size.height;
windows.add(new MacWindow(windowNumber, windowName, windowPid, javaRect));
}
} finally {
windowInfo.release();
}
javaRect = new Rectangle(x, y, width, height);
}
return windows;
}
windows.add(new MacWindow(windowNumber, windowName, windowPid, javaRect));
}
} finally {
windowInfo.release();
}
return windows;
}
}

View File

@@ -49,8 +49,12 @@ public interface OSUtil {
List<OsWindow> getWindows(OsProcess process);
List<OsWindow> getWindows();
List<OsProcess> getProcesses();
OsProcess getProcess();
OsProcess open(String[] cmd, String workDir);
OsWindow getFocusedWindow();

View File

@@ -162,7 +162,9 @@ public class App {
public String toString() {
if (isUserProcess()) {
final String windowTitle = getTitle().isEmpty() ? "" : " (" + getTitle() + ")";
return String.format("[%d:%s%s] %s %s", getPID(), getName(), windowTitle, getExecutable(), getArguments());
String executable = getExecutable().isEmpty() ? "" : getExecutable();
String arguments = getArguments().isEmpty() ? "" : getArguments();
return String.format("[%d:%s%s] %s %s", getPID(), getName(), windowTitle, executable, arguments);
}
return String.format("App:SystemProcess(pid:%d)", getPID());
}
@@ -198,7 +200,7 @@ public class App {
if (cmd != null) {
return cmd.getExecutable();
} else {
return "Executable:NotSet";
return "";
}
}
@@ -227,7 +229,7 @@ public class App {
if (cmd != null) {
return String.join(" ", cmd.getArguments());
} else {
return "Arguments:NotSet";
return "";
}
}
@@ -256,6 +258,9 @@ public class App {
//</editor-fold>
// <editor-fold desc="10 app list">
public static App getApp() {
return new App(osUtil.getProcess());
}
public static List<App> getApps() {
return osUtil.getProcesses().stream().map((p) -> new App(p)).collect(Collectors.toList());
@@ -269,11 +274,15 @@ public class App {
new App();
List<App> appList = getApps();
logOn();
log("***** all running apps");
log("***** running apps with windows");
int n = 0;
for (App app : appList) {
log("%s", app);
if (app.isUserProcess() && app.hasWindow()) {
log("%s", app);
n++;
}
}
log("***** end of list (%d)", appList.size());
log("***** end of list (%d)", n);
logOff();
}
@@ -282,10 +291,14 @@ public class App {
List<App> appList = getApps(name);
logOn();
log("***** running apps matching: %s", name);
int n = 0;
for (App app : appList) {
log("%s", app);
if (app.isUserProcess() && app.hasWindow()) {
log("%s", app);
n++;
}
}
log("***** end of list (%d)", appList.size());
log("***** end of list (%d)", n);
logOff();
}
// </editor-fold>
@@ -583,6 +596,10 @@ public class App {
return windowRegion;
}
List<OsWindow> windows() {
return osUtil.getWindows();
}
public String getTitle(int windowNumber) {
return getWindowTitle(windowNumber);
}

View File

@@ -25,16 +25,9 @@ public class SikulixEvaluate {
static void testApp() {
Commons.startDebug();
if (false) {
App app = new App();
Commons.debug("%s", app);
} else {
List<App> apps = App.getApps();
for (App app : apps) {
boolean userProcess = app.isUserProcess();
}
Commons.debug(" ");
}
App app = new App();
App.listApps("java");
Commons.debug("%s", app);
}
//region test