On 21.04.2012 09:09, Anurag Priyam wrote: > On Sat, Apr 21, 2012 at 9:20 AM, dodo <dodo.the.l...@googlemail.com> 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. -- "Engineering - where the semi-skilled laborers execute the vision of those who think and dream. Hello Oompa-Loompas of science." -- To unsubscribe, send mail to awesome-devel-unsubscr...@naquadah.org.