mirror of https://github.com/fltk/fltk
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:
parent
0bb590c832
commit
df045b0e36
60
src/Fl.cxx
60
src/Fl.cxx
|
@ -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).
|
// 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) {
|
void Fl::pushed(Fl_Widget *o) {
|
||||||
pushed_ = 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
|
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)
|
int Fl::handle(int event, Fl_Window* window)
|
||||||
{
|
{
|
||||||
Fl_Widget* w = window;
|
Fl_Widget* w = window;
|
||||||
|
@ -438,22 +443,18 @@ int Fl::handle(int event, Fl_Window* window)
|
||||||
case FL_PUSH:
|
case FL_PUSH:
|
||||||
if (grab()) w = grab();
|
if (grab()) w = grab();
|
||||||
else if (modal() && w != modal()) return 0;
|
else if (modal() && w != modal()) return 0;
|
||||||
pushed_ = w; mouse_dx = mouse_dy = 0;
|
pushed_ = w;
|
||||||
if (w->handle(event)) return 1;
|
if (send(event, w, window)) return 1;
|
||||||
// raise windows that are clicked on:
|
// raise windows that are clicked on:
|
||||||
window->show();
|
window->show();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case FL_MOVE:
|
case FL_MOVE:
|
||||||
case FL_DRAG:
|
case FL_DRAG:
|
||||||
// this should not happen if enter/leave events were reported
|
fl_xmousewin = window; // this should already be set, but just in case.
|
||||||
// correctly by the system, but just in case:
|
|
||||||
fl_xmousewin = window;
|
|
||||||
if (pushed()) {
|
if (pushed()) {
|
||||||
w = pushed();
|
w = pushed();
|
||||||
event = FL_DRAG;
|
event = FL_DRAG;
|
||||||
e_x += mouse_dx;
|
|
||||||
e_y += mouse_dy;
|
|
||||||
} else if (modal() && w != modal()) {
|
} else if (modal() && w != modal()) {
|
||||||
w = 0;
|
w = 0;
|
||||||
}
|
}
|
||||||
|
@ -464,11 +465,9 @@ int Fl::handle(int event, Fl_Window* window)
|
||||||
if (pushed()) {
|
if (pushed()) {
|
||||||
w = pushed();
|
w = pushed();
|
||||||
pushed_ = 0; // must be zero before callback is done!
|
pushed_ = 0; // must be zero before callback is done!
|
||||||
e_x += mouse_dx;
|
|
||||||
e_y += mouse_dy;
|
|
||||||
}
|
}
|
||||||
if (grab()) w = grab();
|
if (grab()) w = grab();
|
||||||
int r = w->handle(event);
|
int r = send(event, w, window);
|
||||||
fl_fix_focus();
|
fl_fix_focus();
|
||||||
return r;}
|
return r;}
|
||||||
|
|
||||||
|
@ -481,21 +480,18 @@ int Fl::handle(int event, Fl_Window* window)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case FL_KEYBOARD:
|
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:
|
// Try it as keystroke, sending it to focus and all parents:
|
||||||
for (w = grab() ? grab() : focus(); w; w = w->parent())
|
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:
|
// recursive call to try shortcut:
|
||||||
if (handle(FL_SHORTCUT, window)) return 1;
|
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;
|
if (!isalpha(event_text()[0])) return 0;
|
||||||
|
|
||||||
// swap the case and fall through to FL_SHORTCUT case:
|
|
||||||
*(char*)(event_text()) ^= ('A'^'a');
|
*(char*)(event_text()) ^= ('A'^'a');
|
||||||
event = FL_SHORTCUT;
|
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:
|
// Try it as shortcut, sending to mouse widget and all parents:
|
||||||
w = belowmouse(); if (!w) {w = modal(); if (!w) w = window;}
|
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:
|
// try using add_handle() functions:
|
||||||
if (send_handlers(FL_SHORTCUT)) return 1;
|
if (send_handlers(FL_SHORTCUT)) return 1;
|
||||||
|
@ -530,7 +526,7 @@ int Fl::handle(int event, Fl_Window* window)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (w && w->handle(event)) return 1;
|
if (w && send(event, w, window)) return 1;
|
||||||
return send_handlers(event);
|
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 $".
|
||||||
//
|
//
|
||||||
|
|
|
@ -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).
|
// 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();
|
Fl_Widget*const* a = array();
|
||||||
for (int i=children_; i--;) {
|
for (int i=children_; i--;) {
|
||||||
Fl_Widget* o = *a++;
|
Fl_Widget* o = *a++;
|
||||||
|
#if 1
|
||||||
int X = *p++;
|
int X = *p++;
|
||||||
if (X >= IR) X += dw;
|
if (X >= IR) X += dw;
|
||||||
else if (X > IX) X = IX+((X-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX);
|
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++;
|
int B = *p++;
|
||||||
if (B >= IB) B += dh;
|
if (B >= IB) B += dh;
|
||||||
else if (B > IY) B = IY+((B-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY);
|
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);
|
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 $".
|
||||||
//
|
//
|
||||||
|
|
|
@ -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).
|
// Nested window test program for the Fast Light Tool Kit (FLTK).
|
||||||
//
|
//
|
||||||
|
@ -37,23 +37,6 @@
|
||||||
#include <FL/Fl_Box.H>
|
#include <FL/Fl_Box.H>
|
||||||
#include <FL/Fl_Input.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 {
|
class EnterExit : public Fl_Box {
|
||||||
int handle(int);
|
int handle(int);
|
||||||
public:
|
public:
|
||||||
|
@ -90,17 +73,46 @@ const char *eventnames[] = {
|
||||||
};
|
};
|
||||||
#endif
|
#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) {
|
int testwindow::handle(int e) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (e != FL_MOVE) printf("%s : %s\n",label(),eventnames[e]);
|
if (e != FL_MOVE) printf("%s : %s\n",label(),eventnames[e]);
|
||||||
#endif
|
#endif
|
||||||
if (Fl_Window::handle(e)) return 1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Fl_Menu_Button* popup;
|
||||||
|
|
||||||
const char* bigmess =
|
const char* bigmess =
|
||||||
#if 1
|
#if 1
|
||||||
"this|is|only|a test"
|
"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 $".
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue