isLockOn does not change until typing from the keyboard

Asked by masuo

I am sure this behavior by using the following code.
When I click the OK button at the pop-up window, status does not change.
When I type Enter-key at the pop-up window, status will change.
(I tested on Windows7, Java 1.8.0, SikuliX1.1.0 .)

while True:
    msg = "status:%s" % Env.isLockOn(Key.NUM_LOCK)
    popup(msg)
    type(Key.NUM_LOCK)

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
Last query:
Last reply:
Revision history for this message
Best RaiMan (raimund-hocke) said :
#1

interesting. thanks. I will check.
meanwhile I make it a bug

Revision history for this message
masuo (masuo-ohara) said :
#2

Thanks RaiMan, that solved my question.

Revision history for this message
masuo (masuo-ohara) said :
#3

Thank you for checking.

Revision history for this message
Alex Lunyov (lunyov-av) said :
#4

Hi!

There is a similar problem.

In SikuliX 1.1.1 2016-6-6 this code:

for i in range(5):
    type(Key.NUM_LOCK)
    wait(20) # long wait for expected certainly internal system changes
    print(Env.isLockOn(Key.NUM_LOCK))

prints five "True" while the Numlock led toggles with delay 20 sec. By the way internal Numlock is actually switches, only the result of Env.isLockOn() is always the same.

I expected it will print a sequence True/False.

Revision history for this message
Alex Lunyov (lunyov-av) said :
#5

Just want to check, it this bug is under working. It still exists in last nightly.

Revision history for this message
Alex Lunyov (lunyov-av) said :
#6

*if this bug

Revision history for this message
Alex Lunyov (lunyov-av) said :
#7

*if this bug

Revision history for this message
masuo (masuo-ohara) said :
#8

@Alex

In Progress
See [Related bugs]
https://bugs.launchpad.net/bugs/1545428

Revision history for this message
Alex Lunyov (lunyov-av) said :
#9

Thanks, masuo. This bug is 8 month old, so, it might relies on some Java problems but not Sikuli?

Revision history for this message
masuo (masuo-ohara) said :
#10

Changelog version 1.1.1 is here.
http://nightly.sikuli.de/#dailynews

Release information is here.
https://launchpad.net/sikuli/+milestone/1.1.1

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

@Alex
I will have a look at it beginning tomorrow.

Revision history for this message
Alex Lunyov (lunyov-av) said :
#12

May be masuo's and my examples (represented here) will help you a bit. Also notice that the problem of Env.isLockOn arises sometimes when the previous run of the script was interrupted by user (alt+shift+c), in my case.

P.S. My script checks the NumLock state at the beginning and this check not always successful because of this bug. Failure takes place when I pressed alt+shift+c on the previous start (not always). I try find and report more accurate condition of Env.isLockOn failure in my case).

I wish you good luck in this job!

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

@Alex
thanks for the additional info.
they surely will help.

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

I made some research:
I will only try to fix it in version 2 (see my comments in the bug)

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

I changed my mind and fixed it now ;-)
fixed with tomorrow's nightly build

Revision history for this message
Alex Lunyov (lunyov-av) said :
#16

Oh! This is incredible! :) I'm looking forward to be updated and check the solution.

Revision history for this message
Alex Lunyov (lunyov-av) said :
#17

Sos! I've just install the last update 1.1.1 and it seems the workflow interrupts fatally every time on the command Env.isLockOn, see screenshot https://drive.google.com/open?id=0B3bgaHY_O0xMOV8wb0NpcjNwOVU

Revision history for this message
Alex Lunyov (lunyov-av) said :
#18

*installed, sorry.
The screenshot was made from the video of closing the Sikuli IDE

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

just tested on my Win 10/64 with Java 8-91 after having run a setup from the nightly build.

k = {"NUM_LOCK":Key.NUM_LOCK, "SCROLL_LOCK":Key.SCROLL_LOCK, "CAPS_LOCK":Key.CAPS_LOCK}
for key in k.keys():
  vk = k[key]
  print key, Env.isLockOn(vk)
  type(vk)
  print key, Env.isLockOn(vk)

... prints
CAPS_LOCK False
CAPS_LOCK True
SCROLL_LOCK False
SCROLL_LOCK True
NUM_LOCK False
NUM_LOCK True

and all the leds on my keyboard are on and the states are switched indeed.

... and I do not have any problems.

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

... and Java 8-111 works as well

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

... maybe it helps if you delete ALL versioned folders in <SikuliXAppData> (SikulixDownloads and SikulixLibs) and rerun the setup.

Revision history for this message
Alex Lunyov (lunyov-av) said :
#22

Thank you for the advice. I'll try. I have a backup in any case.

