]> git.sesse.net Git - vlc/commitdiff
Fixed fullscreen controler race conditions and ugly static variables.
authorLaurent Aimar <fenrir@videolan.org>
Tue, 15 Jul 2008 19:29:54 +0000 (21:29 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Tue, 15 Jul 2008 19:31:50 +0000 (21:31 +0200)
It is disabled by default, look for the two lines with
//XXX uncomment for fullscreen controler
to enable it. Please report success/failure in order to enable it by
default (linux/win32).

modules/gui/qt4/components/interface_widgets.cpp
modules/gui/qt4/components/interface_widgets.hpp
modules/gui/qt4/input_manager.cpp
modules/gui/qt4/input_manager.hpp
modules/gui/qt4/main_interface.cpp

index 384d9db16a528098855e48c3bb5fda28138a9ded..6a8f8ace5e5a53b9e4729e5a920238700978b66b 100644 (file)
@@ -887,8 +887,9 @@ void ControlsWidget::toggleAdvanced()
 FullscreenControllerWidget::FullscreenControllerWidget( intf_thread_t *_p_i,
         MainInterface *_p_mi, bool b_advControls, bool b_shiny )
         : ControlsWidget( _p_i, _p_mi, b_advControls, b_shiny, true ),
-        i_lastPosX( -1 ), i_lastPosY( -1 ), i_hideTimeout( 1 ),
-        b_mouseIsOver( false ), b_isFullscreen( false )
+          i_mouse_last_x( -1 ), i_mouse_last_y( -1 ), b_mouse_over(false),
+          b_slow_hide_begin(false), i_slow_hide_timeout(1),
+          b_fullscreen( false ), i_hide_timeout( 1 )
 {
     setWindowFlags( Qt::ToolTip );
 
@@ -922,7 +923,7 @@ FullscreenControllerWidget::FullscreenControllerWidget( intf_thread_t *_p_i,
 
     /* hiding timer */
     p_hideTimer = new QTimer( this );
-    CONNECT( p_hideTimer, timeout(), this, hideFSControllerWidget() );
+    CONNECT( p_hideTimer, timeout(), this, hideFSC() );
     p_hideTimer->setSingleShot( true );
 
     /* slow hiding timer */
@@ -939,15 +940,42 @@ FullscreenControllerWidget::FullscreenControllerWidget( intf_thread_t *_p_i,
     move( p_desktop->width() / 2 - width() / 2,
           p_desktop->height() - height() );
 
-    #ifdef WIN32TRICK
+#ifdef WIN32TRICK
     setWindowOpacity( 0.0 );
     fscHidden = true;
     show();
-    #endif
+#endif
+
+    vlc_mutex_init_recursive( &lock );
 }
 
 FullscreenControllerWidget::~FullscreenControllerWidget()
 {
+    vlc_mutex_destroy( &lock );
+}
+
+/**
+ * Show fullscreen controller
+ */
+void FullscreenControllerWidget::showFSC()
+{
+#ifdef WIN32TRICK
+    // after quiting and going to fs, we need to call show()
+    if( isHidden() )
+        show();
+
+    if( fscHidden )
+    {
+        fscHidden = false;
+        setWindowOpacity( 1.0 );
+    }
+#else
+    show();
+#endif
+
+#if HAVE_TRANSPARENCY
+    setWindowOpacity( DEFAULT_OPACITY );
+#endif
 }
 
 /**
@@ -955,14 +983,32 @@ FullscreenControllerWidget::~FullscreenControllerWidget()
  * FIXME: under windows it have to be done by moving out of screen
  *        because hide() doesnt work
  */
-void FullscreenControllerWidget::hideFSControllerWidget()
+void FullscreenControllerWidget::hideFSC()
 {
-    #ifdef WIN32TRICK
+#ifdef WIN32TRICK
     fscHidden = true;
     setWindowOpacity( 0.0 );    // simulate hidding
-    #else
+#else
     hide();
-    #endif
+#endif
+}
+
+/**
+ * Plane to hide fullscreen controller
+ */
+void FullscreenControllerWidget::planHideFSC()
+{
+    vlc_mutex_lock( &lock );
+    int i_timeout = i_hide_timeout;
+    vlc_mutex_unlock( &lock );
+
+    p_hideTimer->start( i_timeout );
+
+#if HAVE_TRANSPARENCY
+    b_slow_hide_begin = true;
+    i_slow_hide_timeout = i_timeout;
+    p_slowHideTimer->start( i_slow_hide_timeout / 2 );
+#endif
 }
 
 /**
@@ -973,16 +1019,14 @@ void FullscreenControllerWidget::hideFSControllerWidget()
 void FullscreenControllerWidget::slowHideFSC()
 {
 #if HAVE_TRANSPARENCY
-    static bool first_call = true;
-
-    if ( first_call )
+    if( b_slow_hide_begin )
     {
-        first_call = false;
+        b_slow_hide_begin = false;
 
         p_slowHideTimer->stop();
         /* the last part of time divided to 100 pieces */
-        p_slowHideTimer->start(
-            (int) ( i_hideTimeout / 2 / ( windowOpacity() * 100 ) ) );
+        p_slowHideTimer->start( (int)( i_slow_hide_timeout / 2 / ( windowOpacity() * 100 ) ) );
+
     }
     else
     {
@@ -997,66 +1041,37 @@ void FullscreenControllerWidget::slowHideFSC()
              setWindowOpacity( windowOpacity() - 0.02 );
          }
 
-         if ( windowOpacity() == 0.0 )
-         {
-             first_call = true;
+         if ( windowOpacity() <= 0.0 )
              p_slowHideTimer->stop();
-         }
     }
 #endif
 }
 
