[vlc-devel] [PATCH 2/2] qt: support mouse wheel actions on tray icon

Niels Martignène niels.martignene at gmail.com
Sun Jul 6 14:47:01 CEST 2014


Add support for mouse wheel actions on tray icon (X11 only). Actions include:
- Ignore
- Change volume (default)
- Change track
- Seek media

Qt requires us to subclass QSystemTrayIcon to handle mouse wheel events, which is done in class MyTrayIcon. It provides an additional signal wheel() to report for mouse wheel events. This event is connected to a new slot MainInterface::handleSystrayWheel(MyTrayIcon::WheelMotion).
---
 modules/gui/qt4/main_interface.cpp | 70 +++++++++++++++++++++++++++++++++++++-
 modules/gui/qt4/main_interface.hpp | 29 +++++++++++++++-
 modules/gui/qt4/qt4.cpp            | 18 ++++++++++
 modules/gui/qt4/qt4.hpp            |  7 ++++
 4 files changed, 122 insertions(+), 2 deletions(-)

diff --git a/modules/gui/qt4/main_interface.cpp b/modules/gui/qt4/main_interface.cpp
index 971c024..77701d9 100644
--- a/modules/gui/qt4/main_interface.cpp
+++ b/modules/gui/qt4/main_interface.cpp
@@ -85,6 +85,27 @@ static int IntfRaiseMainCB( vlc_object_t *p_this, const char *psz_variable,
 const QEvent::Type MainInterface::ToolbarsNeedRebuild =
         (QEvent::Type)QEvent::registerEventType();
 
+bool MyTrayIcon::event( QEvent *e )
+{
+    if (e->type() == QEvent::Wheel) {
+        QWheelEvent * w = (QWheelEvent *)e;
+
+        if (w->orientation() == Qt::Vertical) {
+            wheel_delta += w->delta();
+
+            if (abs( wheel_delta ) >= 120) {
+                emit wheel( wheel_delta > 0 ? MyTrayIcon::WheelUp : MyTrayIcon::WheelDown );
+                wheel_delta = 0;
+            }
+        }
+
+        return true;
+    }
+
+    // fall through
+    return QSystemTrayIcon::event( e );
+}
+
 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
 {
     /* Variables initialisation */
@@ -1061,7 +1082,7 @@ void MainInterface::createSystray()
         iconVLC = QIcon::fromTheme( "vlc-xmas", QIcon( ":/logo/vlc128-xmas.png" ) );
     else
         iconVLC = QIcon::fromTheme( "vlc", QIcon( ":/logo/vlc256.png" ) );
-    sysTray = new QSystemTrayIcon( iconVLC, this );
+    sysTray = new MyTrayIcon( iconVLC, this );
     sysTray->setToolTip( qtr( "VLC media player" ));
 
     systrayMenu = new QMenu( qtr( "VLC media player" ), this );
@@ -1072,6 +1093,8 @@ void MainInterface::createSystray()
 
     CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
              this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
+    CONNECT( sysTray, wheel( MyTrayIcon::WheelMotion ),
+             this, handleSystrayWheel( MyTrayIcon::WheelMotion ) );
 
     /* Connects on nameChanged() */
     CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
@@ -1196,6 +1219,51 @@ void MainInterface::handleSystrayClick(
     }
 }
 
+/* Wheel on systray Icon */
+void MainInterface::handleSystrayWheel( MyTrayIcon::WheelMotion motion )
+{
+    int action = var_InheritInteger( p_intf, "qt-system-tray-wheel" );
+
+    switch ( action )
+    {
+        case SYSTRAY_WHEEL_CHANGE_VOLUME:
+            switch( motion )
+            {
+                case MyTrayIcon::WheelUp:
+                    THEAM->AudioUp();
+                    break;
+                case MyTrayIcon::WheelDown:
+                    THEAM->AudioDown();
+                    break;
+            }
+            break;
+        case SYSTRAY_WHEEL_CHANGE_TRACK:
+            switch( motion )
+            {
+                case MyTrayIcon::WheelUp:
+                    THEMIM->next();
+                    break;
+                case MyTrayIcon::WheelDown:
+                    THEMIM->prev();
+                    break;
+            }
+            break;
+        case SYSTRAY_WHEEL_SEEK:
+            switch( motion )
+            {
+                case MyTrayIcon::WheelUp:
+                    THEAM->skipForward();
+                    break;
+                case MyTrayIcon::WheelDown:
+                    THEAM->skipBackward();
+                    break;
+            }
+            break;
+        default:
+            break;
+    }
+}
+
 /**
  * Updates the name of the systray Icon tooltip.
  * Doesn't check if the systray exists, check before you call it.
diff --git a/modules/gui/qt4/main_interface.hpp b/modules/gui/qt4/main_interface.hpp
index 8a69193..a7407cd 100644
--- a/modules/gui/qt4/main_interface.hpp
+++ b/modules/gui/qt4/main_interface.hpp
@@ -56,6 +56,32 @@ class QMenu;
 class QSize;
 class StandardPLPanel;
 
+// Qt provides no way of receiving wheel motion on tray icons (X11-only)
+// without subclassing QSystemTrayIcon::event method.
+class MyTrayIcon : public QSystemTrayIcon
+{
+    Q_OBJECT
+
+public:
+    enum WheelMotion {
+        WheelUp,
+        WheelDown
+    };
+
+    MyTrayIcon( QObject * parent = 0 )
+        : QSystemTrayIcon( parent ), wheel_delta( 0 ) {}
+    MyTrayIcon( const QIcon & icon, QObject * parent = 0 )
+        : QSystemTrayIcon( icon, parent ), wheel_delta( 0 ) {}
+
+    bool event( QEvent * event );
+
+signals:
+    void wheel( MyTrayIcon::WheelMotion motion );
+
+private:
+    int wheel_delta;
+};
+
 class MainInterface : public QVLCMW
 {
     Q_OBJECT
@@ -129,7 +155,7 @@ private:
 
     /* */
     QSettings           *settings;
-    QSystemTrayIcon     *sysTray;
+    MyTrayIcon          *sysTray;
     QMenu               *systrayMenu;
 
     QString              input_name;
@@ -225,6 +251,7 @@ private slots:
     void visual();
 #endif
     void handleSystrayClick( QSystemTrayIcon::ActivationReason );
+    void handleSystrayWheel( MyTrayIcon::WheelMotion motion );
     void updateSystrayTooltipName( const QString& );
     void updateSystrayTooltipStatus( int );
     void showCryptedLabel( bool );
diff --git a/modules/gui/qt4/qt4.cpp b/modules/gui/qt4/qt4.cpp
index ec60760..c7ce2f9 100644
--- a/modules/gui/qt4/qt4.cpp
+++ b/modules/gui/qt4/qt4.cpp
@@ -95,6 +95,10 @@ static void ShowDialog   ( intf_thread_t *, int, int, intf_dialog_args_t * );
 #define SYSTRAY_MIDDLE_CLICK_LONGTEXT N_( "Action to execute for a middle click on " \
                                           " the system tray icon")
 
