[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-dev] [PATCH] Make mouse events more responsive
From: |
Ivor Blockley |
Subject: |
[Gnash-dev] [PATCH] Make mouse events more responsive |
Date: |
Tue, 25 Jul 2006 22:54:22 +1000 (EST) |
Hi all,
Attached is a patch that fixes a bug with mouse-event handling.
The problem:
Rapid mouse clicking may result in some clicks not being honoured.
To demonstrate load
gnash/testsuite/actionscript.all/visible_and_transparency.swf and then rapidly
click one of the "Lower Alpha" buttons or rapidly hide and show the Primary
window via the "Hide
Primary" and "Show Primary" buttons. A double-clicking speed or faster is
required for repeatable
results.
The patch:
This patch resolves the problem by moving some of the mouse-event
generation/handling code outside
the "movie" loop. It has been tested as working under GTK and SDL and should
apply cleanly against
CVS.
Caveats:
* Is this solution thread-safe?
* I'm having problems building Klash and thus the patch has not been tested
under KDE (although I
believe it should work). I get the following error when I try to make Klash (on
an AMD64 Ubuntu
6.06[Dapper] system):
make[3]: *** No rule to make target `../../server/libgnashasobjs.la', needed by
`klash'. Stop.
I am working on another patch to resolve
https://savannah.gnu.org/bugs/?func=detailitem&item_id=16969 which will require
testing with
Klash. (PS: bug 16969 has been marked "Ready For Test" but the bug still exists
in CVS, as can be
demonstrated by re-sizing the GTK window for visible_and_transparency.swf and
then clicking on
some buttons).
The patch itself:
____________________________________________________
Index: gui/gtk.cpp
===================================================================
RCS file: /sources/gnash/gnash/gui/gtk.cpp,v
retrieving revision 1.13
diff -u -p -r1.13 gtk.cpp
--- gui/gtk.cpp 15 Jul 2006 16:02:23 -0000 1.13
+++ gui/gtk.cpp 25 Jul 2006 12:25:57 -0000
@@ -532,11 +532,11 @@ GtkGui::button_press_event(GtkWidget *co
Gui *obj = static_cast<Gui *>(data);
int mask = 1 << (event->button - 1);
int buttons = obj->getMouseButtons();
- obj->setMouseButtons(buttons |= mask);
+ buttons |= mask;
+ obj->setMouseButtons(buttons);
float scale = obj->getScale();
- obj->setMouseX(int(event->x / scale));
- obj->setMouseY(int(event->y / scale));
-
+ obj->notify_mouse_state(int(event->x / scale),
+ int(event->y / scale), buttons);
return true;
}
@@ -549,12 +549,11 @@ GtkGui::button_release_event(GtkWidget *
Gui *obj = static_cast<Gui *>(data);
int mask = 1 << (event->button - 1);
int buttons = obj->getMouseButtons();
-
- obj->setMouseButtons(buttons &= ~mask);
+ buttons &= ~mask;
+ obj->setMouseButtons(buttons);
float scale = obj->getScale();
- obj->setMouseX(int(event->x / scale));
- obj->setMouseY(int(event->y / scale));
-
+ obj->notify_mouse_state(int(event->x / scale),
+ int(event->y / scale), buttons);
return true;
}
@@ -567,9 +566,9 @@ GtkGui::motion_notify_event(GtkWidget *c
Gui *obj = static_cast<Gui *>(data);
float scale = obj->getScale();
- obj->setMouseX(int(event->x / scale));
- obj->setMouseY(int(event->y / scale));
-
+ int buttons = obj->getMouseButtons();
+ obj->notify_mouse_state(int(event->x / scale),
+ int(event->y / scale), buttons);
return true;
}
Index: gui/gui.cpp
===================================================================
RCS file: /sources/gnash/gnash/gui/gui.cpp,v
retrieving revision 1.10
diff -u -p -r1.10 gui.cpp
--- gui/gui.cpp 15 Jul 2006 16:02:23 -0000 1.10
+++ gui/gui.cpp 25 Jul 2006 12:25:57 -0000
@@ -57,8 +57,6 @@ Gui::Gui() :
_xid(0),
_width(0),
_height(0),
- _mouse_x(0),
- _mouse_y(0),
_scale(1.0f),
_mouse_buttons(0),
_depth(16)
@@ -74,8 +72,6 @@ Gui::Gui(unsigned long xid, float scale,
_xid(xid),
_width(0),
_height(0),
- _mouse_x(0),
- _mouse_y(0),
_scale(scale),
_mouse_buttons(0),
_depth(depth)
@@ -191,6 +187,12 @@ Gui::menu_jump_backward()
m->goto_frame(m->get_current_frame()-10);
}
+void
+Gui::notify_mouse_state(int x, int y, int buttons) {
+// log_msg("Mouse(x,y): %d,%d", x, y);
+ get_current_root()->notify_mouse_state(x, y, buttons);
+}
+
bool
Gui::advance_movie(void *data)
{
@@ -199,9 +201,6 @@ Gui::advance_movie(void *data)
Gui *gui = reinterpret_cast<Gui*> (data);
gnash::movie_interface* m = gnash::get_current_root();
-// log_msg("Mouse(x,y): %d,%d", gui->getMouseX(), gui->getMouseY());
- m->notify_mouse_state(gui->getMouseX(), gui->getMouseY(),
gui->getMouseButtons());
-
m->advance(1.0);
m->display();
Index: gui/gui.h
===================================================================
RCS file: /sources/gnash/gnash/gui/gui.h,v
retrieving revision 1.7
diff -u -p -r1.7 gui.h
--- gui/gui.h 15 Jul 2006 16:02:23 -0000 1.7
+++ gui/gui.h 25 Jul 2006 12:25:57 -0000
@@ -70,11 +70,7 @@ public:
virtual bool setupEvents() = 0;
virtual void renderBuffer() = 0;
- void setMouseX(int x) { _mouse_x = x; }
- void setMouseY(int y) { _mouse_y= y; }
void setMouseButtons(int mask) { _mouse_buttons = mask; }
- int getMouseX() { return _mouse_x; }
- int getMouseY() { return _mouse_y; }
int getMouseButtons() { return _mouse_buttons; }
float getScale() { return _scale; }
bool loops() { return _loop; }
@@ -92,6 +88,7 @@ public:
static void menu_step_backward();
static void menu_jump_forward();
static void menu_jump_backward();
+ static void notify_mouse_state(int x, int y, int buttons);
static bool advance_movie(void *data);
static void resize_view(int width, int height);
@@ -100,8 +97,6 @@ protected:
unsigned long _xid;
int _width;
int _height;
- int _mouse_x;
- int _mouse_y;
float _scale;
int _mouse_buttons;
int _depth;
Index: gui/sdl.cpp
===================================================================
RCS file: /sources/gnash/gnash/gui/sdl.cpp,v
retrieving revision 1.9
diff -u -p -r1.9 sdl.cpp
--- gui/sdl.cpp 15 Jul 2006 16:02:23 -0000 1.9
+++ gui/sdl.cpp 25 Jul 2006 12:25:57 -0000
@@ -62,6 +62,8 @@ SDLGui::SDLGui(unsigned long xid, float
: Gui(xid, scale, loop, depth),
_timeout(0),
_core_trap(true),
+ _mouse_x(0),
+ _mouse_y(0),
_func(advance_movie)
{
@@ -84,6 +86,9 @@ bool
SDLGui::run(void *arg)
{
GNASH_REPORT_FUNCTION;
+ int x_old = -1;
+ int y_old = -1;
+ int button_state_old = -1;
SDL_Event event;
while (true) {
@@ -97,18 +102,29 @@ SDLGui::run(void *arg)
switch (event.type) {
case SDL_MOUSEMOTION:
+ // SDL can generate MOUSEMOTION events even without mouse movement
+ if (event.motion.x == x_old && event.motion.y == y_old) { break; }
_mouse_x = (int) (event.motion.x / _scale);
_mouse_y = (int) (event.motion.y / _scale);
+ notify_mouse_state(_mouse_x, _mouse_y, _mouse_buttons);
+ x_old = event.motion.x;
+ y_old = event.motion.y;
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
int mask = 1 << (event.button.button - 1);
if (event.button.state == SDL_PRESSED) {
+ // multiple events will be fired while the mouse is held down
+ // we are interested only in a change in the mouse state:
+ if (event.button.button == button_state_old) { break; }
_mouse_buttons |= mask;
+ button_state_old = event.button.button;
} else {
_mouse_buttons &= ~mask;
+ button_state_old = -1;
}
+ notify_mouse_state(_mouse_x, _mouse_y, _mouse_buttons);
break;
}
case SDL_KEYDOWN:
Index: gui/sdlsup.h
===================================================================
RCS file: /sources/gnash/gnash/gui/sdlsup.h,v
retrieving revision 1.7
diff -u -p -r1.7 sdlsup.h
--- gui/sdlsup.h 15 Jul 2006 16:02:23 -0000 1.7
+++ gui/sdlsup.h 25 Jul 2006 12:25:57 -0000
@@ -72,6 +72,7 @@ public:
virtual void setTimeout(unsigned int timeout);
private:
unsigned int _interval, _timeout;
+ int _mouse_x, _mouse_y;
callback_t _func;
SDL_Surface *_screen;
#ifdef RENDERER_CAIRO
Index: server/movie_root.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.cpp,v
retrieving revision 1.7
diff -u -p -r1.7 movie_root.cpp
--- server/movie_root.cpp 10 Jul 2006 13:47:12 -0000 1.7
+++ server/movie_root.cpp 25 Jul 2006 12:26:01 -0000
@@ -125,6 +125,12 @@ movie_root::notify_mouse_state(int x, in
m_mouse_x = x;
m_mouse_y = y;
m_mouse_buttons = buttons;
+
+ // Generate a mouse event
+ m_mouse_button_state.m_topmost_entity =
+ m_movie->get_topmost_mouse_entity(PIXELS_TO_TWIPS(m_mouse_x),
PIXELS_TO_TWIPS(m_mouse_y));
+ m_mouse_button_state.m_mouse_button_state_current = (m_mouse_buttons & 1);
+ generate_mouse_button_events(&m_mouse_button_state);
}
void
@@ -219,12 +225,6 @@ movie_root::advance(float delta_time)
}
}
- // Handle the mouse.
- m_mouse_button_state.m_topmost_entity =
- m_movie->get_topmost_mouse_entity(PIXELS_TO_TWIPS(m_mouse_x),
PIXELS_TO_TWIPS(m_mouse_y));
- m_mouse_button_state.m_mouse_button_state_current = (m_mouse_buttons & 1);
- generate_mouse_button_events(&m_mouse_button_state);
-
// m_movie->advance(delta_time);
// Vitaly:
____________________________________________________
Send instant messages to your online friends http://au.messenger.yahoo.com
- [Gnash-dev] [PATCH] Make mouse events more responsive,
Ivor Blockley <=