-/**
- * Get state of visibility of FS controller on screen
- * On windows control if it is on hidden position
- */
-bool FullscreenControllerWidget::isFSCHidden()
-{
-    #ifdef WIN32TRICK
-    return fscHidden;
-    #endif
-
-    return isHidden();
-}
-
 /**
  * event handling
  * events: show, hide, start timer for hidding
  */
 void FullscreenControllerWidget::customEvent( QEvent *event )
 {
-    int type = event->type();
+    bool b_fs;
 
-    if ( type == FullscreenControlShow_Type && b_isFullscreen )
+    switch( event->type() )
     {
-        #ifdef WIN32TRICK
-        // after quiting and going to fs, we need to call show()
-        if ( isHidden() )
-            show();
-
-        if ( fscHidden )
-        {
-            fscHidden = false;
-            setWindowOpacity( 1.0 );
-        }
-        #else
-        show();
-        #endif
-
-#if HAVE_TRANSPARENCY
-        setWindowOpacity( DEFAULT_OPACITY );
-#endif
-    }
-    else if ( type == FullscreenControlHide_Type )
-    {
-        hideFSControllerWidget();
-    }
-    else if ( type == FullscreenControlPlanHide_Type && !b_mouseIsOver )
-    {
-        p_hideTimer->start( i_hideTimeout );
-#if HAVE_TRANSPARENCY
-        p_slowHideTimer->start( i_hideTimeout / 2 );
-#endif
+    case FullscreenControlShow_Type:
+        vlc_mutex_lock( &lock );
+        b_fs = b_fullscreen;
+        vlc_mutex_unlock( &lock );
+
+        if( b_fs )  // FIXME I am not sure about that one
+            showFSC();
+        break;
+    case FullscreenControlHide_Type:
+        hideFSC();
+        break;
+    case FullscreenControlPlanHide_Type:
+        if( !b_mouse_over ) // Only if the mouse is not over FSC
+            planHideFSC();
+        break;
     }
 }
 
@@ -1068,13 +1083,13 @@ void FullscreenControllerWidget::mouseMoveEvent( QMouseEvent *event )
 {
     if ( event->buttons() == Qt::LeftButton )
     {
-        int i_moveX = event->globalX() - i_lastPosX;
-        int i_moveY = event->globalY() - i_lastPosY;
+        int i_moveX = event->globalX() - i_mouse_last_x;
+        int i_moveY = event->globalY() - i_mouse_last_y;
 
         move( x() + i_moveX, y() + i_moveY );
 
-        i_lastPosX = event->globalX();
-        i_lastPosY = event->globalY();
+        i_mouse_last_x = event->globalX();
+        i_mouse_last_y = event->globalY();
     }
 }
 
