observe hidden window while working myself on the screen

Asked by Anton

I\m using Opera web browser. It is not using windows like IE, it uses tabs.

When I use focus on app.window() it seems to treat only the window and not the tab. So I need to have the right tab in focus, for it to observe anything.

it recognizes/finds the tab title, so why would it not focus on the right tab?

my question is, how do I get it to observe one tab, when I'm working in another tab?

code snippet:

while 1:
    myApp = App("title here")
    myRegion = myApp.window()
    if not myRegion:
        popup("didnt find it")
        break
    myApp.focus() <---------- doesn't do anything, not bringing it to front, besides I want the tab to come to front not the window
    while not exists("X.png"): <-------- does not fire unless its showing on screen
        wait(30)
    myRegion.highlight(2) <------------------ highlights the main window, not the tab
    click("X.png") <--------------- fails the second time read below

I have problem with not being able to stop the script. alt+c or alt+shift+c do not work.

but also there is a problem second time it is executing the loop, it tries to click twice and fails. thus I get back the IDE:

lets say the window IS current
it then detects the X
highligts window and clicks X and that window goes away
then it sleeps till next time
it finds X
it highlights and clicks X
window dissapears
then it highlights and tries to click... then it fails..

fyi: X is closing a window inside a game in the browser. its not a real windows window.

[error] Error message: Traceback (most recent call last):
 File "C:\DOCUME~1\KALLEK~1\LOKALA~1\Temp\sikuli-tmp5486196643606122912.py", line 11, in
 click("X.png")
 Line 1, in file C:\DOCUME~1\KALLEK~1\LOKALA~1\Temp\sikuli-tmp5486196643606122912.py

 at org.sikuli.script.Region.handleFindFailed(Region.java:420)
at org.sikuli.script.Region.wait(Region.java:511)
at org.python.proxies.sikuli.Region$Region$0.super__wait(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)

org.sikuli.script.FindFailed: FindFailed: can not find X.png on the screen.
 Line 1, in file C:\DOCUME~1\KALLEK~1\LOKALA~1\Temp\sikuli-tmp5486196643606122912.py

writing only my first lines of code I don't know, is it my code or sikuli that is buggy? :D

Question information

Language:
English Edit question
Status:
Answered
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Anton (afw) said :
#1

EDIT: I solved the double execution by putting a sleep(5) in the end. But this must be a bug, no ?

Revision history for this message
RaiMan (raimund-hocke) said :
#2

myApp = App("title here")
myRegion = myApp.window()
if not myRegion:
    popup("didnt find it")
    exit(1)
myApp.focus()
myRegion.highlight(2)
while 1:
    while not exists("X.png"):
        wait(30)
    click(getLastMatch())
    wait(5)

-- title here
must be the title of the browsers title bar, which should reflect the frontmost browser tab. Since Sikuli has no feature to bring a browser tab to front, you should decide to run your game in a separate browser window, so you can use app.focus().

Based on this recommendation I have changed your script like above.

Generally: Sikuli can only find (and click) what is currently visible on the screen. So to not get any problems, you have to check, wether the region, you want to act on (contains some button you want to click) is visible. If you did not make your screen ready before starting your script or any other actions, to make things visible (like using class App), you will get find failed exceptions that usually stop the script.

Generally and especially while developing a script, endless looping does not make sense, unless they contain some coding to end the loop under specific conditions.

In your case, you might use instead of while 1:
for i in range(3):
which will run your loop 3 times and might be enough to test your approach.

While testing it is a good idea, to run the script in slow motion, which makes it easier to see, what the mouse is doing.

--- does not make sense
    while not exists("X.png"):
        wait(30)
This waits until X gets visible. But if it gets visible shortly after the exists() did not succeed, it takes another 30 seconds until the script continues.
so this is better:
    while not exists("X.png", 0): wait(2)
This checks every 2 seconds only once (without the ,0 it will wait 3 seconds for X to get visible until it continues), so you have a delay of max 3 seconds (2 secs + search time).

Since you know the region, where your X should be, you should restrict the search to that region, to speed things up.

So this would be my solution while testing.

myApp = App("title here")
myRegion = myApp.window()
if not myRegion:
    popup("didnt find it")
    exit(1)
myApp.focus()
myRegion.highlight(2)
for i in range(3):
    while True:
        mX = myRegion.exists("X.png",0)
        if not mX: wait(2)
        else: break
    click(mX)
    wait(5)

Have a look at http://sikuli.org/docx/region.html#exception-findfailed
There you can find an interactive version, to help to handle find failed situations during testing.

Revision history for this message
Anton (afw) said :
#3

Thanks very much for looking into this and for all great advice.

So, changed the game to use its own window. Supporting tabs I guess is too much to ask for.

However my objective was to work in one window, and have another under surveillance with sikuli. But since you say that: "Generally: Sikuli can only find (and click) what is currently visible on the screen. " I feel it can't achieve what I set out to do.

If myApp.focus() had worked, it would have interrupted me all the time. However focus() is not working. and If I don't have the windows visible, it never detects the Xs :( why is it not focusing/bringing to front you suppose?

I added 0 to exists() thank you... and I finally understood why the extra 5 at the end works. It must be so fast that the answer to the click is not received before it tests again. we are talking only ms. so extra 1 at the end is enough.

I had forgot to add myApp = none and myRegion = none at end of the loop

so for now, this works as long as I'm away from keyboard and it has the window active. But it's not any help when I like to do other things with the computer. Is this something that is in the roadmap for sikuli? to at least observe without focusing ?

Not seeing any workaround, sounds like I need to search for other solutions.. and I have no idea what that would be, since the easy event handling of sikuli by just adding a pic like that, is amazingly easy and just GREAT !

Revision history for this message
RaiMan (raimund-hocke) said :
#4

Even if you could manage to have your own work and the other window, that the Sikuli script is working on, side by side on the screen, it is very difficult or impossible (with heavy concurrent usage) to "synchronize" the usage of mouse and keyboard between yourself and the script.

The only solution is to run the script on another machine (which might be a VM). So the script has its own screen/keyboard/mouse.

--- sounds like I need to search for other solutions
If you want to control, what is happening in hidden windows (in the sense, that their content is currently not visible on the screen caused by whatever reason), you need a tool, that is able to control the interface between the application and the window manager, like it is partly possible on Mac with AppleScript and the System UI Server or with Selenium for web pages.
Since it is a never-ending tug war between game users, who want to have bots, and the game developers, who want to have the humans in front of their games, I dought you will find something.

So if you do not have another machine, give Parallels/VMWare/VBox a try.

Can you help with this problem?

Provide an answer of your own, or ask Anton for more information if necessary.

To post a message you must log in.