Bug 116101 - DCOP pause call does playPause instead
Summary: DCOP pause call does playPause instead
Status: RESOLVED FIXED
Alias: None
Product: amarok
Classification: Applications
Component: general (show other bugs)
Version: 1.3.5
Platform: Debian testing Linux
: NOR normal
Target Milestone: ---
Assignee: Amarok Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-11-10 23:28 UTC by Isaac Wilcox
Modified: 2006-11-06 02:53 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Isaac Wilcox 2005-11-10 23:28:57 UTC
Version:           1.3.5 (using KDE KDE 3.4.2)
Installed from:    Debian testing/unstable Packages
OS:                Linux

Hi folks,

Thanks for amarok.  It's one of very few Linux apps I feel I can really show off to people.

If you're using the gstreamer engine and amarok is paused, and you run:
  dcop amarok player pause
amarok will start playing, because it acts as a toggle.  The "pause" call should be a no-op if already paused at the engine level, because "playPause" already caters for toggling in EngineController::playPause() in an engine-independent way:

    if( m_engine->state() == Engine::Playing )
    {
        pause();
    }
    else play();

but the gstreamer engine interface effectively does a playPause in GstEngine::pause():

    if ( GST_STATE( m_gst_thread ) == GST_STATE_PAUSED ) {
        gst_element_set_state( m_gst_thread, GST_STATE_PLAYING );
        emit stateChanged( Engine::Playing );
    }
    else {
        gst_element_set_state( m_gst_thread, GST_STATE_PAUSED );
        emit stateChanged( Engine::Paused );
    }

This is preventing me from using the pause-amarok-using-dcop-when-I-lock-the-screen technique described in http://bugs.kde.org/show_bug.cgi?id=83244#c2 (because if I'm paused, locking the screen will start my music playing - d'oh!).  I thought this would be as simple as changing gstengine.cpp:

--- amarok-1.3.6/amarok/src/engine/gst/gstengine.cpp.orig       2005-11-10 20:22:47.000000000 +0000
+++ amarok-1.3.6/amarok/src/engine/gst/gstengine.cpp    2005-11-10 20:23:52.000000000 +0000
@@ -547,11 +547,7 @@
     DEBUG_BLOCK
     RETURN_IF_PIPELINE_EMPTY

-    if ( GST_STATE( m_gst_thread ) == GST_STATE_PAUSED ) {
-        gst_element_set_state( m_gst_thread, GST_STATE_PLAYING );
-        emit stateChanged( Engine::Playing );
-    }
-    else {
+    if ( GST_STATE( m_gst_thread ) != GST_STATE_PAUSED ) {
         gst_element_set_state( m_gst_thread, GST_STATE_PAUSED );
         emit stateChanged( Engine::Paused );
     }

But this patch didn't seem to fix the problem (AFAICT the m_engine->pause() call resulting from the DCOP call doesn't call through the function I patched, but goes straight into the gstreamer library).  At this point I ran out of steam.

Any help would be much appreciated.

Thanks in advance,

Zak (Isaac Wilcox)
Comment 1 Mark Kretschmann 2005-11-10 23:35:12 UTC
All engines do this, by design :)
Comment 2 Isaac Wilcox 2005-11-10 23:49:30 UTC
OK, but that's not really relevant to apps (or people) using the DCOP call at amarok's level.  If amarok provides a both a playPause() call and a pause() call then the expected behaviour of the pause() call is to do whatever's necessary to pause the current track (which may be nothing).  If it does anything different, it's going against expected behaviour.

So, maybe it's the case that a bug should be filed against the relevant engine(s) asking for two separate calls to enable this functionality in amarok - but the bug against amarok still remains valid as long as the DCOP interface provides both functions.
Comment 3 Kevin Radloff 2006-06-28 19:46:03 UTC
I agree that this is quite an annoying misfeature, but on the bright side you can work around the issue by using "dcop amarok player status" to find the state of amaroK in your script. 2 == play, it seems.
Comment 4 Mark Kretschmann 2006-11-05 17:51:20 UTC
GStreamer engine is no longer supported in current Amarok releases. Hence closing the report.
Comment 5 Kevin Radloff 2006-11-05 18:03:21 UTC
The xine engine does the same thing. Please reopen this.
Comment 6 Martin Aumueller 2006-11-05 18:32:30 UTC
Reproducible with current svn.
Comment 7 Martin Aumueller 2006-11-06 02:53:38 UTC
SVN commit 602460 by aumuell:

don't make pause acting as playPause
- engines need to implement unpause instead of pause doing unpause when paused
BUG: 116101


 M  +1 -0      ChangeLog  
 M  +2 -2      src/app.cpp  
 M  +11 -1     src/engine/helix/helix-engine.cpp  
 M  +1 -0      src/engine/helix/helix-engine.h  
 M  +1 -0      src/engine/void/void-engine.h  
 M  +10 -1     src/engine/xine/xine-engine.cpp  
 M  +1 -0      src/engine/xine/xine-engine.h  
 M  +4 -1      src/enginebase.h  
 M  +8 -2      src/enginecontroller.cpp  
 M  +1 -1      src/playlist.cpp  


