harbour / core

Portable, xBase compatible programming language and environment
https://harbour.github.io/
Other
324 stars 207 forks source link

Right Alt Key ignored by inkey()/LastKey() #239

Open Hovestar opened 3 years ago

Hovestar commented 3 years ago

In inKey() (on windows 10) the right alt key is ignored.

For example: while !((nLast:=inkey(0, INKEY_KEYBOARD))==27) // escape ? nLast,lastKey() enddo

Pressing left alt + g gives 290 290 g gives 103 103 right alt + g gives 103 103 left ctrl + g gives 7 7 Right ctrl + g gives 7 7

We've noticed on multiple machines, and the same code in xHarbour gives proper results.

alcz commented 3 years ago

Which keyboard layout is set on those Win10 machines? US? Is it GTWIN terminal? Also for some layouts "right Alt" equals "left Ctrl+left Alt", what would it do with "g"?

Hovestar commented 3 years ago

US, and no other keyboards installed. Pressing "left Ctrl+left Alt + g" doesn't even trigger inkey(). The docs mention that ctrl+alt doesn't work: https://harbour.github.io/doc/harbour.html#inkey

Hovestar commented 3 years ago

However that's distinct behavior from right alt g where it just gives the code that g would normally give.

alcz commented 3 years ago

I've made some tests, but not having US layout here. Both on Win7 and Win10. right Alt + g doesn't work, nor left Alt + left Ctrl + g - both do not generate any scan code, one can use only left Alt + g No difference with sample run by old xHarbour 1.0.0 - the only one i have here.

You can build keybord test app from the repo too: https://github.com/harbour/core/blob/master/tests/gtkeys.prg

There is also a registry based solution for mapping right alt to work exactly like left one. With SharpKeys utility or without. https://stackoverflow.com/a/460800

Petewg commented 3 years ago

Hi, you may want to take a look at this thread: https://groups.google.com/g/harbour-devel/c/8Sc9YI5hnDE/m/eAn9Q9zGBAAJ not sure, but perhaps could be relevant with the issue in question.

Hovestar commented 3 years ago

That looks like exactly this issue. I'll see what I can do with that to resolve the issue.

For my reference look at commits related to these: druzus - Jul 4, 2016, 1:19:03 PM druzus - Jun 29, 2016, 5:05:09 PM 2016-06-20 21:59 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)

Thanks, I'll detail a solution here once I get one.

Hovestar commented 3 years ago

After extensive debugging this is an intentional feature gtwin.c:~1700:

if( iChar >= 32 &&
      ( ( ( iFlags & HB_KF_CTRL ) != 0 && ( iFlags & HB_KF_ALT ) != 0 ) ||
      ( dwState & ( LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED ) ) == RIGHT_ALT_PRESSED ) )
{
   iFlags &= ~( HB_KF_CTRL | HB_KF_ALT );
   iKey = HB_INKEY_NEW_CHARF( iChar, iFlags );
}
else
   iKey = HB_INKEY_NEW_KEY( iChar, iFlags );

I assume that this is a choice for international support, but I think it would be nice to have some way to turn this logic off. I'll leave the issue open for a day or two, and if there's nothing else on it I'll come close it.

alcz commented 3 years ago

Perhaps we could add some US/International modes into (sort of reused) HB_GTI_KBDALT with the current mode as default. hb_gtInfo( HB_GTI_KBDALT, HB_GTI_KBDALT_US / HB_GTI_KBDALT_INTL )

With those added to hbgtinfo.ch:

/* Keyboard Right-ALT US mode */
#define HB_GTI_KBDALT_INTL      0
#define HB_GTI_KBDALT_US        1

Will see if I can make a patch that is not awful, because HB_GTI_KBDALT used to have logical paramters.