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)
All engines do this, by design :)
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.
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.
GStreamer engine is no longer supported in current Amarok releases. Hence closing the report.
The xine engine does the same thing. Please reopen this.
Reproducible with current svn.
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();