<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>No Key-Up event received on Alt+Tab out</title>
		<link>http://www.allegro.cc/forums/view/615411</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Sat, 30 May 2015 02:14:11 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Currently Allegro doesn&#39;t send a key-up message when switching out while keys are pressed, as happens when using Alt+Tab.  This also becomes an issue if, during gameplay, another app steals the focus.</p><p>When using the event system to handle keys, I am able to work around it by clearing my internal key state on receiving ALLEGRO_EVENT_DISPLAY_SWITCH_OUT, however this doesn&#39;t help for <span class="source-code"><a href="http://www.allegro.cc/manual/al_get_keyboard_state"><span class="a">al_get_keyboard_state</span></a><span class="k2">(</span><span class="k2">)</span></span>, which I also use.  I know the general wisdom is not to use the keyboard state API, but there are cases where it is useful when a more immediate state is needed than once per frame--blocking until a key is released, for example.</p><p>Would there be a way to modify the keyboard state API so that switching out clears any keys currently set as &quot;down&quot; internally?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Tue, 26 May 2015 23:07:09 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Which platform? Windows uses a win32 call to update keyboard state as far as I know so I can&#39;t see how it would be a problem there... but maybe things changed since I last looked.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Elias)</author>
		<pubDate>Wed, 27 May 2015 01:21:42 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Windows, yeah.</p><p>From a cursory look at the source, it looks like Allegro only calls Win32 directly to get the state of Caps Lock et al, the event system is used to track all other state.  So of course if the game loses focus, the display never gets the KEY_UP event and Allegro keeps thinking it&#39;s still pressed.  I notice it happens a lot with the Shift key for me.</p><p>My quick fix was to add this function to wkeyboard.c:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number"> 406</span><span class="c">/* _al_win_kbd_clear_state:</span>
