<div dir="ltr">On Sun, Aug 14, 2011 at 17:03, Jochen Keil <span dir="ltr">&lt;<a href="mailto:jochen.keil@gmail.com">jochen.keil@gmail.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">&gt; It&#39;s because your function is doing stuff instead of listening for X<br>
&gt; events.  If you want to go off and do something else, forkIO a thread<br>
</div>I&#39;ve already tried forkIO, xfork, seq, par, etc. all with more or less<br>
</blockquote><div><br></div><div>seq and par won&#39;t do anything useful here (seq has nothing to do with parallelism and par isn&#39;t designed for this kind of usage).  Also, xmonad doesn&#39;t use OS threads, and it&#39;s just occurred to me that there&#39;s no way to hook the X event loop into GHC&#39;s thread scheduler, so forkIO won&#39;t actually be useful anyway.  :(</div>
<div><br></div><div>xfork spawns a subprocess, which would then need to send X events to the main event loop which you would handle in the handleEventHook.  This is also how an independent thread would need to communicate.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">the same result: the program&#39;s window will be mapped only after the<br>
function returns.<br></blockquote><div><br></div><div>...this happens with forkIO as well?  I&#39;m tempted to say you didn&#39;t use it properly; &quot;after the function returns&quot; isn&#39;t one of the behaviors I&#39;d expect unless you&#39;re trying to synchronize with the thread as well.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">&gt; for the something else.  If your something else requires communication<br>
&gt; with X11, you&#39;ll need to think about rewriting around the event<br>
&gt; handler instead.<br>
</div>I can&#39;t see how to do this at the moment. Is this even possible? As far<br>
as I understand/stood the xmonad code it&#39;s all about grabbing events.<br></blockquote><div><br></div><div>That&#39;s *why* event passing is how it should be solved.</div><div><br></div><div>As to the how:  sendEvent and the handleEventHook.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">       timeout &lt;- io $ waitForEvent d 1000000</div></blockquote><div><br></div><div>*sigh* This is a good way to make xmonad stop processing events.  You must *not* do this if you expect xmonad to be usable while waiting.  (This is why X.A.Submap doesn&#39;t try to handle timeouts.)</div>
<div><br></div><div>Instead, you need to have the event loop manage it.  Use ExtensibleState to store the keymap state and start time; the handleEventHook recognizes a key, checks the ExtensibleState to see if it&#39;s useful, and if so acts on it and returns All False to prevent xmonad&#39;s default handler from also acting on the key.  Acting on it may involve updating the state to point to a new submap, or performing some xmonad action.  You should also forkIO a timeout thread which invokes (delay) (see Control.Concurrent) and then sendEvent to send a timeout event which is also processed by the handleEventHook.  (Remember to clear the ExtensibleState as well as invoking releaseKeys.)</div>
<div><br></div><div>&gt; -- this is oversimplistic:  you need to make sure the MyTimeoutEvent corresponds</div><div>&gt; -- to the current vmap and not an earlier one, by storing some kind of id in both.</div><div>&gt; -- You can&#39;t simply pass the vmap because it&#39;s going to take a trip through the X11</div>
<div>&gt; -- server and there&#39;s no guarantee the same pointer comes back.</div><div>&gt; handleEventHook (SendEvent {ev_type = e})</div><div>&gt;     | e == MyTimeoutEvent = releaseKeys &gt;&gt; ES.put () &gt;&gt; return (All False)</div>
<div>&gt; handleEventHook (KeyPress {ev_key = k}) = do</div><div>&gt;   vmap &lt;- ES.get -- state of vi keymap</div><div>&gt;   -- keyDecision goes here, more or less</div><div>&gt;   -- if you update the keymap, delete the </div>
</div><div>&gt; </div><div>&gt; -- the initial key binding then places the vi keymap in ES and spawns a timeout</div><div>&gt; -- thread, allowing the handleEventHook to do the rest.</div><div><br></div>-- <br>brandon s allbery                                      <a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a><br>
wandering unix systems administrator (available)     (412) 475-9364 vm/sms<br><br>
</div>