--- trunk/extragear/multimedia/amarok/ChangeLog #602459:602460
@@ -16,6 +16,7 @@
     * Amarok now saves playlists with relative paths by default.
 
   BUGFIXES:
+    * Pause would act as Play/Pause. (BR 116101)
     * The same track would sometimes be shown twice in suggested songs
       (BR 129395)
     * Detect vfat partitioned devices on FreeBSD. Patch by Daniel
--- trunk/extragear/multimedia/amarok/src/app.cpp #602459:602460
@@ -360,9 +360,9 @@
 
     m_pGlobalAccel->insert( "play", i18n( "Play" ), 0, KKey("WIN+x"), 0,
                             ec, SLOT( play() ), true, true );
-    m_pGlobalAccel->insert( "pause", i18n( "Pause" ), 0, KKey("WIN+c"), 0,
+    m_pGlobalAccel->insert( "pause", i18n( "Pause" ), 0, 0, 0,
                             ec, SLOT( pause() ), true, true );
-    m_pGlobalAccel->insert( "play_pause", i18n( "Play/Pause" ), 0, 0, 0,
+    m_pGlobalAccel->insert( "play_pause", i18n( "Play/Pause" ), 0, KKey("WIN+c"), 0,
                             ec, SLOT( playPause() ), true, true );
     m_pGlobalAccel->insert( "stop", i18n( "Stop" ), 0, KKey("WIN+v"), 0,
                             ec, SLOT( stop() ), true, true );
--- trunk/extragear/multimedia/amarok/src/engine/helix/helix-engine.cpp #602459:602460
@@ -450,7 +450,17 @@
       m_state = Engine::Paused;
       emit stateChanged( Engine::Paused );
    }
-   else if ( m_state == Engine::Paused )
+}
+
+void
+HelixEngine::unpause()
+{
+   if (!m_inited)
+      return;
+
+   // TODO: PAUSE in XFADE
+   debug() << "In unpause\n";
+   if ( m_state == Engine::Paused )
    {
       PlayerControl::resume(m_current);
       m_state = Engine::Playing;
--- trunk/extragear/multimedia/amarok/src/engine/helix/helix-engine.h #602459:602460
@@ -48,6 +48,7 @@
    virtual bool play( uint = 0 );
    virtual void stop();
    virtual void pause();
+   virtual void unpause();
    virtual void seek( uint );
 
    virtual void setEqualizerEnabled( bool );
--- trunk/extragear/multimedia/amarok/src/engine/void/void-engine.h #602459:602460
@@ -28,6 +28,7 @@
     virtual bool play( uint ) { return false; }
     virtual void stop() {}
     virtual void pause() {}
+    virtual void unpause() {}
     virtual void setVolumeSW( uint ) {}
     virtual void seek( uint ) {}
 
--- trunk/extragear/multimedia/amarok/src/engine/xine/xine-engine.cpp #602459:602460
@@ -393,8 +393,17 @@
         xine_set_param( m_stream, XINE_PARAM_AUDIO_CLOSE_DEVICE, 1);
         emit stateChanged( Engine::Paused );
 
-    } else {
+    }
+}
 
+void
+XineEngine::unpause()
+{
+    if ( !m_stream )
+        return;
+    
+    if( xine_get_param( m_stream, XINE_PARAM_SPEED ) == XINE_SPEED_PAUSE )
+    {
         if( s_fader && s_fader->running() )
             s_fader->resume();
 
--- trunk/extragear/multimedia/amarok/src/engine/xine/xine-engine.h #602459:602460
@@ -37,6 +37,7 @@
     virtual bool play( uint = 0 );
     virtual void stop();
     virtual void pause();
+    virtual void unpause();
     virtual uint position() const;
     virtual uint length() const;
     virtual void seek( uint );
--- trunk/extragear/multimedia/amarok/src/enginebase.h #602459:602460
@@ -136,7 +136,10 @@
         /** Pauses playback */
         virtual void pause() = 0;
 
-        /**
+        /** Resumes playback if paused */
+        virtual void unpause() = 0;
+
+         /**
          * Get current engine status.
          * @return the correct State as described at the enum
          */
--- trunk/extragear/multimedia/amarok/src/enginecontroller.cpp #602459:602460
@@ -329,7 +329,7 @@
 {
     if ( m_engine->state() == Engine::Paused )
     {
-        m_engine->pause();
+        m_engine->unpause();
     }
     else emit orderCurrent();
 }
@@ -521,7 +521,13 @@
     {
         pause();
     }
-    else play();
+    else if( m_engine->state() == Engine::Paused )
+    {
+        if ( m_engine->loaded() )
+            m_engine->unpause();
+    }
+    else
+        play();
 }
 
 
--- trunk/extragear/multimedia/amarok/src/playlist.cpp #602459:602460
@@ -2263,7 +2263,7 @@
         break;
 
     case Engine::Paused:
-        Amarok::actionCollection()->action( "pause" )->setEnabled( true );
+        Amarok::actionCollection()->action( "pause" )->setEnabled( false );
         Amarok::actionCollection()->action( "stop" )->setEnabled( true );
 
         Glow::reset();