@@ -1084,8 +1099,8 @@ void FullscreenControllerWidget::mouseMoveEvent( QMouseEvent *event )
  */
 void FullscreenControllerWidget::mousePressEvent( QMouseEvent *event )
 {
-    i_lastPosX = event->globalX();
-    i_lastPosY = event->globalY();
+    i_mouse_last_x = event->globalX();
+    i_mouse_last_y = event->globalY();
 }
 
 /**
@@ -1093,11 +1108,12 @@ void FullscreenControllerWidget::mousePressEvent( QMouseEvent *event )
  */
 void FullscreenControllerWidget::enterEvent( QEvent *event )
 {
+    b_mouse_over = true;
+
     p_hideTimer->stop();
 #if HAVE_TRANSPARENCY
     p_slowHideTimer->stop();
 #endif
-    b_mouseIsOver = true;
 }
 
 /**
@@ -1105,11 +1121,9 @@ void FullscreenControllerWidget::enterEvent( QEvent *event )
  */
 void FullscreenControllerWidget::leaveEvent( QEvent *event )
 {
-    p_hideTimer->start( i_hideTimeout );
-#if HAVE_TRANSPARENCY
-    p_slowHideTimer->start( i_hideTimeout / 2 );
-#endif
-    b_mouseIsOver = false;
+    planHideFSC();
+
+    b_mouse_over = false;
 }
 
 /**
@@ -1129,80 +1143,85 @@ void FullscreenControllerWidget::keyPressEvent( QKeyEvent *event )
         event->ignore();
 }
 
-/**
- * It is called when video start
- */
-void FullscreenControllerWidget::regFullscreenCallback( vout_thread_t *p_vout )
+/* */
+static int FullscreenControllerWidgetFullscreenChanged( vlc_object_t *vlc_object, const char *variable,
+                                                        vlc_value_t old_val, vlc_value_t new_val,
+                                                        void *data )
 {
-    if ( p_vout )
-    {
-        var_AddCallback( p_vout, "fullscreen", regMouseMoveCallback, this );
-    }
+    vout_thread_t *p_vout = (vout_thread_t *) vlc_object;
+    FullscreenControllerWidget *p_fs = (FullscreenControllerWidget *)data;
+
+    p_fs->fullscreenChanged( p_vout, new_val.b_bool, var_GetInteger( p_vout, "mouse-hide-timeout" ) );
+
+    return VLC_SUCCESS;
+}
+/* */
+static int FullscreenControllerWidgetMouseMoved( vlc_object_t *vlc_object, const char *variable,
+                                                 vlc_value_t old_val, vlc_value_t new_val,
+                                                 void *data )
+{
+    FullscreenControllerWidget *p_fs = (FullscreenControllerWidget *)data;
+
+    /* Show event */
+    IMEvent *eShow = new IMEvent( FullscreenControlShow_Type, 0 );
+    QApplication::postEvent( p_fs, static_cast<QEvent *>(eShow) );
+
+    /* Plan hide event */
+    IMEvent *eHide = new IMEvent( FullscreenControlPlanHide_Type, 0 );
+    QApplication::postEvent( p_fs, static_cast<QEvent *>(eHide) );
+
+    return VLC_SUCCESS;
 }
 
+
 /**
- * It is called after turn off video, because p_vout is NULL now
- * we cannt delete callback, just hide if FScontroller is visible
+ * It is called when video start
  */
-void FullscreenControllerWidget::unregFullscreenCallback()
+void FullscreenControllerWidget::attachVout( vout_thread_t *p_vout )
 {
-    if ( isVisible() )
-        hide();
-}
+    assert( p_vout );
 
+    vlc_mutex_lock( &lock );
+    var_AddCallback( p_vout, "fullscreen", FullscreenControllerWidgetFullscreenChanged, this ); /* I miss a add and fire */
+    fullscreenChanged( p_vout, var_GetBool( p_vout, "fullscreen" ), var_GetInteger( p_vout, "mouse-hide-timeout" ) );
+    vlc_mutex_unlock( &lock );
+}
 /**
- * Register and unregister callback for mouse moving
+ * It is called after turn off video.
  */
