#include <QBitmap>
#ifdef Q_WS_X11
-# include <X11/Xlib.h>
-# include <qx11info_x11.h>
-static void videoSync( void )
-{
- /* Make sure the X server has processed all requests.
- * This protects other threads using distinct connections from getting
- * the video widget window in an inconsistent states. */
- XSync( QX11Info::display(), False );
-}
-#else
-# define videoSync() (void)0
+# include <X11/Xlib.h>
+# include <qx11info_x11.h>
#endif
#include <math.h>
#include <assert.h>
-class ReparentableWidget : public QWidget
-{
-private:
- VideoWidget *owner;
-public:
- ReparentableWidget( VideoWidget *owner ) : owner( owner )
- {}
-};
-
/**********************************************************************
* Video Widget. A simple frame on which video is drawn
* This class handles resize issues
VideoWidget::VideoWidget( intf_thread_t *_p_i )
: QFrame( NULL )
, p_intf( _p_i )
- , reparentable( NULL )
{
/* Set the policy to expand in both directions */
// setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
layout = new QHBoxLayout( this );
layout->setContentsMargins( 0, 0, 0, 0 );
setLayout( layout );
+ stable = NULL;
}
VideoWidget::~VideoWidget()
{
/* Ensure we are not leaking the video output. This would crash. */
- assert( reparentable == NULL );
+ assert( !stable );
+}
+
+void VideoWidget::sync( void )
+{
+#ifdef Q_WS_X11
+ /* Make sure the X server has processed all requests.
+ * This protects other threads using distinct connections from getting
+ * the video widget window in an inconsistent states. */
+ XSync( QX11Info::display(), False );
+#endif
}
/**
{
msg_Dbg( p_intf, "Video was requested %i, %i", *pi_x, *pi_y );
- if( reparentable != NULL )
+ if( stable )
{
msg_Dbg( p_intf, "embedded video already in use" );
return NULL;
*pi_height = size().height();
}
- /* 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 ReparentableWidget( this );
- reparentable->installEventFilter(this );
- 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();
+ stable = new QWidget();
QPalette plt = palette();
plt.setColor( QPalette::Window, Qt::black );
stable->setPalette( plt );
stable->setAttribute( Qt::WA_PaintOnScreen, true );
#endif
- innerLayout->addWidget( stable );
-
- layout->addWidget( reparentable );
+ layout->addWidget( stable );
#ifdef Q_WS_X11
/* HACK: Only one X11 client can subscribe to mouse button press events.
attr.your_event_mask &= ~(ButtonPressMask|ButtonReleaseMask);
XSelectInput( dpy, w, attr.your_event_mask );
#endif
- videoSync();
+ sync();
#ifndef NDEBUG
msg_Dbg( p_intf, "embedded video ready (handle %p)",
(void *)stable->winId() );
Parent has to care about resizing itself */
void VideoWidget::SetSizing( unsigned int w, unsigned int h )
{
- if (reparentable->windowState() & Qt::WindowFullScreen )
- return;
if( !isVisible() ) show();
resize( w, h );
emit sizeChanged( w, h );
*/
if( size().width() == w && size().height() == h )
updateGeometry();
- videoSync();
-}
-
-void VideoWidget::SetFullScreen( bool b_fs, bool b_ontop )
-{
- const Qt::WindowStates curstate = reparentable->windowState();
- Qt::WindowStates newstate = curstate;
- Qt::WindowFlags newflags = reparentable->windowFlags();
-
-
- if( b_fs )
- {
- newstate |= Qt::WindowFullScreen;
- if( b_ontop )
- newflags |= Qt::WindowStaysOnTopHint;
- }
- else
- {
- newstate &= ~Qt::WindowFullScreen;
- newflags &= ~Qt::WindowStaysOnTopHint;
- }
- if( newstate == curstate )
- return; /* no changes needed */
-
- if( b_fs )
- { /* Go full-screen */
- int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
- /* if user hasn't defined screennumber, or screennumber that is bigger
- * than current number of screens, take screennumber where current interface
- * is
- */
- if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
- numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
-
- QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
-
- /* To be sure window is on proper-screen in xinerama */
- if( !screenres.contains( reparentable->pos() ) )
- {
- msg_Dbg( p_intf, "Moving video to correct screen");
- reparentable->move( QPoint( screenres.x(), screenres.y() ) );
- }
- reparentable->setParent( NULL, newflags );
- reparentable->setWindowState( newstate );
-
- /* FIXME: inherit from the vout window, not the interface */
- char *title = var_InheritString( p_intf, "video-title" );
- reparentable->setWindowTitle( qfu(title ? title : _("Video")) );
- free( title );
-
- reparentable->show();
- reparentable->activateWindow();
- reparentable->raise();
- }
- else
- { /* Go windowed */
- reparentable->setWindowFlags( newflags );
- reparentable->setWindowState( newstate );
- layout->addWidget( reparentable );
- }
- videoSync();
+ sync();
}
void VideoWidget::release( void )
{
msg_Dbg( p_intf, "Video is not needed anymore" );
- //layout->removeWidget( reparentable );
- reparentable->deleteLater();
- reparentable = NULL;
+ assert( stable );
+ layout->removeWidget( stable );
+ stable->deleteLater();
+ stable = NULL;
+
updateGeometry();
hide();
}
-#undef KeyPress
-bool VideoWidget::eventFilter(QObject *obj, QEvent *event)
-{
- if( obj == reparentable )
- {
- if (event->type() == QEvent::Close)
- {
- THEDP->quit();
- return true;
- }
- else if( event->type() == QEvent::KeyPress )
- {
- emit keyPressed( static_cast<QKeyEvent *>(event) );
- return true;
- }
- else if( event->type() == QEvent::Wheel )
- {
- int i_vlckey = qtWheelEventToVLCKey( static_cast<QWheelEvent *>(event) );
- var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
- return true;
- }
- }
- return false;
-}
-
/**********************************************************************
* Background Widget. Show a simple image background. Currently,
* it's album art if present or cone.
class QHBoxLayout;
class QMenu;
class QSlider;
-class ReparentableWidget;
/******************** Video Widget ****************/
class VideoWidget : public QFrame
{
Q_OBJECT
-friend class ReparentableWidget;
-
public:
VideoWidget( intf_thread_t * );
virtual ~VideoWidget();
WId request( int *, int *, unsigned int *, unsigned int *, bool );
void release( void );
int control( void *, int, va_list );
- void SetFullScreen( bool, bool );
+ void sync( void );
protected:
virtual QPaintEngine *paintEngine() const
private:
intf_thread_t *p_intf;
- QWidget *reparentable;
+ QWidget *stable;
QLayout *layout;
- virtual bool eventFilter ( QObject * watched, QEvent * event );
signals:
- void keyPressed( QKeyEvent * );
void sizeChanged( int, int );
public slots:
b_autoresize = var_InheritBool( p_intf, "qt-video-autoresize" );
/* Are we in the enhanced always-video mode or not ? */
- i_visualmode = var_InheritBool( p_intf, "qt-minimal-view" );
+ b_minimalView = var_InheritBool( p_intf, "qt-minimal-view" );
/* Do we want anoying popups or not */
b_notificationEnabled = var_InheritBool( p_intf, "qt-notification" );
}
CONNECT( this, askVideoSetFullScreen( bool ),
this, setVideoFullScreen( bool ) );
- CONNECT( videoWidget, keyPressed( QKeyEvent * ),
- this, handleKeyPress( QKeyEvent * ) );
}
CONNECT( THEDP, toolBarConfUpdated(), this, recreateToolbars() );
QVLCTools::restoreWidgetPosition( settings, this, QSize(400, 100) );
settings->endGroup();
+ b_interfaceFullScreen = isFullScreen();
+
/* Final sizing and showing */
setVisible( !b_hideAfterCreation );
menuBar()->sizeHint().width() ) + 30 );
/* Switch to minimal view if needed, must be called after the show() */
- if( i_visualmode )
+ if( b_minimalView )
toggleMinimalView( true );
}
{
videoWidget->release();
setVideoOnTop( false );
+ setVideoFullScreen( false );
if( stackCentralW->currentWidget() == videoWidget )
restoreStackOldWidget();
void MainInterface::setVideoSize( unsigned int w, unsigned int h )
{
- if( isFullScreen() || isMaximized() )
- showNormal();
- videoWidget->SetSizing( w, h );
+ if( !isFullScreen() && !isMaximized() )
+ videoWidget->SetSizing( w, h );
}
void MainInterface::setVideoFullScreen( bool fs )
{
b_videoFullScreen = fs;
- /* refresh main interface on-top status if needed */
- setVideoOnTop( b_videoOnTop );
- videoWidget->SetFullScreen( fs, b_videoOnTop );
+ if( fs )
+ {
+ int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
+ /* if user hasn't defined screennumber, or screennumber that is bigger
+ * than current number of screens, take screennumber where current interface
+ * is
+ */
+ if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
+ numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
+
+ QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
+
+ /* To be sure window is on proper-screen in xinerama */
+ if( !screenres.contains( pos() ) )
+ {
+ msg_Dbg( p_intf, "Moving video to correct screen");
+ move( QPoint( screenres.x(), screenres.y() ) );
+ }
+ setMinimalView( true );
+ setInterfaceFullScreen( true );
+ }
+ else
+ {
+ /* TODO do we want to restore screen and position ? (when
+ * qt-fullscreen-screennumber is forced) */
+ setMinimalView( b_minimalView );
+ setInterfaceFullScreen( b_interfaceFullScreen );
+ }
+ videoWidget->sync();
}
/* Slot to change the video always-on-top flag.
void MainInterface::setVideoOnTop( bool on_top )
{
b_videoOnTop = on_top;
- /* The main interface is not always-on-top if it does not contain
- * the video (which is to say in fullscreen mode). */
- if( b_videoFullScreen )
- on_top = false;
Qt::WindowFlags oldflags = windowFlags(), newflags;
- if( on_top )
+ if( b_videoOnTop )
newflags = oldflags | Qt::WindowStaysOnTopHint;
else
newflags = oldflags & ~Qt::WindowStaysOnTopHint;
playlistVisible = true;
}
+void MainInterface::setMinimalView( bool b_minimal )
+{
+ menuBar()->setVisible( !b_minimal );
+ controls->setVisible( !b_minimal );
+ statusBar()->setVisible( !b_minimal );
+ inputC->setVisible( !b_minimal );
+}
+
/*
- If b_switch is false, then we are normalView
+ If b_minimal is false, then we are normalView
*/
-void MainInterface::toggleMinimalView( bool b_switch )
+void MainInterface::toggleMinimalView( bool b_minimal )
{
- if( i_visualmode == 0 && b_autoresize ) /* Normal mode */
+ if( !b_minimalView && b_autoresize ) /* Normal mode */
{
if( stackCentralW->currentWidget() == bgWidget )
{
}
}
}
+ b_minimalView = b_minimal;
+ if( !b_videoFullScreen )
+ setMinimalView( b_minimalView );
- menuBar()->setVisible( !b_switch );
- controls->setVisible( !b_switch );
- statusBar()->setVisible( !b_switch );
- inputC->setVisible( !b_switch );
-
- emit minimalViewToggled( b_switch );
+ emit minimalViewToggled( b_minimalView );
}
/* toggling advanced controls buttons */
void MainInterface::handleKeyPress( QKeyEvent *e )
{
- if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H )
- && !menuBar()->isVisible() )
+ if( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
{
- toggleMinimalView( false );
+ toggleMinimalView( !b_minimalView );
e->accept();
}
THEDP->quit();
}
-void MainInterface::toggleFullScreen()
+void MainInterface::setInterfaceFullScreen( bool fs )
{
- if( isFullScreen() )
- {
- showNormal();
- emit fullscreenInterfaceToggled( false );
- }
- else
- {
+ if( fs )
showFullScreen();
- emit fullscreenInterfaceToggled( true );
- }
+ else
+ showNormal();
+}
+void MainInterface::toggleInterfaceFullScreen()
+{
+ b_interfaceFullScreen = !b_interfaceFullScreen;
+ if( !b_videoFullScreen )
+ setInterfaceFullScreen( b_interfaceFullScreen );
+ emit fullscreenInterfaceToggled( b_interfaceFullScreen );
}
/*****************************************************************************
#endif
int getControlsVisibilityStatus();
bool isPlDocked() { return ( b_plDocked != false ); }
+ bool isInterfaceFullScreen() { return b_interfaceFullScreen; }
protected:
void dropEventPlay( QDropEvent *, bool);
void showVideo();
void restoreStackOldWidget();
+ /* */
+ void setMinimalView( bool );
+ void setInterfaceFullScreen( bool );
+
/* */
QSettings *settings;
#ifndef HAVE_MAEMO
bool b_videoFullScreen; ///< --fullscreen
bool b_videoOnTop; ///< --video-on-top
bool b_hideAfterCreation;
- int i_visualmode; ///< Visual Mode
+ bool b_minimalView; ///< Minimal video
+ bool b_interfaceFullScreen;
/* States */
bool playlistVisible; ///< Is the playlist visible ?
void toggleUpdateSystrayMenu();
#endif
void toggleAdvancedButtons();
- void toggleFullScreen();
+ void toggleInterfaceFullScreen();
void toggleFSC();
void popupMenu( const QPoint& );
void resizeStack( int w, int h ) {
if( !isFullScreen() && !isMaximized() )
- if( i_visualmode == 1 ) resize( w, h ); /* Oh yes, it shouldn't
+ if( b_minimalView ) resize( w, h ); /* Oh yes, it shouldn't
be possible that size() - stackCentralW->size() < 0
since stackCentralW is contained in the QMW... */
else resize( size() - stackCentralW->size() + QSize( w, h ) );
/* FullScreen View */
action = menu->addAction( qtr( "&Fullscreen Interface" ), mi,
- SLOT( toggleFullScreen() ), QString( "F11" ) );
+ SLOT( toggleInterfaceFullScreen() ), QString( "F11" ) );
action->setCheckable( true );
- action->setChecked( mi->isFullScreen() );
+ action->setChecked( mi->isInterfaceFullScreen() );
CONNECT( mi, fullscreenInterfaceToggled( bool ),
action, setChecked( bool ) );