mirror of
https://github.com/RaiMan/SikuliX1.git
synced 2023-06-02 10:04:55 +03:00
revised: new App class implementation
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user