Revision history for this message
Alex Lunyov (lunyov-av) said :
#23

I deleted all "C:\Users\Lunyov\AppData\Roaming\Sikulix" folder, no effect. Then I uninstalled Java 8-111, reinstalled it, again deleted SikuliX and installed last nightly SikuliX 1.1.1. No effect. I have got hs_err_pid1236.log in my Sikuli working folder with fatal error description.
I'll try on another computer and comment here the result.

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

could you send the detailed error description and stack traces to my mail sikulix--at--outlook--dot--com

Revision history for this message
Alex Lunyov (lunyov-av) said :
#25

OK, RaiMan, I'll do that. Some news meanwhile: I've installed last nightly version of SikuliX on the similar computer (Win 7 64 bit) with Java 7 version installed. Env.isLockOn(...) didn't cause fatal error, worked fine. Then I updated to Java 8-111 and it crashed agatin on the isLockOn function.

Revision history for this message
Alex Lunyov (lunyov-av) said :
#26

The problem was solved with RaiMan's assist. Java 64 bit was needed, not 32 bit version, on Win 7-64.

Revision history for this message
Alex Lunyov (lunyov-av) said :
#27

Well, the problem of _crashing_ was solved, but... I have just realized that Env.isLockOn(...) doesn't work as expected. This function gives True in any cases. Type(Key.*_LOCK) works fine though. I use Win 7 64 bit. I've tried to install Java 8-111 64 bit + Sikuli last nightly on two sterile machines Win 7 64 bit and also reinstalled that on mine. No result.

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

@Alex
I am sorry for the inconvenience, but I cannot test this on a Windows 7 currently.
I developed and tested the implementation on Win10, where it works without problems.

This is the implementation according to the Windows API, where it states, that this is valid since Win2000.

Env.isLock... is routed to here in class Key

  /**
   * get the lock state of the given key
   *
   * @param key as Character (scroll, caps, num)
   * @return true/false
   */
  public static boolean isLockOn(char key) {
// Toolkit tk = Toolkit.getDefaultToolkit();
// return tk.getLockingKeyState(KeyEvent.VK_SCROLL_LOCK);
// return tk.getLockingKeyState(KeyEvent.VK_CAPS_LOCK);
// return tk.getLockingKeyState(KeyEvent.VK_NUM_LOCK);
    if (!RunTime.get().runningWindows) {
      return false;
    }
    switch (key) {
      case '\ue025':
        return SysJNA.WinUser32.isScrollLockOn();
      case '\ue027':
        return SysJNA.WinUser32.isCapsLockOn();
      case '\ue03B':
        return SysJNA.WinUser32.isNumLockOn();
      default:
        return false;
    }
  }

... and the low level implementation in SysJNA.WinUser32:

  /**
   * Direct access to Windows API user32.dll via BridJ
   */
  @Library("user32")
  public static class WinUser32 {

    /*
    https://msdn.microsoft.com/pt-br/library/windows/desktop/dd375731
    VK_NUM_LOCK 0x90
    VK_SCROLL 0x91
    VK_CAPITAL 0x14
    */
    private static int WinNumLock = 0x90;
    private static int WinScrollLock = 0x91;
    private static int WinCapsLock = 0x14;

    static {
      BridJ.register();
    }

    public static boolean isNumLockOn() {
      int state = GetKeyState(WinNumLock);
      return state > 0;
    }

    public static boolean isScrollLockOn() {
      int state = GetKeyState(WinScrollLock);
      return state > 0;
    }

    public static boolean isCapsLockOn() {
      int state = GetKeyState(WinCapsLock);
      return state > 0;
    }

    /*
    https://msdn.microsoft.com/en-us/library/ms646301(VS.85).aspx
    SHORT WINAPI GetKeyState(
      _In_ int nVirtKey
    );
     */
    private static native int GetKeyState(int aVK);
  }

You might check the MS links and look for any possible reason.

I will only have a chance to go deeper after end of November (some vacation ;-)

Revision history for this message
Alex Lunyov (lunyov-av) said :
#29

May be this will help: GetKeyState returns type SHORT signed and state variable is of Java INT type, and so sign is lost (and hence True value is returned anyway). May be Java in Win 10 is able to repair this incompatibility with signs.

OK, this all is just my humble thoughts and I can't look deeper. Just try to help. :)

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

Yes, I already thought about that too, but the "sign-bit" is only on, if in that moment the respective key is pressed (held-down).
The toggle state (on/off) is reported by the right-most bit being 1 or 0.
So since I use
state > 0
IMHO this can only return true if the right-most bit is on and with or without sign-bit never in the off-case.

... but I will check how BridJ maps a short as return value back to an int.