Subject: bug in module command queue

From: Dominik Vogt <[email-masked]>
Date: Mon, 15 May 2000 23:52:10 +0200

Tim, as far as I can see the module command queue is working
well except for one thing.  When a module sends a command
it is put in the queue.  Then, after the event loop has
cleaned up all pending events, My_XNextEvent finally reaches
line 2148:

  ExecuteCommandQueue();

Some of the commands that are executed trigger new X events,
but the function continues until it reaches the select call:

  if (fvwmSelect(fd_width, &in_fdset, &out_fdset, 0, timeoutP) > 0) {

Now we have X events pending, but fvwm hangs in the select()
call and waits for module input.  I have made a patch that
simply exits Mx_XNextEvent() if the command queue was not
empty in ExecuteCommandQueue().  This seems to fix the problem.

What I do not understand is why select() hangs at all.  The
x_fd is part of the in_fdset, but still it does not trigger the
select() call - even though there are pending events.

Bye

Dominik ^_^

--
Dominik Vogt, [email-masked]
Reply-To: [email-masked]
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]

---

From: Tim Phipps <[email-masked]>
Date: Tue, 16 May 2000 08:40:22 +0100

> Some of the commands that are executed trigger new X events,

Doh!

> select() call - even though there are pending events.

There is no XFlush() after ExecuteModuleCommand(). XPending() does an
XFlush() if there is nothing in the X event queue so your fix of
re-entering My_XNextEvent() works by running the first XPending() again.

I'll have another look at My_XNextEvent() and see if I can streamline it
a bit.

Cheers,
Tim.

---

From: Tim Phipps <[email-masked]>
Date: Tue, 16 May 2000 09:15:22 +0100

> re-entering My_XNextEvent() works by running the first XPending() again.

Double Doh! It's an XPending that's missing after the
ExecuteModuleCommand().  There's already an XFlush() before the select
but if ExecuteModuleCommand() runs an X command that needs a server
response (like XGetGeometry()) there will be XEvents waiting in the X
queue. The select will block until a new event turns up.

Cheers,
Tim.

---

From: Dominik Vogt <[email-masked]>
Date: Tue, 16 May 2000 16:04:39 +0200

> queue. The select will block until a new event turns up.

Hm, if I understand that correctly, if I change this code:

  if (ExecuteCommandQueue())
  {
    return 0;
  }

to this:

  if (ExecuteCommandQueue())
  {
    XPending(dpy);
  }

It should work too.  Right?  Unfortunately that is not the case,
not even if I add 'Xsync(dpy, 0);' after the XPending() call.
I really don't understand why the select() does not return when 
new events are pending.

BTW, you can easily verify it yourself if you use the

  *FvwmPagerSloppyFocus

option.  Simply point at an unfocused window in the pager.  It
will gain focus only after you *leave* the window, not when you
enter it.

Bye

Dominik ^_^

-- 
Dominik Vogt, Agilent Technologies, Dept. BVS
Herrenberger Str.130, 71034 Boeblingen, Germany
phone: 07031/464-4596, fax: 07031/464-3883, [email-masked]
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]

---

From: Tim Phipps <[email-masked]>
Date: Wed, 17 May 2000 10:29:14 +0100

> It should work too.  Right?  Unfortunately that is not the case,

it should be 
    if (XPending(dpy)
    {
      XNextEvent(dpy,event);
      StashEventTime(event);
      return 1;
    }
  }

This is a duplicate of the code before the ExecuteCommandQueue(). Now
that module command queueing only happens in My_XNextEvent it is
possible to move the ExecuteCommandQueue to happen after the select()
rather than before. The queue only gets command added to it after the
select and is immediately emptied.  I've committed this change. I've
also added an extra test for X events after the select as a tune up.

Cheers,
Tim.

---

From: Dominik Vogt <[email-masked]>
Date: Wed, 17 May 2000 10:33:35 +0200

Tim, I am not sure I understand your latest patch correctly.
Isn't is now the other way round: queued commands won't be
executed unless a new X event comes in?  I.e. if a module
issues a command that gets queued, but no X event follows,
the select() will not trigger ExecuteCommandQueue()?  I have
no time to try this out right now.

Bye

Dominik ^_^

---

From: Tim Phipps <[email-masked]>
Date: Wed, 17 May 2000 13:50:48 +0100

Dominik Vogt wrote:
> executed unless a new X event comes in?

Nope. The module command queue is always empty when the routine is
entered, if there are no X events queued up select() is called which
blocks until something happens (X event or module command arrives).
After any module commands are put in the queue the commands in the queue
is emptied. There is no way to exit the routine without an empty module
command queue. A simplified version of the routine follows:

int MyXNextEvent()
{
  if (XPending())
  {
    get next event
    return 1
  }

  select(all_inputs and all_outputs)

  for all modules
  {
    if (input from module ready)
    {
      add module command to queue
    }
    if (output to module ready)
    {
      write message to module
    }
  }

  execute all the modules commands from the queue

  if (XPending())
  {
    get next event
    return 1
  }

  return 0
}

Cheers,
Tim.