Subject: Wait in functions is broken

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 8 May 2001 21:58:24 +0000

I don't know when this started.

  AddToFunc TestFunction I Wait "unexisting window"
  TestFunction

Now, click or drag using the mouse anywhere. Woops, mouse is mostly
locked. The keyboard works well (did I say something similar before?),
so you may quit this mode by pressing Ctrl-Alt-Escape.

Regards,
Mikhael.
--
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: Dominik Vogt <[email-masked]>
Date: Wed, 9 May 2001 01:48:44 +0200

> so you may quit this mode by pressing Ctrl-Alt-Escape.

That's not really new.  This was always the case if the function
used anything else but 'I'.  I don't know what to do about that.
The pointer must be grabbed during function execution for the
reasons I explained in the thread with Paul's deiconify problem.

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: Wed, 09 May 2001 10:29:16 +0100

> reasons I explained in the thread with Paul's deiconify problem.

I think something is going wrong. With this function everything seems
fine except when a window closes (ctrl-d in xterm). The application
window goes away but the fvwm frame remains. EscapeFunc causes the frame
to go away. I played around with this a bit and by running the function,
createing two windows, closing them, switching desks and hitting the key
that does EsacpeFunc I got the following core dump:

#0  0x39568 in remove_window_from_stack_ring (t=0xc4600) at stack.c:170
170       t->stack_prev->stack_next = t->stack_next;
(gdb) where
#0  0x39568 in remove_window_from_stack_ring (t=0xc4600) at stack.c:170
#1  0x39e40 in RaiseOrLowerWindow (t=0xc4600, do_lower=0, 
    allow_recursion=1, is_new_window=0) at stack.c:598
#2  0x3a0d8 in RaiseWindow (t=0xc4600) at stack.c:746
#3  0x309ec in warp_to_fvwm_window (eventp=0x86900, t=0xc4600, 
    warp_x=35, x_unit=100, warp_y=50, y_unit=100) at focus.c:489
#4  0x30bb8 in CMD_WarpToWindow (eventp=0x86900, w=0, tmp_win=0xc4600, 
    context=1, action=0xc0e4d "35p 50p", Module=0xefffd6dc)
    at focus.c:532
#5  0x4b55c in execute_function (efa=0xefffd6c8) at functions.c:1091
#6  0x4b6f0 in old_execute_function (
    action=0xc1556 " WarpToWindow 35p 50p", tmp_win=0xc4600, 
    eventp=0x86900, context=1, Module=-1, exec_flags=0 '\000', 
    args=0x85400) at functions.c:1160
#7  0x436d4 in CMD_Current (eventp=0x86900, w=54, tmp_win=0x0, 
    context=8, action=0xc1548 "(!FvwmButtons) WarpToWindow 35p 50p", 
    Module=0xefffd89c) at conditional.c:482
#8  0x4b55c in execute_function (efa=0xefffd888) at functions.c:1091
#9  0x4b6f0 in old_execute_function (
    action=0x9c970 "Current (!FvwmButtons) WarpToWindow 35p 50p", 
    tmp_win=0x0, eventp=0x86900, context=8, Module=-1, 
    exec_flags=0 '\000', args=0x85400) at functions.c:1160
#10 0x4c16c in execute_complex_function (eventp=0x86900, w=0, 
    tmp_win=0x0, context=8, action=0x85400 "", Module=0xefffdafc, 
    desperate=0x9bba0) at functions.c:1654
#11 0x4b5b0 in execute_function (efa=0xefffdae8) at functions.c:1108
#12 0x4b6f0 in old_execute_function (action=0x9f288 "my_cursorwarp", 
    tmp_win=0x0, eventp=0x86900, context=8, Module=-1, 
    exec_flags=0 '\000', args=0x85400) at functions.c:1160
#13 0x4c16c in execute_complex_function (eventp=0x86900, w=0, 
    tmp_win=0x0, context=8, action=0x85400 "", Module=0xefffdd5c, 
    desperate=0x9f0b0) at functions.c:1654
#14 0x4b5b0 in execute_function (efa=0xefffdd48) at functions.c:1108
#15 0x4b6f0 in old_execute_function (
    action=0xefffde68 " my_destroy_event 0xa400003", tmp_win=0x0, 
    eventp=0x86900, context=8, Module=6, exec_flags=0 '\000', 
    args=0x85400) at functions.c:1160
#16 0x37730 in ExecuteModuleCommand (w=0, module=6, 
    text=0xefffde68 " my_destroy_event 0xa400003")
    at module_interface.c:641