+#define SYSTRAY_WHEEL_TEXT N_( "Wheel motion" )
+#define SYSTRAY_WHEEL_LONGTEXT N_( "Action to execute for wheel motion over " \
+                                   "the system tray icon" )
+
 #define MINIMIZED_TEXT N_( "Start VLC with only a systray icon" )
 #define MINIMIZED_LONGTEXT N_( "VLC will start with just an icon in " \
                                "your taskbar" )
@@ -203,6 +207,13 @@ static const char *const psz_systray_click_list_text[] =
     { N_("Ignore"), N_("Toggle main interface"), N_("Play/pause"),
       N_("Mute/unmute") };
 
+static const int i_systray_wheel_list[] =
+    { SYSTRAY_WHEEL_IGNORE, SYSTRAY_WHEEL_CHANGE_VOLUME,
+      SYSTRAY_WHEEL_CHANGE_TRACK, SYSTRAY_WHEEL_SEEK };
+
+static const char *const psz_systray_wheel_list_text[] =
+    { N_("Ignore"), N_("Change volume"), N_("Change track"), N_("Seek media") };
+
 static const int i_notification_list[] =
     { NOTIFICATION_NEVER, NOTIFICATION_MINIMIZED, NOTIFICATION_ALWAYS };
 
@@ -319,6 +330,13 @@ vlc_module_begin ()
                      SYSTRAY_MIDDLE_CLICK_LONGTEXT, false )
                 change_integer_list( i_systray_click_list, psz_systray_click_list_text )
 
+#ifdef Q_WS_X11
+        add_integer( "qt-system-tray-wheel", SYSTRAY_WHEEL_CHANGE_VOLUME,
+                     SYSTRAY_WHEEL_TEXT,
+                     SYSTRAY_WHEEL_LONGTEXT, false )
+                change_integer_list( i_systray_wheel_list, psz_systray_wheel_list_text )
+#endif
+
     cannot_unload_broken_library()
 
     add_submodule ()
diff --git a/modules/gui/qt4/qt4.hpp b/modules/gui/qt4/qt4.hpp
index 3fa5125..324ff12 100644
--- a/modules/gui/qt4/qt4.hpp
+++ b/modules/gui/qt4/qt4.hpp
@@ -57,6 +57,13 @@ enum {
     SYSTRAY_CLICK_TOGGLE_MUTE = 3
 };
 
+enum {
+    SYSTRAY_WHEEL_IGNORE = 0,
+    SYSTRAY_WHEEL_CHANGE_VOLUME = 1,
+    SYSTRAY_WHEEL_CHANGE_TRACK = 2,
+    SYSTRAY_WHEEL_SEEK = 3
+};
+
 enum{
     NOTIFICATION_NEVER = 0,
     NOTIFICATION_MINIMIZED = 1,
-- 
2.0.1




More information about the vlc-devel mailing list