On 21 April 2012 09:49, Uli Schlachter <[email protected]> wrote: > On 21.04.2012 09:09, Anurag Priyam wrote: >> On Sat, Apr 21, 2012 at 9:20 AM, dodo <[email protected]> wrote: >>>>> not quite. you tell awful.keygrabber that you want keys but if someone >>>>> after you asks for keys as well he will get it until he leaves it and >>>>> you're back in key control again. >>>>> the attachment might describe it in a better way than my words ^^ >> >> Patch 1: >> >> [...] >> +--- Keygrabber Stack >> +module("awful.keygrabber") >> + >> +-- Private data >> +local grabbers = {} >> +local keygrabbing = false >> + >> +--- The global key grabber >> +-- that distributes the key events to the last grabber in history >> +local function grabber(mod, key, event) >> + for i, g in ipairs(grabbers) do >> + -- continue if the grabber returns explicitly false >> + if g(mod, key, event) ~= false then >> + break >> + end >> + end >> +end >> + >> >> Say I run two grabbers one after the other. If the second grabber >> returns false, the event will be dispatched to the first one without >> removing the second one from the stack. This doesn't sound like what >> you previously said "...if someone after you asks for keys as well he >> will get it until he leaves it and you're back in key control again." > > Uhm, I think this "table stack" works the other way around than you think it > works. The newest entry has index 1 in the table. > > So the first entry in the table gets asked "Do you want this key event?". > Unless > it returns false, the answer is taken to be "yes". So the one that was started > last can decide if it wants a key or not. Only if it doesn't want it, the > event > gets passed on to others. > > Keygrabber can thus not only ask for old events, but can also pass on some of > them to "older" keygrabbers. E.g. a menu which can only be navigated with > arrow > keys and ignores/passes on all other keys. > >> Also, won't bad things happen if the first grabber calls >> awful.keygrabber.stop and is removed from the stack while the second >> one is still running? I think it is best to send key events to only >> the first grabber on the stack: > > Nah, look below at the implementation of stop() (which is also why your > optimization doesn't work). > >> local function grabber(mod, key, event) >> local g = grabbers[1] >> g(mod, key, event) >> end >> >> +--- Remove a key grabber from the history >> +-- @param g The key grabber that must be removed. >> +function stop(g) >> + for i, v in ipairs(grabbers) do >> + if v == g then >> + table.remove(grabbers, i) >> + break >> + end >> + end >> >> In the context of the above argument, I think you just need a stack 'pop' >> here: >> >> table.remove(grabbers, 1) > > So let's say I open a menu and from the menu I start a prompt. > > | action | grabber table | > ------------------------------------------------------ > | open menu | [menu's grabber] | > | start prompt | [prompt's grabber, menu's grabber ] | > | close menu | [prompt's grabber ] | > > In the last step, you could also have stopped the prompt and continued with > the > menu. So this doesn't work FIFO, but instead they can be removed/stopped in > any > order. > >> [...] >> +--- Update key grabber history. >> +-- @param g The key grabber that will get the key events until it >> will be deleted or a new grabber is added. >> +function run(g) >> + -- Remove the grabber if its in stack >> + stop(g) >> + -- Record the grabber has latest added >> + table.insert(grabbers, 1, g) >> >> Why not insert at the last position and assume the tail of the table >> to be the head of the stack? > > Because then the ipairs() in grabber would start with the oldest registered > grabber, not with the newest one. > > Does this make sense? Do you agree that this makes sense? > > (I take your response as a NACK to the patch and will now wait for an ACK or a > timeout ;-) ) > > Uli > > P.S.: > No guarantees that my description is correct, but this is how I understand it.
and you understood it perfectly :) -- To unsubscribe, send mail to [email protected].