#17 0x37618 in HandleModuleInput (w=0, module=6, 
    expect=0x74418 "NOP UNLOCK", queue=0) at module_interface.c:606
#18 0x38a2c in PositiveWrite (module=6, ptr=0x0, size=4194304)
    at module_interface.c:1353
#19 0x37af8 in BroadcastPacket (event_type=6, num_datum=7)
    at module_interface.c:842
#20 0x5aaf8 in destroy_window (tmp_win=0xc4600) at add_window.c:1969
#21 0x57a00 in destroy_scheduled_windows () at update.c:310
#22 0x3f790 in HandleEvents () at events.c:2797
#23 0x608f8 in main (argc=1, argv=0xefffee04) at fvwm.c:742
(gdb) print t->stack_next
$1 = (struct FvwmWindow *) 0x0
(gdb) print t->stack_prev
$2 = (struct FvwmWindow *) 0x0

I use some weird functions driven by FvwmEvent to warp the pointer back
to the focussed window when a window dies which might have something to
do with it, I don't see the wait cursor like I should.

Cheers,
Tim.

---

From: Mikhael Goikhman <[email-masked]>
Date: Wed, 9 May 2001 23:12:26 +0000

> reasons I explained in the thread with Paul's deiconify problem.

I think I see this thread and I can't find where is explained why the
cursor grabbing is needed. What is the date of the message you mention?

This locked cursor behaviour is not good. Wait is mostly used in "I"
functions. It is used in many places, including fvwm-themes, FVWM FAQ.

In any case I think Wait command may have additional optional parameter
"timeout" and probably one more optional parameter "timeout-command".
And we should have a built-in command Break, which finishes a function,
it may be used in Wait's "timeout-command" or in conditional commands.

Regards,
Mikhael.

---

From: Dominik Vogt <[email-masked]>
Date: Thu, 10 May 2001 12:35:27 +0200

On Wed, May 09, 2001 at 11:12:26PM +0000, Mikhael Goikhman wrote:
> cursor grabbing is needed.

>From the ChangeLog:

  2001-03-22  Dominik Vogt  <[email-masked]>

    * fvwm/functions.c (execute_complex_function):
    fixed button presses being passed to other applications with functions
    that only have immediate actions

> What is the date of the message you mention?

I think I messed up the mails.

> functions. It is used in many places, including fvwm-themes, FVWM FAQ.

No, it's not good at all.

Bye

Dominik ^_^  ^_^

--
Dominik Vogt, email: [email-masked]
LifeBits Aktiengesellschaft, Albrechtstr. 9, D-72072 Tuebingen
fon: ++49 (0) 7071/7965-0, fax: ++49 (0) 7071/7965-20
--
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: Mikhael Goikhman <[email-masked]>
Date: Fri, 18 May 2001 18:01:03 +0000

> No, it's not good at all.

So, what do we do about this? A possible solution is to ungrab cursor
before some commands (Wait) and then grab again. If there is no solution,
I think we should disable this commit, because it is problematic. I run a
version with this commit disabled during a week now, so I may do it.

Regards,
Mikhael.

---

From: Dominik Vogt <[email-masked]>
Date: Mon, 21 May 2001 13:00:25 +0200

> version with this commit disabled during a week now, so I may do it.

I have been thinking about this a lot.  The main problem is the
way 'Wait' is implemented at all.  The man page claims that fvwm
stays fully functional during a wait which has not been true for a
long time.  The wait function implements its own inferior version
of the event loop which will fail in a lot of cases.  For example
it does not handle the module queue properly, so modules are not
able to issue commands during a wait.  Furthermore it expects that
DispatchEvent() never handles more than one event.  This may be
true for MapNotify at the moment, but if HandleMapNotify() would
ever check for a matching DestroyNotify() in the future, 'Wait'
might miss the MapNotify and hang forever.

This solution will work, but it's not trivial to implement:

 1) When 'Wait' is called, it inserts the information about the
    window to wait for in a table.
 2) 'Wait' returns immediately.  It does not do any event handling.
 3) 'Wait' has a special flag in the function table that tells
    execute_function() to return immediately without finishing
    the function.  Instead it builds a new function with the rest
    of the actions that would have to be taken as soon as the
    window appears.  Then it returns and tells the function from
    which it was called to do the same.
 4) Finally, function execution ends with a more or less long list
    of pending commands.  The cursor is ungrabbed and fvwm resumes
    execution in the normal event loop.
 5) Whenever a new window is mapped, fvwm checks the list of
    pending waits for a matching window.  For the first matching
    window it executes the recorded function and deletes it after
    execution.

