FL_KEYBOARD events have the correct x/y when sent to child X windows.

Notice that if you worked around this bug by adjusting the x/y yourself
you will have to change your code.

In addition all events have the correct x/y when sent to the grab()
widget.  And the code to do all this was simplified a lot.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.0@630 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Bill Spitzak 1999-07-22 21:37:04 +00:00
parent 0bb590c832
commit df045b0e36
3 changed files with 78 additions and 56 deletions

View File

@ -1,5 +1,5 @@
//
// "$Id: Fl.cxx,v 1.24.2.9 1999/06/07 07:03:31 bill Exp $"
// "$Id: Fl.cxx,v 1.24.2.10 1999/07/22 21:37:03 bill Exp $"
//
// Main event handling code for the Fast Light Tool Kit (FLTK).
//
@ -327,19 +327,8 @@ void Fl::belowmouse(Fl_Widget *o) {
}
}
// Because mouse events are posted to the outermost window we need to
// adjust them for child windows if they are pushed(). This should also
// be done for the focus() but that is nyi.
static int mouse_dx;
static int mouse_dy;
void Fl::pushed(Fl_Widget *o) {
pushed_ = o;
mouse_dx = 0;
mouse_dy = 0;
if (o) for (Fl_Widget* w = o; w->parent(); w = w->parent()) {
if (w->type()>=FL_WINDOW) {mouse_dx -= w->x(); mouse_dy -= w->y();}
}
}
Fl_Window *fl_xfocus; // which window X thinks has focus
@ -416,6 +405,22 @@ void fl_throw_focus(Fl_Widget *o) {
////////////////////////////////////////////////////////////////
// Call to->handle but first replace the mouse x/y with the correct
// values to account for nested X windows. 'window' is the outermost
// window the event was posted to by X:
static int send(int event, Fl_Widget* to, Fl_Window* window) {
int dx = window->x();
int dy = window->y();
for (const Fl_Widget* w = to; w; w = w->parent())
if (w->type()>=FL_WINDOW) {dx -= w->x(); dy -= w->y();}
int save_x = Fl::e_x; Fl::e_x += dx;
int save_y = Fl::e_y; Fl::e_y += dy;
int ret = to->handle(event);
Fl::e_y = save_y;
Fl::e_x = save_x;
return ret;
}
int Fl::handle(int event, Fl_Window* window)
{
Fl_Widget* w = window;
@ -438,22 +443,18 @@ int Fl::handle(int event, Fl_Window* window)
case FL_PUSH:
if (grab()) w = grab();
else if (modal() && w != modal()) return 0;
pushed_ = w; mouse_dx = mouse_dy = 0;
if (w->handle(event)) return 1;
pushed_ = w;
if (send(event, w, window)) return 1;
// raise windows that are clicked on:
window->show();
return 1;
case FL_MOVE:
case FL_DRAG:
// this should not happen if enter/leave events were reported
// correctly by the system, but just in case:
fl_xmousewin = window;
fl_xmousewin = window; // this should already be set, but just in case.
if (pushed()) {
w = pushed();
event = FL_DRAG;
e_x += mouse_dx;
e_y += mouse_dy;
} else if (modal() && w != modal()) {
w = 0;
}
@ -464,11 +465,9 @@ int Fl::handle(int event, Fl_Window* window)
if (pushed()) {
w = pushed();
pushed_ = 0; // must be zero before callback is done!
e_x += mouse_dx;
e_y += mouse_dy;
}
if (grab()) w = grab();
int r = w->handle(event);
int r = send(event, w, window);
fl_fix_focus();
return r;}
@ -481,21 +480,18 @@ int Fl::handle(int event, Fl_Window* window)
return 1;
case FL_KEYBOARD:
fl_xfocus = window; // this should already be set, but just in case.
// this should not happen if focus/unfocus events were reported
// correctly by the system, but just in case:
fl_xfocus = window;
// Try it as keystroke, sending it to focus and all parents:
for (w = grab() ? grab() : focus(); w; w = w->parent())
if (w->handle(FL_KEYBOARD)) return 1;
if (send(FL_KEYBOARD, w, window)) return 1;
// recursive call to try shortcut:
if (handle(FL_SHORTCUT, window)) return 1;
// and then try a shortcut with the case of the text swapped:
// and then try a shortcut with the case of the text swapped, by
// changing the text and falling through to FL_SHORTCUT case:
if (!isalpha(event_text()[0])) return 0;
// swap the case and fall through to FL_SHORTCUT case:
*(char*)(event_text()) ^= ('A'^'a');
event = FL_SHORTCUT;
@ -505,7 +501,7 @@ int Fl::handle(int event, Fl_Window* window)
// Try it as shortcut, sending to mouse widget and all parents:
w = belowmouse(); if (!w) {w = modal(); if (!w) w = window;}
for (; w; w = w->parent()) if (w->handle(FL_SHORTCUT)) return 1;
for (; w; w = w->parent()) if (send(FL_SHORTCUT, w, window)) return 1;
// try using add_handle() functions:
if (send_handlers(FL_SHORTCUT)) return 1;
@ -530,7 +526,7 @@ int Fl::handle(int event, Fl_Window* window)
default:
break;
}
if (w && w->handle(event)) return 1;
if (w && send(event, w, window)) return 1;
return send_handlers(event);
}
@ -698,5 +694,5 @@ int fl_old_shortcut(const char* s) {
}
//
// End of "$Id: Fl.cxx,v 1.24.2.9 1999/06/07 07:03:31 bill Exp $".
// End of "$Id: Fl.cxx,v 1.24.2.10 1999/07/22 21:37:03 bill Exp $".
//

