GetKeyShiftState not working on Linux / GTK? lazarus / 31-LCL ---------------------------------------------------------------------- Alloc · 2016-06-17 15:53 Hi there, have been successfully implementing a little launcher tool for a game. Made it so it only shows its own window when Shift is pressed at start up time, otherwise it directly starts the game and closes itself. Now I ported it over to Linux but it does no longer show itself when shift is pressed when the program is started. I use the following in the application's main form's OnCreate event: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if ssShift in GetKeyShiftState() then// show launcher Is that a known issue? Is there something else I could use instead to query the current state of the Shift key? Kind regards, Chris ---------------------------------------------------------------------- RAW · 2016-06-17 17:52 For me it's working too... under Windows. But unfortunately I cannot test it under Linux right now...  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i UNIT uShiftTest;{$MODE OBJFPC}{$H+}INTERFACEUSES Windows,Classes,SysUtils,F orms,Controls;TYPE TForm1 = Class(TForm)  Procedure FormCreate (Sender:TObject); PRIVATE  Const   ByeBye = WM_USER + 555; PROTECTED  Procedure WndProc (Var MSG:TMessage);Override; End;VAR Form1: TForm1;IMPLEMENTATION{$R *.LFM} Procedure TForm1.FormCreate(Sender:TObject);Begin  // MainForm = Application.ShowMainForm:= False;  If ssShift In GetKeyShiftState()  Then Show  Else SendMessage(Handle,ByeBye,0,0);End; Procedure TForm1.WndProc(Var MSG:TMessage);Begin  If MSG.Msg = ByeBye  Then Close  Else Inherited WndProc(MSG);End; END. ---------------------------------------------------------------------- Alloc · 2016-06-18 12:24 Even working on OSX, just not Linux it seems ---------------------------------------------------------------------- Abelisto · 2016-06-18 13:04 Quote from: Alloc on June 18, 2016, 02:24:02 pmEven working on OSX, just not Linux it seems Works fine with the simple test: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);var    st: TShiftState;    sts: string[3];begin    st := GetKeyShiftState;    sts := '   ';    if ssShift in st then        sts[1] := 'S';    if ssCtrl in st then        sts[2] := 'C';    if ssAlt in st then        sts[3] := 'A';    Caption := sts;end; Linux Mint. Probably the problem somewhere else. ---------------------------------------------------------------------- Alloc · 2016-06-19 00:12 Yeah, it seems like it works when used with the form being visible, but not when used within the OnCreate event of the main form ---------------------------------------------------------------------- Windsurfer · 2016-06-19 09:53 Try using the OnShow event, rather than the OnCreate event. The form does exist to accept key strokes until after it has been created. ---------------------------------------------------------------------- Alloc · 2016-06-19 11:21 Same issue ... added an OnShow handler and checked GetKeyShiftState and it doesn't return any of the modifiers. Also, if I would do it in the OnShow the window would always flash up, even if Shift isn't pressed (and thus the launcher should not show). ---------------------------------------------------------------------- Windsurfer · 2016-06-19 14:49 This works in Linux using LCL and GTK2 and avoids a lot of complexity. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Procedure TForm1.FormActivate(Sender: TObject);  begin    If ssShift In GetKeyShiftState()    Then Form1.Show    Else      begin        Form1.visible := False;        ShowMessage('Bye');        Application.Terminate;      end;  end; ---------------------------------------------------------------------- RAW · 2016-06-19 14:56 I've never used it but what about directly talking to Xlib (xGrabKey or xGrabKeyboard...) ??? Or is GetKeyShiftstate doing it already? There must be a similar way that is functioning... ---------------------------------------------------------------------- Alloc · 2016-06-19 21:49 @Windsurfer: This might work but even if so it shows the same issue as OnShow: It would show the window and then close it again (i.e. "flash" it) @SoE: Yeah, using system APIs most likely would do the trick but I'm not to keen to go any direct-lib-access route here. Already fearing that the precompiled executables won't work on a lot of other systems (unlike with Pascal executables on Windows where you can be almost 100% sure they will run on anything ...). Still hoping there's a proper solution for this with "built-in" stuff ---------------------------------------------------------------------- RAW · 2016-06-20 01:23 Try this.... EDIT: Maybe it's a good idea to give the user a little bit more time ... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i UNIT uGetShift;{$MODE OBJFPC}{$H+}INTERFACEUSES Classes,SysUtils,Forms,Cont rols,ExtCtrls;TYPE TForm1 = Class(TForm)  Procedure FormCreate        (Sender:TObject);  Procedure FormCloseQuery      (Sender:TObject;Var CanClose:Boolean);  Procedure OnKeyDownWndShift   (Sender:TObject;Var Key:Word;Shift:TShiftState);  Procedure OnCloseQueryWndShift(Sender:TObject;Var CanClose:Boolean);  Procedure OnTimer             (Sender:TObject); PRIVATE  WndShift:TForm;Timer:TTimer; End;VAR Form1:TForm1;IMPLEMENTATION{$R *.LFM} Procedure TForm1.FormCreate(Sender:TObject);Begin  // main wnd = Application.ShowMainForm:= False;  // create wnd to recognize SHIFT on keydown  WndShift:= TForm.Create(Self);  WndShift.AlphaBlend:= True;  WndShift.AlphaBlendValue:= 1;  WndShift.KeyPreview:= True;  WndShift.BorderStyle:= bsNone;  WndShift.FormStyle:= fsSystemStayOnTop;  WndShift.OnKeyDown:= @OnKeyDownWndShift;  WndShift.OnCloseQuery:= @OnCloseQueryWndShift;  WndShift.SetBounds(0,0,1,1);  // create timer  Timer:= TTimer.Create(wndShift);  Timer.Interval:= 4000;  // 4 seconds to press SHIFT  Timer.OnTimer:= @OnTimer;  Timer.Enabled:= True;  // "show" wnd  WndShift.Show;End; Procedure TForm1.OnKeyDownWndShift(Sender:TObject;Var Key:Word;Shift:TShiftState);Begin  If ssShift In Shift  Then   Begin  Timer.Enabled:= False;    Show;    WndShift.Release; // optional   End;End; Procedure TForm1.OnTimer(Sender:TObject);Begin  Timer.Enabled:= False;  Application.Terminate;End; Procedure TForm1.OnCloseQueryWndShift(Sender:TObject;Var CanClose:Boolean);Begin  // deny closing  CanClose:= False;End; Procedure TForm1.FormCloseQuery(Sender:TObject;Var CanClose:Boolean);Begin  If Visible  Then CanClose:= True  Else CanClose:= False;End; END. ---------------------------------------------------------------------- Windsurfer · 2016-06-20 12:39 Try setting Visible := false in the Object Inspector. I just checked and mine was set that way. I did not see any screen flashes on my system. (Linux rather than Windows.) ---------------------------------------------------------------------- Alloc · 2016-06-20 14:55 @Windsurfer: If Visible is set to false the OnActivate event won't trigger (unless you use Form.Show somewhere but that again will set Visible to true). @SoE: Interesting solution. Actually I probably wouldn't even need the timer but instead could use OnActivate on that new form. Issue is though, that AlphaBlend doesn't seem to have any effect on forms at all. So it will always be at least a 1x1 pixel left But this could still be better than it completely not working at all ---------------------------------------------------------------------- RAW · 2016-06-20 20:23 Quote..that AlphaBlend doesn't seem to have any effect on forms at all... Really ? On Windows 7 I can see absolutely nothing even when I set the color to clfuchsia. Is that a LINUX bug or a feature ??? If you ask me, why not showing the second window in the middle of the screen and telling the user how much seconds he had left to press shift to enter the configuration menu or whatever... (counting the seconds and telling him that the window will automatically close after 3 or 4 seconds). That will also work as a good reminder for the user. Feels a little bit more like the normal way... showing him the options he got... ---------------------------------------------------------------------- Alloc · 2016-06-20 20:27 Quote from: SoE on June 20, 2016, 10:23:11 pmQuote..that AlphaBlend doesn't seem to have any effect on forms at all... Really ? On Windows 7 I can see absolutely nothing even when I set the color to clfuchsia. Is that a LINUX bug or a feature ???Could also be Xfce, Xubuntu, GTK2, theme ... Quote from: SoE on June 20, 2016, 10:23:11 pmIf you ask me, why not showing the second window in the middle of the screen and telling the user how much seconds he had left to press shift to enter the configuration menu or whatever... (counting the seconds and telling him that the window will automatically close after 3 or 4 seconds). That will also work as a good reminder for the user. Feels a little bit more like the normal way... showing him the options he got... Well, there's the option to show the launcher by a command line argument (and that is passed by one of the Steam launch options so not that hard to get ). I don't really like delaying the start of the actual program. But the current workaround with a second 1x1 px window just to check GetKeyShiftState in its OnActivate seems to work fine. Not the nicest solution but working. Of course if anyone still comes up with a way to get the shift-state without such a hack (and without pulling in further library dependencies ) I would be happy. Thank you guys again a lot for all your input.