There are still some problems in this solution that would have to
be solved:

 a) How can ctrl-alt-escape be implemented?
 b) How can the busy cursor be implemented?
 c) What happens to function parameters?  When leaving the current
    function they have to be recorded in some way.  One way would
    be to store them in the recorded function somehow (new
    command?)  Alternatively the commands could be executed as
    usual but instead of executing them the string that would have
    been executed is recorded.

Bye

Dominik ^_^  ^_^

---

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 29 May 2001 14:28:11 +0000

>     been executed is recorded.

Dominik, do you work on this now? I think this is a good solution, but
it requires so many changes in several places that we may need 2.3.33.

Can we restore the previous behaviour of Wait in "I" functions now and
release 2.4.0? And this solution may be implemented in 2.4.1 or similar.

I think we don't need to fork to 2.5.0/2.9.0 (which is going to be
incompatible) immediately after 2.4.0, this may be done later in 2.4.x.

Regards,
Mikhael.

---

From: Dominik Vogt <[email-masked]>
Date: Tue, 29 May 2001 17:00:24 +0200

> Dominik, do you work on this now? I think this is a good solution, but

No, I didn't dare to start this.  Of course it would be much
cleaner to dump backwards compatibility and make the 'Wait'
command take the name of a function as an argument instead of
collecting commands when it is called.

> it requires so many changes in several places that we may need 2.3.33.

We'll need a 2.3.33 anyway.

> release 2.4.0? And this solution may be implemented in 2.4.1 or similar.

How about this:

 1) I'll implement a new wait syntax that takes a function name
    to execute with all the stuf necessary to maintain a list of
    waits.  Perhaps the id of the new window could even be passed
    into the function.
 2) The current wait is kept exactly as it is now but we'll ungrab
    the pointer during execution.  This will break 'I'-only
    functions in a few cases and will not work well if the pointer
    was grabbed multiple times when the wait was called.
 3) The paragraph claiming that "Fvwm remains fully functional
    during a wait" is scrapped.  It has never been true and will
    never be true with the old syntax.  Only the new syntax can do
    this.
 4) A warning in the conversion tool is added.
 5) Anybody complaining about this will have to use the new
    syntax.
 6) Unless someone else comes up with a good idea, the busy cursor
    feature in waits is dropped for now.

Bye

Dominik ^_^  ^_^

---

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 29 May 2001 16:04:26 +0000

> We'll need a 2.3.33 anyway.

Ok, but whoever builds it should use "make_fvwmdist.sh -r -M" to ensure we
don't have 2.3.34.

>     feature in waits is dropped for now.

What would be a problem with the busy cursor in the new implementation?
When a total Wait counter is 0 the normal root cursor may be restored.

(2) is needed, but are other items are needed for 2.4.0? If Wait worked
badly in 2.2.x and users didn't complain, maybe this was enough?
We may even add (2.5) Re-set $w or a new variable $m after Wait.

If I understand you correctly, the new non-blocking Wait has the syntax:

  Wait "window-name" callback-function

If we already do this, I would extend it to:

  Wait "window-name" callback-function [timeout [timeout-function]]

and EscapeFunc may trigger timeout-function too if the last is defined.

I have no problem if this new syntax is implemented after 2.4.0.
but I will support your decision.

Regards,
Mikhael.

---

From: Dominik Vogt <[email-masked]>
Date: Tue, 29 May 2001 21:00:35 +0200

> When a total Wait counter is 0 the normal root cursor may be restored.

I thought that the pointer has to be grabbed to change the cursor.
This is nonsese, of course.

> We may even add (2.5) Re-set $w or a new variable $m after Wait.

I've coded this with little effort.  Still, windows can't be
destroyed while the function in running, so I added a patch that
at least unmaps a window in DestroyWindow() when it can not be
destroyed immediately.  I hope this does not break someathing
else.

>   Wait "window-name" callback-function

Yes, something like this.  Perhaps a new name for the command
would be better to stress that the syntax has changed radically.
For example "WaitForWindow".

> and EscapeFunc may trigger timeout-function too if the last is defined.

I think this would be a bit cleaner:

  Wait [timeout <secs>] [timeoutcommand command] command window-name
 
> but I will support your decision.

The 'fix' works for me at the moment, so the final solution can
wait.  If too many people complain we may have to provide the new
syntax soon after 2.4.

Bye

Dominik ^_^  ^_^