From fa29bbdc0f872bb739754ced1893e3529e9d9b12 Mon Sep 17 00:00:00 2001 From: Bill Spitzak Date: Sat, 10 Apr 1999 08:09:39 +0000 Subject: [PATCH] 1. ~Fl_Widget(), Fl_Widget::hide(), and Fl_Widget::deactivate() no longer send FL_LEAVE, FL_RELEASE, or FL_UNFOCUS events to the widget. This seems to be desirable behavior and fixes a crash in flwm. 2. After you show() a window, Fl::damage() should be true and remain true until the window is actually drawn and up to date. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.0@530 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl.cxx | 111 ++++++++++++++++++++++++++--------------------- src/Fl_grab.cxx | 8 ++-- src/Fl_win32.cxx | 6 +-- src/Fl_x.cxx | 7 ++- 4 files changed, 72 insertions(+), 60 deletions(-) diff --git a/src/Fl.cxx b/src/Fl.cxx index 032268a8c..9b03897d1 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl.cxx,v 1.24.2.2 1999/03/13 20:07:20 bill Exp $" +// "$Id: Fl.cxx,v 1.24.2.3 1999/04/10 08:09:38 bill Exp $" // // Main event handling code for the Fast Light Tool Kit (FLTK). // @@ -127,9 +127,14 @@ void Fl::flush() { if (damage()) { damage_ = 0; for (Fl_X* x = Fl_X::first; x; x = x->next) { - if (!x->wait_for_expose && x->w->damage() && x->w->visible()) { - x->flush(); - x->w->clear_damage(); + if (x->w->damage() && x->w->visible()) { + if (x->wait_for_expose) { + // leave Fl::damage() set so programs can tell damage still exists + damage_ = 1; + } else { + x->flush(); + x->w->clear_damage(); + } } } } @@ -335,27 +340,25 @@ void Fl::pushed(Fl_Widget *o) { } Fl_Window *fl_xfocus; // which window X thinks has focus -Fl_Window *fl_xmousewin; // which window X thinks has FL_ENTER +Fl_Window *fl_xmousewin;// which window X thinks has FL_ENTER Fl_Window *Fl::grab_; // most recent Fl::grab() -Fl_Window *Fl::modal_; +Fl_Window *Fl::modal_; // topmost modal() window -// Update modal(), focus() and other state according to system state. +// Update modal(), focus() and other state according to system state, +// and send FL_ENTER, FL_LEAVE, FL_FOCUS, and/or FL_UNFOCUS events. +// This is the only function that produces these events in response +// to system activity. // This is called whenever a window is added or hidden, and whenever -// X says the focus or mouse window have changed, and when grab_ is -// changed. +// X says the focus or mouse window have changed. + void fl_fix_focus() { if (Fl::grab()) return; // don't do anything while grab is on. - // set Fl::modal() based on any modal windows displayed: - Fl_Window* w = Fl::first_window(); - while (w && w->parent()) w = Fl::next_window(w); - Fl::modal_ = (w && w->modal()) ? w : 0; - // set focus based on Fl::modal() and fl_xfocus - w = fl_xfocus; - while (w && w->parent()) w = w->window(); + Fl_Widget* w = fl_xfocus; if (w) { + while (w->parent()) w = w->parent(); if (Fl::modal()) w = Fl::modal(); if (!w->contains(Fl::focus())) if (!w->take_focus()) Fl::focus(w); @@ -369,23 +372,45 @@ void fl_fix_focus() { if (w) { if (Fl::modal()) w = Fl::modal(); if (!w->contains(Fl::belowmouse())) { - Fl::belowmouse(w); w->handle(FL_ENTER);} - } else + Fl::belowmouse(w); + w->handle(FL_ENTER); + } else { + // send a FL_MOVE event so the enter/leave state is up to date + Fl::e_x = Fl::e_x_root-fl_xmousewin->x(); + Fl::e_y = Fl::e_y_root-fl_xmousewin->y(); + w->handle(FL_MOVE); + } + } else { Fl::belowmouse(0); + } } } +#ifndef WIN32 +Fl_Widget *fl_selection_requestor; // from Fl_cutpaste.C +#endif + +// This function is called by ~Fl_Widget() and by Fl_Widget::deactivate +// and by Fl_Widget::hide(). It indicates that the widget does not want +// to receive any more events, and also removes all global variables that +// point at the widget. +// I changed this from the 1.0.1 behavior, the older version could send +// FL_LEAVE or FL_UNFOCUS events to the widget. This appears to not be +// desirable behavior and caused flwm to crash. + +void fl_throw_focus(Fl_Widget *o) { + if (o->contains(Fl::pushed())) Fl::pushed_ = 0; + if (o->contains(Fl::selection_owner())) Fl::selection_owner_ = 0; +#ifndef WIN32 + if (o->contains(fl_selection_requestor)) fl_selection_requestor = 0; +#endif + if (o->contains(Fl::belowmouse())) Fl::belowmouse_ = 0; + if (o->contains(Fl::focus())) Fl::focus_ = 0; + fl_fix_focus(); +} + //////////////////////////////////////////////////////////////// -void fl_send_extra_move() { - // send a FL_MOVE event so the enter/leave state is up to date - if (fl_xmousewin && !Fl::grab()) { - Fl::e_x = Fl::e_x_root-fl_xmousewin->x(); - Fl::e_y = Fl::e_y_root-fl_xmousewin->y(); - fl_xmousewin->handle(FL_MOVE); - } -} - int Fl::handle(int event, Fl_Window* window) { Fl_Widget* w = window; @@ -440,7 +465,6 @@ int Fl::handle(int event, Fl_Window* window) if (grab()) w = grab(); int r = w->handle(event); fl_fix_focus(); - fl_send_extra_move(); return r;} case FL_UNFOCUS: @@ -490,8 +514,8 @@ int Fl::handle(int event, Fl_Window* window) return 0; case FL_ENTER: - fl_xmousewin = window; fl_fix_focus(); - fl_send_extra_move(); + fl_xmousewin = window; + fl_fix_focus(); return 1; case FL_LEAVE: @@ -508,8 +532,6 @@ int Fl::handle(int event, Fl_Window* window) //////////////////////////////////////////////////////////////// // hide() destroys the X window, it does not do unmap! -void fl_throw_focus(Fl_Widget*); // in Fl_x.C - void Fl_Window::hide() { clear_visible(); if (!shown()) return; @@ -531,6 +553,13 @@ void Fl_Window::hide() { } else w = w->next; } + if (this == Fl::modal_) { // we are closing the modal window, find next one: + Fl_Window* w; + for (w = Fl::first_window(); w; w = Fl::next_window(w)) + if (w->modal()) break; + Fl::modal_ = w; + } + // Make sure no events are sent to this window: if (this == fl_xmousewin) fl_xmousewin = 0; if (this == fl_xfocus) fl_xfocus = 0; @@ -583,22 +612,6 @@ void Fl::selection_owner(Fl_Widget *owner) { selection_owner_ = owner; } -#ifndef WIN32 -Fl_Widget *fl_selection_requestor; // from Fl_cutpaste.C -#endif - -void fl_throw_focus(Fl_Widget *o) { - if (o->contains(Fl::pushed())) Fl::pushed(0); - if (o->contains(Fl::selection_owner())) Fl::selection_owner(0); -#ifndef WIN32 - if (o->contains(fl_selection_requestor)) fl_selection_requestor = 0; -#endif - int fix = 0; - if (o->contains(Fl::belowmouse())) {Fl::belowmouse(0); fix = 1;} - if (o->contains(Fl::focus())) {Fl::focus(0); fix = 1;} - if (fix) fl_fix_focus(); -} - #include void Fl_Widget::redraw() {damage(FL_DAMAGE_ALL);} @@ -682,5 +695,5 @@ int fl_old_shortcut(const char* s) { } // -// End of "$Id: Fl.cxx,v 1.24.2.2 1999/03/13 20:07:20 bill Exp $". +// End of "$Id: Fl.cxx,v 1.24.2.3 1999/04/10 08:09:38 bill Exp $". // diff --git a/src/Fl_grab.cxx b/src/Fl_grab.cxx index 8626a7cf6..f6bfd5e30 100644 --- a/src/Fl_grab.cxx +++ b/src/Fl_grab.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_grab.cxx,v 1.1 1999/02/03 08:43:33 bill Exp $" +// "$Id: Fl_grab.cxx,v 1.1.2.1 1999/04/10 08:09:38 bill Exp $" // // Grab/release code for the Fast Light Tool Kit (FLTK). // @@ -35,7 +35,7 @@ // This also modifies how Fl_Window::show() works, on X it turns on // override_redirect, it does similar things on WIN32. -extern void fl_send_extra_move(); // in Fl.cxx +extern void fl_fix_focus(); // in Fl.cxx #ifdef WIN32 // We have to keep track of whether we have captured the mouse, since @@ -83,11 +83,11 @@ void Fl::grab(Fl_Window* w) { XFlush(fl_display); #endif grab_ = 0; - fl_send_extra_move(); + fl_fix_focus(); } } } // -// End of "$Id: Fl_grab.cxx,v 1.1 1999/02/03 08:43:33 bill Exp $". +// End of "$Id: Fl_grab.cxx,v 1.1.2.1 1999/04/10 08:09:38 bill Exp $". // diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index 36c0e24de..8f424b701 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_win32.cxx,v 1.33.2.4 1999/04/01 14:45:47 mike Exp $" +// "$Id: Fl_win32.cxx,v 1.33.2.5 1999/04/10 08:09:38 bill Exp $" // // WIN32-specific code for the Fast Light Tool Kit (FLTK). // @@ -733,7 +733,7 @@ Fl_X* Fl_X::make(Fl_Window* w) { ShowWindow(x->xid, fl_show_iconic ? SW_SHOWMINNOACTIVE : fl_capture? SW_SHOWNOACTIVATE : SW_SHOWNORMAL); fl_show_iconic = 0; - fl_fix_focus(); + if (w->modal()) {Fl::modal_ = w; fl_fix_focus();} return x; } @@ -905,5 +905,5 @@ void Fl_Window::make_current() { } // -// End of "$Id: Fl_win32.cxx,v 1.33.2.4 1999/04/01 14:45:47 mike Exp $". +// End of "$Id: Fl_win32.cxx,v 1.33.2.5 1999/04/10 08:09:38 bill Exp $". // diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index ceb847fd8..96f264646 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_x.cxx,v 1.24.2.1 1999/03/15 07:06:46 bill Exp $" +// "$Id: Fl_x.cxx,v 1.24.2.2 1999/04/10 08:09:39 bill Exp $" // // X specific code for the Fast Light Tool Kit (FLTK). // @@ -543,6 +543,7 @@ Fl_X* Fl_X::set_xid(Fl_Window* w, Window xid) { x->region = 0; x->wait_for_expose = 1; Fl_X::first = x; + if (w->modal()) {Fl::modal_ = w; fl_fix_focus();} return x; } @@ -628,8 +629,6 @@ void Fl_X::make_xid(Fl_Window* w, XVisualInfo *visual, Colormap colormap) w->set_visible(); w->handle(FL_SHOW); // get child windows to appear w->redraw(); - fl_fix_focus(); // if this is modal we must fix focus now - //XInstallColormap(fl_display, colormap); if (!w->parent() && !attr.override_redirect) { // Communicate all kinds 'o junk to the X Window Manager: @@ -824,5 +823,5 @@ void Fl_Window::make_current() { #endif // -// End of "$Id: Fl_x.cxx,v 1.24.2.1 1999/03/15 07:06:46 bill Exp $". +// End of "$Id: Fl_x.cxx,v 1.24.2.2 1999/04/10 08:09:39 bill Exp $". //