[vlc-devel] commit: Qt4 window: full-screen support ( Rémi Denis-Courmont )

git version control git at videolan.org
Wed Aug 12 20:36:09 CEST 2009


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Aug 12 21:35:02 2009 +0300| [36938ceb0d57d2981d1541a2c631d2d7dd7f7e61] | committer: Rémi Denis-Courmont 

Qt4 window: full-screen support

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=36938ceb0d57d2981d1541a2c631d2d7dd7f7e61
---

 modules/gui/qt4/components/interface_widgets.cpp |   84 +++++++++++++++++-----
 modules/gui/qt4/components/interface_widgets.hpp |    5 +-
 modules/gui/qt4/main_interface.cpp               |    9 +++
 modules/gui/qt4/main_interface.hpp               |    1 +
 4 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/modules/gui/qt4/components/interface_widgets.cpp b/modules/gui/qt4/components/interface_widgets.cpp
index 55e89b2..2ef0b56 100644
--- a/modules/gui/qt4/components/interface_widgets.cpp
+++ b/modules/gui/qt4/components/interface_widgets.cpp
@@ -57,7 +57,7 @@
 VideoWidget::VideoWidget( intf_thread_t *_p_i ) : QFrame( NULL ), p_intf( _p_i )
 {
     /* Init */
-    b_used = false;
+    reparentable = NULL;
     videoSize.rwidth() = -1;
     videoSize.rheight() = -1;
 
@@ -66,16 +66,14 @@ VideoWidget::VideoWidget( intf_thread_t *_p_i ) : QFrame( NULL ), p_intf( _p_i )
     /* Set the policy to expand in both directions */
 //    setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
 
-    /* Black background is more coherent for a Video Widget */
-    QPalette plt =  palette();
-    plt.setColor( QPalette::Window, Qt::black );
-    setPalette( plt );
-    setAutoFillBackground(true);
-
     /* Indicates that the widget wants to draw directly onto the screen.
        Widgets with this attribute set do not participate in composition
        management */
     setAttribute( Qt::WA_PaintOnScreen, true );
+
+    layout = new QHBoxLayout( this );
+    layout->setContentsMargins( 0, 0, 0, 0 );
+    setLayout( layout );
 }
 
 void VideoWidget::paintEvent(QPaintEvent *ev)
@@ -89,7 +87,7 @@ void VideoWidget::paintEvent(QPaintEvent *ev)
 VideoWidget::~VideoWidget()
 {
     /* Ensure we are not leaking the video output. This would crash. */
-    assert( !b_used );
+    assert( reparentable == NULL );
 }
 
 /**
@@ -101,22 +99,47 @@ WId VideoWidget::request( int *pi_x, int *pi_y,
 {
     msg_Dbg( p_intf, "Video was requested %i, %i", *pi_x, *pi_y );
 
+    if( reparentable != NULL )
+    {
+        msg_Dbg( p_intf, "embedded video already in use" );
+        return NULL;
+    }
     if( b_keep_size )
     {
         *pi_width  = size().width();
         *pi_height = size().height();
     }
 
-    if( b_used )
-    {
-        msg_Dbg( p_intf, "embedded video already in use" );
-        return NULL;
-    }
-    b_used = true;
+    /* The Qt4 UI needs a fixed a widget ("this"), so that the parent layout is
+     * not messed up when we the video is reparented. Hence, we create an extra
+     * reparentable widget, that will be within the VideoWidget in windowed
+     * mode, and within the root window (NULL parent) in full-screen mode.
+     */
+    reparentable = new QWidget();
+    QLayout *innerLayout = new QHBoxLayout( reparentable );
+    innerLayout->setContentsMargins( 0, 0, 0, 0 );
+
+    /* The owner of the video window needs a stable handle (WinId). Reparenting
+     * in Qt4-X11 changes the WinId of the widget, so we need to create another
+     * dummy widget that stays within the reparentable widget. */
+    QWidget *stable = new QWidget();
+    QPalette plt = palette();
+    plt.setColor( QPalette::Window, Qt::black );
+    stable->setPalette( plt );
+    stable->setAutoFillBackground(true);
+    stable->setAttribute( Qt::WA_PaintOnScreen, true );
+
+    innerLayout->addWidget( stable );
+
+    reparentable->setLayout( innerLayout );
+    layout->addWidget( reparentable );
+    updateGeometry();
+
 #ifndef NDEBUG
