gnash-dev
[Top][All Lists]
Advanced

[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 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]