View File

@ -1,5 +1,5 @@
//
// "$Id: Fl_Group.cxx,v 1.8.2.1 1999/07/22 07:27:11 bill Exp $"
// "$Id: Fl_Group.cxx,v 1.8.2.2 1999/07/22 21:37:03 bill Exp $"
//
// Group widget for the Fast Light Tool Kit (FLTK).
//
@ -399,7 +399,7 @@ void Fl_Group::resize(int X, int Y, int W, int H) {
Fl_Widget*const* a = array();
for (int i=children_; i--;) {
Fl_Widget* o = *a++;
#if 1
int X = *p++;
if (X >= IR) X += dw;
else if (X > IX) X = IX+((X-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX);
@ -413,7 +413,21 @@ void Fl_Group::resize(int X, int Y, int W, int H) {
int B = *p++;
if (B >= IB) B += dh;
else if (B > IY) B = IY+((B-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY);
#else // much simpler code from Francois Ostiguy:
int X = *p++;
if (X >= IR) X += dw;
else if (X > IX) X = X + dw * (X-IX)/(IR-IX);
int R = *p++;
if (R >= IR) R += dw;
else if (R > IX) R = R + dw * (R-IX)/(IR-IX);
int Y = *p++;
if (Y >= IB) Y += dh;
else if (Y > IY) Y = Y + dh*(Y-IY)/(IB-IY);
int B = *p++;
if (B >= IB) B += dh;
else if (B > IY) B = B + dh*(B-IY)/(IB-IY);
#endif
o->resize(X+dx, Y+dy, R-X, B-Y);
}
}
@ -489,5 +503,5 @@ void Fl_Group::draw_outside_label(const Fl_Widget& w) const {
}
//
// End of "$Id: Fl_Group.cxx,v 1.8.2.1 1999/07/22 07:27:11 bill Exp $".
// End of "$Id: Fl_Group.cxx,v 1.8.2.2 1999/07/22 21:37:03 bill Exp $".
//

View File

@ -1,5 +1,5 @@
//
// "$Id: subwindow.cxx,v 1.5.2.1 1999/04/19 07:01:24 bill Exp $"
// "$Id: subwindow.cxx,v 1.5.2.2 1999/07/22 21:37:04 bill Exp $"
//
// Nested window test program for the Fast Light Tool Kit (FLTK).
//
@ -37,23 +37,6 @@
#include <FL/Fl_Box.H>
#include <FL/Fl_Input.H>
class testwindow : public Fl_Window {
int handle(int);
void draw();
public:
testwindow(Fl_Boxtype b,int x,int y,const char *l)
: Fl_Window(x,y,l) {box(b);}
testwindow(Fl_Boxtype b,int x,int y,int w,int h,const char *l)
: Fl_Window(x,y,w,h,l) {box(b);}
};
void testwindow::draw() {
#ifdef DEBUG
printf("%s : draw\n",label());
#endif
Fl_Window::draw();
}
class EnterExit : public Fl_Box {
int handle(int);
public:
@ -90,17 +73,46 @@ const char *eventnames[] = {
};
#endif
Fl_Menu_Button* popup;
class testwindow : public Fl_Window {
int handle(int);
void draw();
int cx, cy; char key;
public:
testwindow(Fl_Boxtype b,int x,int y,const char *l)
: Fl_Window(x,y,l) {box(b); key = 0;}
testwindow(Fl_Boxtype b,int x,int y,int w,int h,const char *l)
: Fl_Window(x,y,w,h,l) {box(b); key = 0;}
};
#include <FL/fl_draw.H>
void testwindow::draw() {
#ifdef DEBUG
printf("%s : draw\n",label());
#endif
Fl_Window::draw();
if (key) fl_draw(&key, 1, cx, cy);
}
int testwindow::handle(int e) {
#ifdef DEBUG
if (e != FL_MOVE) printf("%s : %s\n",label(),eventnames[e]);
#endif
if (Fl_Window::handle(e)) return 1;
// if (e==FL_PUSH) return popup->handle(e);
if (e == FL_FOCUS) return 1;
if (e == FL_PUSH) {Fl::focus(this); return 1;}
if (e == FL_KEYBOARD && Fl::event_text()[0]) {
key = Fl::event_text()[0];
cx = Fl::event_x();
cy = Fl::event_y();
redraw();
return 1;
}
return 0;
}
Fl_Menu_Button* popup;
const char* bigmess =
#if 1
"this|is|only|a test"
@ -171,5 +183,5 @@ int main(int, char **) {
}
//
// End of "$Id: subwindow.cxx,v 1.5.2.1 1999/04/19 07:01:24 bill Exp $".
// End of "$Id: subwindow.cxx,v 1.5.2.2 1999/07/22 21:37:04 bill Exp $".
//