-static int regMouseMoveCallback( vlc_object_t *vlc_object, const char *variable,
-                                 vlc_value_t old_val, vlc_value_t new_val,
-                                 void *data )
+void FullscreenControllerWidget::detachVout( vout_thread_t *p_vout )
 {
-    vout_thread_t *p_vout = (vout_thread_t *) vlc_object;
+    assert( p_vout );
 
-    static bool b_registered = false;
-    FullscreenControllerWidget *p_fs = (FullscreenControllerWidget *) data;
-
-    if ( var_GetBool( p_vout, "fullscreen" ) && !b_registered )
-    {
-        p_fs->setHideTimeout( var_GetInteger( p_vout, "mouse-hide-timeout" ) );
-        p_fs->setIsFullscreen( true );
-        var_AddCallback( p_vout, "mouse-moved",
-                        showFullscreenControllCallback, (void *) p_fs );
-        b_registered = true;
-    }
-
-    if ( !var_GetBool( p_vout, "fullscreen" ) && b_registered )
-    {
-        p_fs->setIsFullscreen( false );
-        p_fs->hide();
-        var_DelCallback( p_vout, "mouse-moved",
-                        showFullscreenControllCallback, (void *) p_fs );
-        b_registered = false;
-    }
-
-    return VLC_SUCCESS;
+    var_DelCallback( p_vout, "fullscreen", FullscreenControllerWidgetFullscreenChanged, this );
+    vlc_mutex_lock( &lock );
+    fullscreenChanged( p_vout, false, 0 );
+    vlc_mutex_unlock( &lock );
 }
 
 /**
- * Show fullscreen controller after mouse move
- * after show immediately plan hide event
+ * Register and unregister callback for mouse moving
  */
-static int showFullscreenControllCallback( vlc_object_t *vlc_object, const char *variable,
-                                           vlc_value_t old_val, vlc_value_t new_val,
-                                           void *data )
+void FullscreenControllerWidget::fullscreenChanged( vout_thread_t *p_vout, bool b_fs, int i_timeout )
 {
-    FullscreenControllerWidget *p_fs = (FullscreenControllerWidget *) data;
-
-    if ( p_fs->isFSCHidden() || p_fs->windowOpacity() < DEFAULT_OPACITY )
+    vlc_mutex_lock( &lock );
+    if( b_fs && !b_fullscreen )
     {
-        IMEvent *event = new IMEvent( FullscreenControlShow_Type, 0 );
-        QApplication::postEvent( p_fs, static_cast<QEvent *>(event) );
+        b_fullscreen = true;
+        i_hide_timeout = i_timeout;
+        var_AddCallback( p_vout, "mouse-moved", FullscreenControllerWidgetMouseMoved, this );
     }
+    else if( !b_fs && b_fullscreen )
+    {
+        b_fullscreen = false;
+        i_hide_timeout = i_timeout;
+        var_DelCallback( p_vout, "mouse-moved", FullscreenControllerWidgetMouseMoved, this );
 
-    IMEvent *e = new IMEvent( FullscreenControlPlanHide_Type, 0 );
-    QApplication::postEvent( p_fs, static_cast<QEvent *>(e) );
-
-    return VLC_SUCCESS;
+        /* Force fs hidding */
+        IMEvent *eHide = new IMEvent( FullscreenControlHide_Type, 0 );
+        QApplication::postEvent( this, static_cast<QEvent *>(eHide) );
+    }
+    vlc_mutex_unlock( &lock );
 }
 
 /**********************************************************************
index e1bcbb5f8cdd78ac22f20963ee5a008461f1b463..911eb89bac5e70d016315b43bfc8565b1655a46c 100644 (file)
@@ -236,13 +236,6 @@ signals:
 /***********************************
  * Fullscreen controller
  ***********************************/