<span class="number"> 407</span><span class="c">*  Clears the keyboard state, e.g. when switching out</span>
<span class="number"> 408</span><span class="c">*/</span>
<span class="number"> 409</span><span class="k1">void</span> _al_win_kbd_clear_state<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span>
<span class="number"> 410</span><span class="k2">{</span>
<span class="number"> 411</span>   <a href="http://www.delorie.com/djgpp/doc/libc/libc_569.html" target="_blank">memset</a><span class="k2">(</span><span class="k3">&amp;</span>the_state, <span class="n">0</span>, <span class="k1">sizeof</span><span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_KEYBOARD_STATE"><span class="a">ALLEGRO_KEYBOARD_STATE</span></a><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 412</span><span class="k2">}</span>
</div></div><p>

And then call that in the WM_ACTIVATE handler in wwindow.c on switch-out.</p><p>But of course, naturally I&#39;d prefer to use an unmolested Allegro build if at all possible.  Unfortunately, there&#39;s no way to work around it right now <i>without</i> editing Allegro directly...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Wed, 27 May 2015 08:10:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Somewhat ironically, Linux supports overriding single or groups of library functions using LDPRELOAD.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Chris Katko)</author>
		<pubDate>Wed, 27 May 2015 09:42:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>This problem has popped up before. I guess it would be a reasonable workaround to add an al_clear_keyboard_state() API function for all platforms which you then can call on receiving an ALLEGRO_EVENT_DISPLAY_SWITCH_OUT or  ALLEGRO_EVENT_DISPLAY_SWITCH_IN.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (beoran)</author>
		<pubDate>Wed, 27 May 2015 11:14:38 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The root of the problem, of course, is the lack of KEY_UP events from the OS when focus is lost.  But this is an OS limitation, so all we can do is work around it... Imagine if you never got button-up events when you dragged the mouse outside a window?  Implementing drag and drop would be a nightmare. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>But I&#39;m not sure the state-clearing should be exposed to the outside, it seems more something that should be done internally.  It&#39;s not exactly intuitive when keys are reported as pressed after they&#39;ve been physically released just because the programmer didn&#39;t handle DISPLAY_SWITCH_OUT.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Thu, 28 May 2015 03:22:16 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I think it&#39;s a valid use case to <u>not</u> have key_up events when window focus is lost, the most obvious being while your debugging your app/gui and the debugger interrupts you.</p><p>I also ran into this issue debugging my allegro apps in linux and android.<br />Anybody who wants to clear the input state can catch the ALLEGRO_EVENT_DISPLAY_SWITCH_OUT event and update your application key/mouse/touch states appropriately.<br />It&#39;s a minor inconvenience. Don&#39;t force this behavior onto people. Especially if there&#39;s no way to tell if the key_up event came because of the user or the window manager.<br />None of the OS&#39;s I&#39;ve tested on generate key_up events when focus is lost, and it&#39;s probably for good reason.</p><p>Just my $0.02<br />Pho75
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Pho75_)</author>
		<pubDate>Thu, 28 May 2015 16:59:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I agree more with Pho75_ here. Also, in Allegro 5 there is a precedent that on certain events, you have to manually call certain allegro functions to handle the event. Functions such as <span class="source-code"><a href="http://www.allegro.cc/manual/al_acknowledge_resize"><span class="a">al_acknowledge_resize</span></a><span class="k2">(</span><span class="k2">)</span></span> come to mind. </p><p>However, I also think that  <span class="source-code"><a href="http://www.allegro.cc/manual/al_get_keyboard_state"><span class="a">al_get_keyboard_state</span></a><span class="k2">(</span><span class="k2">)</span></span> is clearly not well enough documented. It should be noted what will happen on a display lost event. If we introduce an al_clear_keyboard_state then it should be when it must be called.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (beoran)</author>
		<pubDate>Thu, 28 May 2015 19:44:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>My point here was, al_get_keyboard_state(), naming-wise, looks like a function which returns the current state of the keys at the time of call (similar to GetKeyState() in Win32).  However, since it uses events under the hood, this is not actually the case.  The behavior is not intuitive.</p><p>That&#39;s why I argue for clearing the internal state automatically on switch-out, to make the function adhere closer to the behavior suggested by its name.</p><p>Just to clear up any confusion: I&#39;m not suggesting Allegro start sending automatic KEY_UP events on switch-out (this would be unexpected, as pointed out), just to not make the state get &quot;stuck&quot; if the app suddenly loses focus while a key is pressed.  It&#39;s not always the programmer&#39;s fault if focus is lost--sometimes other apps on the system steal it.</p><p>I view it as a similar situation to D3D display loss: Allegro defaults to restoring the display automagically whenever it&#39;s lost, without any inconvenience to the library user.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Thu, 28 May 2015 23:30:57 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>No, your idea is very clear, just that I&#39;m not sure that automatically clearing the key state is always what the end user wants. As Pho75_ says, it might cause problems when debugging. </p><p>The analogy with bitmap reloading on Directx is interesting though as that behavior is configurable. Perhaps we can do what you want, but make it configurable using al_set_new_display_flags or such...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (beoran)</author>
		<pubDate>Fri, 29 May 2015 08:46:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Err.. a display flag for a keyboard setting? How about al_clear_keyboard_state? That is the most simple and direct way of doing it, leaves it up to the user to do so, and we could add a note in the docs about ALLEGRO_EVENT_DISPLAY_SWITCH_IN and needing to clear the key state if desired, and leave it optional.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">if</span> <span class="k2">(</span>ev.type <span class="k3">=</span><span class="k3">=</span> ALLEGRO_EVENT_DISPLAY_SWITCH_IN<span class="k2">)</span> <span class="k2">{</span>
   al_clear_keyboard_state<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Fri, 29 May 2015 09:02:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Eh, I&#39;ll take it.  I&#39;m still worried that it&#39;s not intuitive and raises the barrier to entry by giving the library user another responsibility (the one thing I love about Allegro is the shallow learning curve, it&#39;s easy to get started but turns out to be very powerful as you get more skilled...), but it would solve the issue at hand at least.</p><p>For what it&#39;s worth I think the clear should almost always be done on switch <u>out</u> though, otherwise if focus is lost the key is stuck in &quot;pressed&quot; state until the display window is reactivated.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Fri, 29 May 2015 09:07:24 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If you perform the clear on switch out, then you miss any keys pressed after that but before switch in. You shouldn&#39;t be checking the keyboard state on switch out for the very reason that it is not reliable due to os limitation.</p><p>Actually, wait. I may be wrong. If a window registers itself as an RIDEV_INPUTSINK device it can receive keyboard input even while the window is not in focus. However in my explorations of this recently I believe it only works with gui applications. If you create a console application it fails to register the device. I need to check that though.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Fri, 29 May 2015 09:34:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>That&#39;s kind of the point though, right?  If your app doesn&#39;t have the focus you don&#39;t want to get any key events.  Hence why you clear the state, to set all keys as not-pressed so they won&#39;t affect the game while it&#39;s not active.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Fri, 29 May 2015 09:36:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Well if you want correct keystate you&#39;re gonna have to listen to keyboard events when not in focus.</p><p>The kb state comes from the Raw Input API, it could easily be sent as ALLEGRO_EVENT_KEYBOARD events or not based on a simple flag, but at the same time, maintain internal state and consistency.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Fri, 29 May 2015 09:41:24 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I think we&#39;re discussing two different things now.  I was referring to the proposed al_clear_keyboard_state() API.  The best place to call that is on switch-out, otherwise keys stay in &quot;pressed&quot; state because the display never gets the key_up event.</p><p>And unfortunately, no, the KB state is actually emulated via events, at least on Win32.  I wish it were taken from raw input, but it&#39;s not.  That&#39;s the source of the issue here--if the game loses focus, the KEY_UP is lost so the game keeps thinking it&#39;s down.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Fri, 29 May 2015 09:46:21 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Allegro monitors WM_INPUT which uses the Raw API, at least for the mouse. It could probably be extended fairly easily to monitor the keyboard info as well. All that needs to be done is to register the device type for the keyboard with windows.</p><p>Edit<br />And actually, now that I read Pho75&#39;s post again, I realize that you don&#39;t even need to clear allegro&#39;s key state but your own (and use events instead of keystates). Although there is the problem of keys being held while out of focus and then giving focus back to the window while the key is still pressed then allegro thinks the key is not down until it is released, and pressed again.</p><p>We could clear the key state during WM_ACTIVATE in wwindow.c, as it already calls _al_win_fix_modifiers() anyway.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Fri, 29 May 2015 09:55:47 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/615411/1013631#target">Bruce Pascoe</a> said:</div><div class="quote"><p> Just to clear up any confusion: I&#39;m not suggesting Allegro start sending automatic KEY_UP events on switch-out (this would be unexpected, as pointed out), just to not make the state get &quot;stuck&quot; if the app suddenly loses focus while a key is pressed. </p></div></div><p>I believe this would even worse behavior.<br />Now allegro&#39;s keyboard state and the keyboard event queue don&#39;t match.<br />If the keyboard state changes, there darn well better be a corresponding key_up/key_dn event generated in the event queue.</p><p>I make frequent use of both Polling keystate and listening for events simultaneously, and I&#39;m not doing unholy sorcery, you might simply want to check if somebody is holding down LSHIFT, etc.</p><p>Otherwise nobody can ALT+tab out of an allegro app because it risks breaking the input state.<br />Regardless of which behavior you choose as default, allegro should not contradict itself.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p> It&#39;s not always the programmer&#39;s fault if focus is lost--sometimes other apps on the system steal it.
</p></div></div><p>What if the end user wants it. Suppose I want to walk from the west coast to the east in my RPG and it takes 15min. You&#39;re telling me I can&#39;t press RIGHT and alt+tab away, go make a mohito and come back later. I can&#39;t even ALT+TAB to my browser and read until my character reaches the destination. Now I have to sit and hold the key for 15min<br />or hire a day-laborer to hold the key down for me (economy, jobs, durka-dur! XP).<br />Ok, that&#39;s facetious, but you get my point. I&#39;m not disagreeing the default behavior<br />you desire is probably what the end-user wants most of the time, but an app/user can be doing anything, so it&#39;s certainly not right for everyone all of the time.</p><p>Cheers
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Pho75_)</author>
		<pubDate>Fri, 29 May 2015 21:45:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The LSHIFT thing was a perfect example actually, suppose you&#39;re typing something and press Shift to get an uppercase letter, and while you&#39;re doing that a background app steals the focus for a split second.  The user doesn&#39;t realize this and releases Shift during focus loss.  User keeps typing, and ends up with a pseudo caps-lock because Allegro still thinks Shift is pressed.  That&#39;s the kind of issue I was referring to, and one that I get complaints from playtesters about all the time.  Maybe some users would find it desirable (in the same way that cloning in a Pokemon game is desirable), but 9 times out of 10, in a game it will be treated as a bug.</p><p>The point I&#39;m trying to make is, al_get_keyboard_state() as implemented doesn&#39;t actually return the <i>current state</i> of the keys, only what Allegro <i>thinks</i> the state is.  This is not how any other polling input API (GetKeyState, joystick functions, etc.) works, if the user calls this function it&#39;s because they want the real, up-to-the-minute key state.  It serves a completely different purpose than the event API.</p><p>Anyway, like I said, al_clear_keyboard_state() is a good compromise, and I&#39;d accept that.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Fri, 29 May 2015 22:49:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>This topic is in risk of becoming a bikeshed paining session so, I&#39;ll stop arguing and agree that &#39;al_clear_keyboard_state()&#39; would be a desirable workaround. I&#39;ll propose this on the mailing list.</p><p>EDIT: I proposed it and it looks like such a function is acceptable, but we&#39;re still discussing the details.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (beoran)</author>
		<pubDate>Sat, 30 May 2015 02:14:11 +0000</pubDate>
	</item>
</rss>