-    msg_Dbg( p_intf, "embedded video ready (handle %p)", (void *)winId() );
+    msg_Dbg( p_intf, "embedded video ready (handle %p)",
+             (void *)stable->winId() );
 #endif
-    return winId();
+    return stable->winId();
 }
 
 /* Set the Widget to the correct Size */
@@ -131,10 +154,37 @@ void VideoWidget::SetSizing( unsigned int w, unsigned int h )
     updateGeometry(); // Needed for deinterlace
 }
 
+void VideoWidget::SetFullScreen( bool b_fs )
+{
+    const Qt::WindowStates curstate = reparentable->windowState();
+    Qt::WindowStates newstate = curstate;
+
+    if( b_fs )
+        newstate |= Qt::WindowFullScreen;
+    else
+        newstate &= ~Qt::WindowFullScreen;
+    if( newstate == curstate )
+        return; /* no changes needed */
+
+    if( b_fs )
+    {   /* Go full-screen */
+        reparentable->setParent( NULL );
+        reparentable->setWindowState( newstate );
+        reparentable->show();
+    }
+    else
+    {   /* Go windowed */
+        reparentable->setWindowState( newstate );
+        layout->addWidget( reparentable );
+    }
+}
+
 void VideoWidget::release( void )
 {
     msg_Dbg( p_intf, "Video is not needed anymore" );
-    b_used = false;
+    //layout->removeWidget( reparentable );
+    delete reparentable;
+    reparentable = NULL;
     videoSize.rwidth() = 0;
     videoSize.rheight() = 0;
     updateGeometry();
diff --git a/modules/gui/qt4/components/interface_widgets.hpp b/modules/gui/qt4/components/interface_widgets.hpp
index 6187b20..af894fe 100644
--- a/modules/gui/qt4/components/interface_widgets.hpp
+++ b/modules/gui/qt4/components/interface_widgets.hpp
@@ -76,13 +76,14 @@ protected:
 
 private:
     intf_thread_t *p_intf;
-    bool b_used;
 
     QSize videoSize;
+    QWidget *reparentable;
+    QLayout *layout;
 
 public slots:
     void SetSizing( unsigned int, unsigned int );
-
+    void SetFullScreen( bool );
 };
 
 /******************** Background Widget ****************/
diff --git a/modules/gui/qt4/main_interface.cpp b/modules/gui/qt4/main_interface.cpp
index 715d2fe..5bc1fc5 100644
--- a/modules/gui/qt4/main_interface.cpp
+++ b/modules/gui/qt4/main_interface.cpp
@@ -228,6 +228,8 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
     {
         CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
                  videoWidget, SetSizing( unsigned int, unsigned int ) );
+        CONNECT( this, askVideoSetFullScreen( bool ),
+                 videoWidget, SetFullScreen( bool ) );
     }
 
     CONNECT( this, askUpdate(), this, doComponentsUpdate() );
@@ -792,6 +794,13 @@ int MainInterface::controlVideo( int i_query, va_list args )
         QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
         return VLC_SUCCESS;
     }
+    case VOUT_WINDOW_SET_FULLSCREEN:
+    {
+        bool b_fs = va_arg( args, int );
+        msg_Err( p_intf, b_fs ? "fullscreen!" : "windowed!" );
+        emit askVideoSetFullScreen( b_fs );
+        return VLC_SUCCESS;
+    }
     default:
         msg_Warn( p_intf, "unsupported control query" );
         return VLC_EGENERIC;
diff --git a/modules/gui/qt4/main_interface.hpp b/modules/gui/qt4/main_interface.hpp
index aeeffa8..1e6ce55 100644
--- a/modules/gui/qt4/main_interface.hpp
+++ b/modules/gui/qt4/main_interface.hpp
@@ -183,6 +183,7 @@ signals:
                       unsigned int *pi_width, unsigned int *pi_height );
     void askReleaseVideo( );
     void askVideoToResize( unsigned int, unsigned int );
+    void askVideoSetFullScreen( bool );
     void askUpdate();
     void minimalViewToggled( bool );
     void fullscreenInterfaceToggled( bool );




More information about the vlc-devel mailing list