-
-static int showFullscreenControllCallback(vlc_object_t *vlc_object, const char *variable, vlc_value_t old_val,
-    vlc_value_t new_val, void *data);
-
-static int regMouseMoveCallback(vlc_object_t *vlc_object, const char *variable, vlc_value_t old_val,
-    vlc_value_t new_val, void *data);
-
 class FullscreenControllerWidget : public ControlsWidget
 {
     Q_OBJECT
@@ -250,14 +243,10 @@ public:
     FullscreenControllerWidget( intf_thread_t *, MainInterface*, bool, bool );
     virtual ~FullscreenControllerWidget();
 
-    void setHideTimeout( int hideTimeout ) { i_hideTimeout = hideTimeout; }
-    void setIsFullscreen( bool isFS ) { b_isFullscreen = isFS; }
-    void regFullscreenCallback( vout_thread_t *p_vout );
-
-    bool isFSCHidden();
-
-public slots:
-    void unregFullscreenCallback();
+    /* */
+    void attachVout( vout_thread_t *p_vout );
+    void detachVout( vout_thread_t *p_vout );
+    void fullscreenChanged( vout_thread_t *, bool b_fs, int i_timeout );
 
 protected:
     friend class MainInterface;
@@ -270,27 +259,37 @@ protected:
     virtual void keyPressEvent( QKeyEvent *event );
 
 private slots:
-    void hideFSControllerWidget();
+    void showFSC();
+    void planHideFSC();
+    void hideFSC();
+
     void slowHideFSC();
 
+
 private:
     QTimer *p_hideTimer;
-
 #if HAVE_TRANSPARENCY
     QTimer *p_slowHideTimer;
 #endif
 
-    int i_lastPosX;
-    int i_lastPosY;
-    int i_hideTimeout;  /* FSC hiding timeout, same as mouse hiding timeout */
-    bool b_mouseIsOver;
-    bool b_isFullscreen;
+    int i_mouse_last_x;
+    int i_mouse_last_y;
+
+    bool b_mouse_over;
+
+    bool b_slow_hide_begin;
+    int  i_slow_hide_timeout;
 
 #ifdef WIN32TRICK
     bool fscHidden;
 #endif
 
     virtual void customEvent( QEvent *event );
+
+    /* Shared variable between FSC and VLC (protected by a lock) */
+    vlc_mutex_t lock;
+    bool        b_fullscreen;
+    int         i_hide_timeout;  /* FSC hiding timeout, same as mouse hiding timeout */
 };
 
 
index 4ff801a3ddae78882f197418d2f6739848f3a0c1..ab6a3a227ec600292b6b8022991623a6801a2bfb 100644 (file)
@@ -99,7 +99,6 @@ void InputManager::setInput( input_thread_t *_p_input )
         p_input = NULL;
         i_input_id = 0;
         emit rateChanged( INPUT_RATE_DEFAULT );
-        emit inputUnset();
     }
 }
 
index d6ec96447ec2f497632dc636131e2acb29ca6ae7..6d133f6cf32e0a850f9e3c3e016b7702cd756642 100644 (file)
@@ -119,8 +119,6 @@ signals:
     /// Play/pause status
     void statusChanged( int );
     void artChanged( QString );
-    /// Controll of fullscreen controller
-    void inputUnset();
     /// Teletext
     void teletextEnabled( bool );
     void toggleTelexButtons();
index 5692d92f78aa902f459565f0c6d21c921568d267..355f7a3f3572f18ad737ef52b2be79f3fce56678 100644 (file)
@@ -228,10 +228,6 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
     CONNECT( fullscreenControls, advancedControlsToggled( bool ),
              this, doComponentsUpdate() );
 
-    CONNECT( THEMIM->getIM(), inputUnset(),
-            fullscreenControls, unregFullscreenCallback() );
-
-
     /* Size and placement of interface */
     QVLCTools::restoreWidgetPosition(settings,this,QSize(350,60));
 
@@ -682,12 +678,17 @@ void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
 
 //        emit askVideoToResize( *pi_width, *pi_height );
         emit askUpdate();
+
+        //XXX uncomment for fullscreen controler
+        //fullscreenControls->attachVout( p_nvout );
     }
     return ret;
 }
 
 void MainInterface::releaseVideo( vout_thread_t *p_vout, void *p_win )
 {
+    //XXX uncomment for fullscreen controler
+    //fullscreenControls->detachVout( p_vout );
     emit askReleaseVideo( p_win );
 }