[gnome-music/search] Rebased on master
- From: Vadim Rutkovsky <vrutkovsky src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/search] Rebased on master
- Date: Thu, 27 Jun 2013 16:05:03 +0000 (UTC)
commit af7f7a4ddeedfb721443dcb8e26e255dd101deb6
Author: Vadim Rutkovsky <vrutkovs redhat com>
Date: Thu Jun 27 18:04:55 2013 +0200
Rebased on master
AUTHORS.in | 21 +++
Makefile.am | 26 +++-
autogen.sh | 1 +
data/Makefile.am | 2 +-
libgd | 2 +-
src/application.js | 62 ++++++++
src/grilo.js | 4 +-
src/player.js | 322 +++++++++++++++++++++++++++++++++++++++-
src/toolbar.js | 17 ++
src/window.js | 42 +++++-
tests/Makefile.am | 29 ++--
tests/tests_albumArt.js | 6 +-
tests/tests_albumPlayback.js | 6 +-
tests/tests_artistsPlayback.js | 6 +-
14 files changed, 504 insertions(+), 42 deletions(-)
---
diff --git a/AUTHORS.in b/AUTHORS.in
new file mode 100644
index 0000000..0d897b1
--- /dev/null
+++ b/AUTHORS.in
@@ -0,0 +1,21 @@
+ GNOME Music Authors
+ ===================
+
+GNOME Music was initially written by:
+
+ César García Tapia <cesar garcia tapia openshine com>
+ Seif Lotfy <seif lotfy com>
+ Vadim Rutkovsky <vrutkovs redhat com>
+
+GNOME Music is currently maintained by:
+
+ Seif Lotfy <seif lotfy com>
+ Vadim Rutkovsky <vrutkovs redhat com>
+
+Patches have been received from:
+
+#authorslist#
+
+ ... send patches to get your name here ...
+
+-- End
diff --git a/Makefile.am b/Makefile.am
index 987dab2..f98e024 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,8 +1,17 @@
ACLOCAL_AMFLAGS = -I m4 -I libgd
+NULL =
SUBDIRS = po libgd src data tests
+EXTRA_DIST = \
+ AUTHORS.in \
+ $(NULL)
+
+CLEANFILES = \
+ $(NULL)
+
MAINTAINERCLEANFILES = \
+ $(srcdir)/AUTHORS \
$(srcdir)/INSTALL \
$(srcdir)/aclocal.m4 \
$(srcdir)/autoscan.log \
@@ -15,8 +24,21 @@ MAINTAINERCLEANFILES = \
$(srcdir)/install-sh \
$(srcdir)/ltmain.sh \
$(srcdir)/missing \
- $(srcdir)/mkinstalldirs
+ $(srcdir)/mkinstalldirs \
+ $(NULL)
+
+GITIGNOREFILES = \
+ m4 \
+ $(NULL)
+
+dist-hook: gen-AUTHORS
-GITIGNOREFILES = m4/
+gen-AUTHORS:
+ $(AM_V_GEN)if test -d $(srcdir)/.git; then \
+ out="`cd $(srcdir) && git log --pretty=format:'%aN <%aE>' | sort -u`" && \
+ perl -p -e "s/#authorslist#// and print '$$out'" \
+ < $(srcdir)/AUTHORS.in > $(distdir)/AUTHORS-tmp && \
+ mv -f $(distdir)/AUTHORS-tmp $(distdir)/AUTHORS ; \
+ fi
-include $(top_srcdir)/git.mk
diff --git a/autogen.sh b/autogen.sh
index 5f239c0..6a36f45 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -23,4 +23,5 @@ which gnome-autogen.sh || {
test -d m4 || mkdir m4/ ;
git submodule update --init --recursive ;
)
+touch AUTHORS
. gnome-autogen.sh
diff --git a/data/Makefile.am b/data/Makefile.am
index 960a2cf..4e58aa1 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -50,9 +50,9 @@ gsettings_SCHEMAS = org.gnome.Music.gschema.xml
EXTRA_DIST = \
$(icon_files) \
$(resource_files) \
- CREDITS \
gnome-music.desktop.in \
gnome-music.gresource.xml \
+ org.gnome.Music.gschema.xml \
$(NULL)
CLEANFILES = \
diff --git a/libgd b/libgd
index 3fca3b6..8192ded 160000
--- a/libgd
+++ b/libgd
@@ -1 +1 @@
-Subproject commit 3fca3b6073a25b2c8ed4e16135ff3b17912141b6
+Subproject commit 8192ded5a63aff6f2528576009858bf0d61ec5de
diff --git a/src/application.js b/src/application.js
index fb995ab..73b3157 100644
--- a/src/application.js
+++ b/src/application.js
@@ -40,6 +40,18 @@ var AppState = {
PLAYLIST_NEW: 5
};
+const MediaPlayer2Iface = <interface name="org.mpris.MediaPlayer2">
+ <method name="Raise"/>
+ <method name="Quit"/>
+ <property name="CanQuit" type="b" access="read"/>
+ <property name="CanRaise" type="b" access="read"/>
+ <property name="HasTrackList" type="b" access="read"/>
+ <property name="Identity" type="s" access="read"/>
+ <property name="DesktopEntry" type="s" access="read"/>
+ <property name="SupportedUriSchemes" type="as" access="read"/>
+ <property name="SupportedMimeTypes" type="as" access="read"/>
+</interface>;
+
const Application = new Lang.Class({
Name: 'Music',
Extends: Gtk.Application,
@@ -52,6 +64,11 @@ const Application = new Lang.Class({
});
GLib.set_application_name(_("Music"));
+
+ this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MediaPlayer2Iface, this);
+ this._dbusImpl.export(Gio.DBus.session, '/org/mpris/MediaPlayer2');
+
+ Gio.DBus.session.own_name('org.mpris.MediaPlayer2.gnome-music', Gio.BusNameOwnerFlags.REPLACE, null,
null);
},
_buildAppMenu: function() {
@@ -116,4 +133,49 @@ const Application = new Lang.Class({
this.quit();
}));
},
+
+ /* MPRIS */
+
+ Raise: function() {
+ this._window.present();
+ },
+
+ Quit: function() {
+ this.quit();
+ },
+
+ get CanQuit() {
+ return true;
+ },
+
+ get CanRaise() {
+ return true;
+ },
+
+ get HasTrackList() {
+ return false;
+ },
+
+ get Identity() {
+ return 'Music';
+ },
+
+ get DesktopEntry() {
+ return 'gnome-music';
+ },
+
+ get SupportedUriSchemes() {
+ return [
+ 'file'
+ ];
+ },
+
+ get SupportedMimeTypes() {
+ return [
+ 'application/ogg',
+ 'audio/x-vorbis+ogg',
+ 'audio/x-flac',
+ 'audio/mpeg'
+ ];
+ },
});
diff --git a/src/grilo.js b/src/grilo.js
index e3b55fc..4128f03 100644
--- a/src/grilo.js
+++ b/src/grilo.js
@@ -84,7 +84,7 @@ const Grilo = new Lang.Class({
options.set_count(count);
grilo.tracker.query(
query,
- [Grl.METADATA_KEY_ID, Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_ARTIST,
Grl.METADATA_KEY_CREATION_DATE],
+ [Grl.METADATA_KEY_ID, Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_ARTIST,
Grl.METADATA_KEY_ALBUM, Grl.METADATA_KEY_DURATION, Grl.METADATA_KEY_THUMBNAIL,
Grl.METADATA_KEY_CREATION_DATE],
options,
Lang.bind(this, callback, null));
},
@@ -95,7 +95,7 @@ const Grilo = new Lang.Class({
options.set_flags (Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY);
grilo.tracker.query(
query,
- [Grl.METADATA_KEY_ID, Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_ARTIST,
Grl.METADATA_KEY_CREATION_DATE],
+ [Grl.METADATA_KEY_ID, Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_ARTIST,
Grl.METADATA_KEY_ALBUM, Grl.METADATA_KEY_DURATION, Grl.METADATA_KEY_THUMBNAIL,
Grl.METADATA_KEY_CREATION_DATE],
options,
Lang.bind(this, callback, null));
},
diff --git a/src/player.js b/src/player.js
index be75412..664ab47 100644
--- a/src/player.js
+++ b/src/player.js
@@ -25,6 +25,7 @@ const Gtk = imports.gi.Gtk;
const Gd = imports.gi.Gd;
const Gio = imports.gi.Gio;
const Gst = imports.gi.Gst;
+const GstAudio = imports.gi.GstAudio;
const GstPbutils = imports.gi.GstPbutils;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
@@ -46,6 +47,52 @@ const RepeatType = {
SHUFFLE: 3,
}
+const PropertiesIface = <interface name="org.freedesktop.DBus.Properties">
+<signal name="PropertiesChanged">
+ <arg type="s" direction="out" />
+ <arg type="a{sv}" direction="out" />
+ <arg type="as" direction="out" />
+</signal>
+</interface>;
+const PropertiesProxy = Gio.DBusProxy.makeProxyWrapper(PropertiesIface);
+
+const MediaPlayer2PlayerIface = <interface name="org.mpris.MediaPlayer2.Player">
+ <method name="Next"/>
+ <method name="Previous"/>
+ <method name="Pause"/>
+ <method name="PlayPause"/>
+ <method name="Stop"/>
+ <method name="Play"/>
+ <method name="Seek">
+ <arg direction="in" name="Offset" type="x"/>
+ </method>
+ <method name="SetPosition">
+ <arg direction="in" name="TrackId" type="o"/>
+ <arg direction="in" name="Position" type="x"/>
+ </method>
+ <method name="OpenUri">
+ <arg direction="in" name="Uri" type="s"/>
+ </method>
+ <signal name="Seeked">
+ <arg name="Position" type="x"/>
+ </signal>
+ <property name="PlaybackStatus" type="s" access="read"/>
+ <property name="LoopStatus" type="s" access="readwrite"/>
+ <property name="Rate" type="d" access="readwrite"/>
+ <property name="Shuffle" type="b" access="readwrite"/>
+ <property name="Metadata" type="a{sv}" access="read"/>
+ <property name="Volume" type="d" access="readwrite"/>
+ <property name="Position" type="x" access="read"/>
+ <property name="MinimumRate" type="d" access="read"/>
+ <property name="MaximumRate" type="d" access="read"/>
+ <property name="CanGoNext" type="b" access="read"/>
+ <property name="CanGoPrevious" type="b" access="read"/>
+ <property name="CanPlay" type="b" access="read"/>
+ <property name="CanPause" type="b" access="read"/>
+ <property name="CanSeek" type="b" access="read"/>
+ <property name="CanControl" type="b" access="read"/>
+</interface>;
+
const Player = new Lang.Class({
Name: "Player",
@@ -73,6 +120,9 @@ const Player = new Lang.Class({
}));
this.repeat = this._settings.get_enum('repeat');
+ this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MediaPlayer2PlayerIface, this);
+ this._dbusImpl.export(Gio.DBus.session, '/org/mpris/MediaPlayer2');
+
this.bus.connect("message::state-changed", Lang.bind(this, function(bus, message) {
// Note: not all state changes are signaled through here, in particular
// transitions between Gst.State.READY and Gst.State.NULL are never async
@@ -176,7 +226,7 @@ const Player = new Lang.Class({
case RepeatType.ALL:
previousTrack = currentTrack.copy();
if (!this.playlist.iter_previous(previousTrack))
- nextTrack = this._getIterLast();
+ previousTrack = this._getIterLast();
break;
case RepeatType.NONE:
@@ -234,8 +284,14 @@ const Player = new Lang.Class({
},
_syncPrevNext: function() {
- this.nextBtn.sensitive = this._hasNext();
- this.prevBtn.sensitive = this._hasPrevious();
+ let hasNext = this._hasNext()
+ let hasPrevious = this._hasPrevious()
+
+ this.nextBtn.sensitive = hasNext;
+ this.prevBtn.sensitive = hasPrevious;
+
+ this._dbusImpl.emit_property_changed('CanGoNext', GLib.Variant.new('b', hasNext));
+ this._dbusImpl.emit_property_changed('CanGoPrevious', GLib.Variant.new('b', hasPrevious));
},
setPlaying: function(bool) {
@@ -245,6 +301,9 @@ const Player = new Lang.Class({
this.play();
else
this.pause();
+
+ let media = this.playlist.get_value(this.currentTrack, this.playlistField);
+ this.playBtn.set_image(this._pauseImage);
},
load: function(media) {
@@ -294,11 +353,18 @@ const Player = new Lang.Class({
this.player.nextUrl = null;
}
+ this._dbusImpl.emit_property_changed('Metadata', GLib.Variant.new('a{sv}', this.Metadata));
+ this._dbusImpl.emit_property_changed('CanPlay', GLib.Variant.new('b', true));
+ this._dbusImpl.emit_property_changed('CanPause', GLib.Variant.new('b', true));
+
this.emit("playlist-item-changed", this.playlist, this.currentTrack);
this.emit('current-changed');
},
play: function() {
+ if (this.playlist == null)
+ return;
+
if (this.player.get_state(1)[1] != Gst.State.PAUSED)
this.stop();
@@ -308,6 +374,8 @@ const Player = new Lang.Class({
this._updatePositionCallback();
if (!this.timeout)
this.timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, Lang.bind(this,
this._updatePositionCallback));
+
+ this._dbusImpl.emit_property_changed('PlaybackStatus', GLib.Variant.new('s', 'Playing'));
},
pause: function () {
@@ -317,6 +385,7 @@ const Player = new Lang.Class({
}
this.player.set_state(Gst.State.PAUSED);
+ this._dbusImpl.emit_property_changed('PlaybackStatus', GLib.Variant.new('s', 'Paused'));
},
stop: function() {
@@ -326,25 +395,36 @@ const Player = new Lang.Class({
}
this.player.set_state(Gst.State.NULL);
+ this._dbusImpl.emit_property_changed('PlaybackStatus', GLib.Variant.new('s', 'Stopped'));
this.emit('playing-changed');
},
playNext: function() {
+ if (this.playlist == null)
+ return;
+
+ if (!this.nextBtn.sensitive)
+ return;
+
+ this.stop();
this.currentTrack = this._getNextTrack();
if (this.currentTrack)
this.play();
- else
- this.stop();
},
playPrevious: function() {
+ if (this.playlist == null)
+ return;
+
+ if (!this.prevBtn.sensitive)
+ return;
+
+ this.stop();
this.currentTrack = this._getPreviousTrack();
if (this.currentTrack)
this.play();
- else
- this.stop();
},
setPlaylist: function (type, id, model, iter, field) {
@@ -478,20 +558,248 @@ const Player = new Lang.Class({
}
this.repeatBtnImage.icon_name = icon;
+ this._dbusImpl.emit_property_changed('LoopStatus', GLib.Variant.new('s', this.LoopStatus));
+ this._dbusImpl.emit_property_changed('Shuffle', GLib.Variant.new('b', this.Shuffle));
},
onProgressScaleChangeValue: function(scroll) {
var seconds = scroll.get_value() / 60;
if (seconds != this.duration) {
this.player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, seconds *
1000000000);
+ this._dbusImpl.emit_signal('Seeked', GLib.Variant.new('(x)', [seconds * 1000000]));
} else {
let duration = this.player.query_duration(Gst.Format.TIME, null);
if (duration) {
// Rewind a second back before the track end
this.player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT,
duration[1]-1000000000);
+ this._dbusImpl.emit_signal('Seeked', GLib.Variant.new('(x)',
[(duration[1]-1000000000)/1000]));
}
}
return true;
},
+
+ /* MPRIS */
+
+ Next: function() {
+ this.playNext();
+ },
+
+ Previous: function() {
+ this.playPrevious();
+ },
+
+ Pause: function() {
+ this.setPlaying(false);
+ },
+
+ PlayPause: function() {
+ if (this.player.get_state(1)[1] == Gst.State.PLAYING){
+ this.setPlaying(false);
+ } else {
+ this.setPlaying(true);
+ }
+ },
+
+ Play: function() {
+ this.setPlaying(true);
+ },
+
+ Stop: function() {
+ this.progressScale.set_value(0);
+ this.progressScale.sensitive = false;
+ this.playBtn.set_image(this._playImage);
+ this.stop();
+ },
+
+ SeekAsync: function(params, invocation) {
+ let [offset] = params;
+
+ let duration = this.player.query_duration(Gst.Format.TIME, null);
+ if (!duration)
+ return;
+
+ if (offset < 0) {
+ offset = 0;
+ }
+
+ if (duration[1] >= offset * 1000) {
+ this.player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, offset *
1000);
+ this._dbusImpl.emit_signal('Seeked', GLib.Variant.new('(x)', [offset]));
+ } else {
+ this.playNext();
+ }
+ },
+
+ SetPositionAsync: function(params, invocation) {
+ let [trackId, position] = params;
+
+ if (this.currentTrack == null)
+ return;
+
+ let media = this.playlist.get_value(this.currentTrack, this.playlistField);
+ if (trackId != '/org/mpris/MediaPlayer2/Track/' + media.get_id())
+ return;
+
+ let duration = this.player.query_duration(Gst.Format.TIME, null);
+ if (duration && position >= 0 && duration[1] >= position * 1000) {
+ this.player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, position
* 1000);
+ this._dbusImpl.emit_signal('Seeked', GLib.Variant.new('(x)', [position]));
+ }
+ },
+
+ OpenUriAsync: function(params, invocation) {
+ let [uri] = params;
+ },
+
+ get PlaybackStatus() {
+ let [ok, state, pending] = this.player.get_state(0);
+ if (ok == Gst.StateChangeReturn.ASYNC)
+ state = pending;
+ else if (ok != Gst.StateChangeReturn.SUCCESS)
+ return 'Stopped';
+
+ if (state == Gst.State.PLAYING) {
+ return 'Playing';
+ } else if (state == Gst.State.PAUSED) {
+ return 'Paused';
+ } else {
+ return 'Stopped';
+ }
+ },
+
+ get LoopStatus() {
+ if (this.repeat == RepeatType.NONE) {
+ return 'None';
+ } else if (this.repeat == RepeatType.SONG) {
+ return 'Track';
+ } else {
+ return 'Playlist';
+ }
+ },
+
+ set LoopStatus(mode) {
+ if (mode == 'None') {
+ this.repeat = RepeatType.NONE;
+ } else if (mode == 'Track') {
+ this.repeat = RepeatType.SONG;
+ } else if (mode == 'Playlist') {
+ this.repeat = RepeatType.ALL;
+ }
+ this._syncRepeatImage();
+ },
+
+ get Rate() {
+ return 1.0;
+ },
+
+ set Rate(rate) {
+ },
+
+ get Shuffle() {
+ return this.repeat == RepeatType.SHUFFLE;
+ },
+
+ set Shuffle(enable) {
+ if (enable && this.repeat != RepeatType.SHUFFLE) {
+ this.repeat = RepeatType.SHUFFLE;
+ } else if (!enable && this.repeat == RepeatType.SHUFFLE) {
+ this.repeat = RepeatType.NONE;
+ }
+ this._syncRepeatImage();
+ },
+
+ get Metadata() {
+ if (this.currentTrack == null)
+ return {};
+
+ let media = this.playlist.get_value(this.currentTrack, this.playlistField);
+ let metadata = {
+ 'mpris:trackid': GLib.Variant.new('s', '/org/mpris/MediaPlayer2/Track/' + media.get_id()),
+ 'xesam:url': GLib.Variant.new('s', media.get_url()),
+ 'mpris:length': GLib.Variant.new('x', media.get_duration()*1000000),
+ 'xesam:trackNumber': GLib.Variant.new('i', media.get_track_number()),
+ 'xesam:useCount': GLib.Variant.new('i', media.get_play_count()),
+ 'xesam:userRating': GLib.Variant.new('d', media.get_rating()),
+ };
+
+ let title = media.get_title();
+ if (title) {
+ metadata['xesam:title'] = GLib.Variant.new('s', title);
+ }
+
+ let album = media.get_album();
+ if (album) {
+ metadata['xesam:album'] = GLib.Variant.new('s', album);
+ }
+
+ let artist = media.get_artist();
+ if (artist) {
+ metadata['xesam:artist'] = GLib.Variant.new('as', [artist]);
+ metadata['xesam:albumArtist'] = GLib.Variant.new('as', [artist]);
+ }
+
+ let genre = media.get_genre();
+ if (genre) {
+ metadata['xesam:genre'] = GLib.Variant.new('as', [genre]);
+ }
+
+ let last_played = media.get_last_played();
+ if (last_played) {
+ metadata['xesam:lastUsed'] = GLib.Variant.new('s', last_played);
+ }
+
+ let thumbnail = media.get_thumbnail();
+ if (thumbnail) {
+ metadata['mpris:artUrl'] = GLib.Variant.new('s', thumbnail);
+ }
+
+ return metadata;
+ },
+
+ get Volume() {
+ return this.player.get_volume(GstAudio.StreamVolumeFormat.LINEAR);
+ },
+
+ set Volume(rate) {
+ this.player.set_volume(GstAudio.StreamVolumeFormat.LINEAR, rate);
+ this._dbusImpl.emit_property_changed('Volume', GLib.Variant.new('d', rate));
+ },
+
+ get Position() {
+ return this.player.query_position(Gst.Format.TIME, null)[1]/1000;
+ },
+
+ get MinimumRate() {
+ return 1.0;
+ },
+
+ get MaximumRate() {
+ return 1.0;
+ },
+
+ get CanGoNext() {
+ return this._hasNext();
+ },
+
+ get CanGoPrevious() {
+ return this._hasPrevious();
+ },
+
+ get CanPlay() {
+ return this.currentTrack != null;
+ },
+
+ get CanPause() {
+ return this.currentTrack != null;
+ },
+
+ get CanSeek() {
+ return true;
+ },
+
+ get CanControl() {
+ return true;
+ },
+
});
Signals.addSignalMethods(Player.prototype);
diff --git a/src/toolbar.js b/src/toolbar.js
index fca41ee..71dc9cd 100644
--- a/src/toolbar.js
+++ b/src/toolbar.js
@@ -49,6 +49,7 @@ const Toolbar = new Lang.Class({
this._addBackButton();
this._addSearchButton();
this._addSelectButton();
+ this._addCloseButton();
},
set_stack: function(stack) {
@@ -91,6 +92,14 @@ const Toolbar = new Lang.Class({
this._backButton.show();
else
this._backButton.hide();
+
+ if (this._selectionMode) {
+ this._closeSeparator.hide();
+ this._closeButton.hide();
+ } else {
+ this._closeSeparator.show();
+ this._closeButton.show();
+ }
},
_addBackButton: function() {
@@ -115,6 +124,14 @@ const Toolbar = new Lang.Class({
label: _("Select") });
this.pack_end(this._selectButton);
this._selectButton.show();
+ },
+
+ _addCloseButton: function() {
+ this._closeSeparator = new Gtk.Separator({ orientation: Gtk.Orientation.VERTICAL });
+ this.pack_end(this._closeSeparator);
+
+ this._closeButton = new Gd.HeaderCloseButton();
+ this.pack_end(this._closeButton);
}
});
Signals.addSignalMethods(Toolbar.prototype);
diff --git a/src/window.js b/src/window.js
index aed4eda..d695469 100644
--- a/src/window.js
+++ b/src/window.js
@@ -44,14 +44,53 @@ const MainWindow = new Lang.Class({
application: app,
title: _('Music'),
window_position: Gtk.WindowPosition.CENTER,
- hide_titlebar_when_maximized: true
});
+ this.connect('focus-in-event', Lang.bind(this, this._windowsFocusCb));
let settings = new Gio.Settings({ schema: 'org.gnome.Music' });
this.add_action(settings.create_action('repeat'));
this.set_size_request(887, 640);
this._setupView();
+
+ this.proxy = Gio.DBusProxy.new_sync(Gio.bus_get_sync(Gio.BusType.SESSION, null),
+ Gio.DBusProxyFlags.NONE,
+ null,
+ 'org.gnome.SettingsDaemon',
+ '/org/gnome/SettingsDaemon/MediaKeys',
+ 'org.gnome.SettingsDaemon.MediaKeys',
+ null);
+ this.proxy.call_sync('GrabMediaPlayerKeys',
+ GLib.Variant.new('(su)', 'Music'),
+ Gio.DBusCallFlags.NONE,
+ -1,
+ null);
+ this.proxy.connect('g-signal', Lang.bind(this, this._handleMediaKeys));
+ },
+
+ _windowsFocusCb: function(window, event) {
+ this.proxy.call_sync('GrabMediaPlayerKeys',
+ GLib.Variant.new('(su)', 'Music'),
+ Gio.DBusCallFlags.NONE,
+ -1,
+ null);
+ },
+
+ _handleMediaKeys: function(proxy, sender, signal, parameters) {
+ if (signal != 'MediaPlayerKeyPressed') {
+ log ('Received an unexpected signal \'%s\' from media player'.format(signal));
+ return;
+ }
+
+ let key = parameters.get_child_value(1).get_string()[0];
+ if (key == 'Play')
+ this.player.PlayPause();
+ else if (key == 'Stop')
+ this.player.Stop();
+ else if (key == 'Next')
+ this.player.Next();
+ else if (key == 'Previous')
+ this.player.Previous();
},
_setupView: function () {
@@ -63,6 +102,7 @@ const MainWindow = new Lang.Class({
this.player = new Player.Player();
this.toolbar = new Toolbar.Toolbar();
+ this.set_titlebar(this.toolbar);
this._stack = new Gtk.Stack({
transition_type: Gtk.StackTransitionType.CROSSFADE,
transition_duration: 100,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e0c46a1..ae347dd 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,18 +1,21 @@
TESTS = \
- tests_albumArt.js \
- tests_albumPlayback.js \
- tests_artistsPlayback.js \
- $(NULL)
+ tests_albumArt.js \
+ tests_albumPlayback.js \
+ tests_artistsPlayback.js \
+ $(NULL)
+
+EXTRA_DIST = $(TESTS)
+
+TESTS_ENVIRONMENT = \
+ LD_LIBRARY_PATH=$(top_builddir)/libgd/.libs:$$LD_LIBRARY_PATH \
+ GI_TYPELIB_PATH=$(top_builddir)/libgd:$$GI_TYPELIB_PATH
check-TESTS:
- @RUN_TESTS_ENV_VARS= \
- LD_LIBRARY_PATH=$(top_srcdir)/libgd/.libs:$$LD_LIBRARY_PATH \
- GI_TYPELIB_PATH=$(top_srcdir)/libgd:$$GI_TYPELIB_PATH ; \
- for test in $(TESTS) ; do \
- echo "Running suite $$test" ; \
- $(RUN_TESTS_ENV_VARS) gjs $$test ; \
- status=$$? ; \
- if [[ $$status -ne 0 ]] ; then exit 1 ; fi ; \
- done
+ for test in $(TESTS) ; do \
+ echo "Running suite $$test" ; \
+ $(TESTS_ENVIRONMENT) gjs --include-path=$(top_srcdir)/src $(srcdir)/$$test ; \
+ status=$$? ; \
+ if [[ $$status -ne 0 ]] ; then exit 1 ; fi ; \
+ done
-include $(top_srcdir)/git.mk
diff --git a/tests/tests_albumArt.js b/tests/tests_albumArt.js
index 224a115..e0835e5 100755
--- a/tests/tests_albumArt.js
+++ b/tests/tests_albumArt.js
@@ -4,11 +4,7 @@ if (!('assertEquals' in this)) { /* allow running this test standalone */
gjstestRun = function() { return imports.jsUnit.gjstestRun(window); };
}
-imports.searchPath.unshift('..');
-imports.searchPath.unshift('../src');
-imports.searchPath.unshift('../libgd');
-imports.searchPath.unshift('../data');
-const AlbumArtCache = imports.src.albumArtCache.AlbumArtCache
+const AlbumArtCache = imports.albumArtCache.AlbumArtCache
const GLib = imports.gi.GLib;
const Lang = imports.lang;
diff --git a/tests/tests_albumPlayback.js b/tests/tests_albumPlayback.js
index 31eb330..b927eec 100644
--- a/tests/tests_albumPlayback.js
+++ b/tests/tests_albumPlayback.js
@@ -4,10 +4,6 @@ if (!('assertEquals' in this)) { /* allow running this test standalone */
gjstestRun = function() { return imports.jsUnit.gjstestRun(window); };
}
-imports.searchPath.unshift('..');
-imports.searchPath.unshift('../src');
-imports.searchPath.unshift('../libgd');
-imports.searchPath.unshift('../data');
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Gdk = imports.gi.Gdk;
@@ -37,7 +33,7 @@ function getAlbumView() {
let player = new Player.Player();
let stack = new Gtk.Stack();
toolbar.set_stack(stack);
- view = new AlbumView(toolbar, player);
+ let view = new AlbumView(toolbar, player);
stack.add_titled(view, "Albums", "Albums");
stack.set_visible_child_name('Albums');
return view;
diff --git a/tests/tests_artistsPlayback.js b/tests/tests_artistsPlayback.js
index 3393c31..8a73e17 100644
--- a/tests/tests_artistsPlayback.js
+++ b/tests/tests_artistsPlayback.js
@@ -4,10 +4,6 @@ if (!('assertEquals' in this)) { /* allow running this test standalone */
gjstestRun = function() { return imports.jsUnit.gjstestRun(window); };
}
-imports.searchPath.unshift('..');
-imports.searchPath.unshift('../src');
-imports.searchPath.unshift('../libgd');
-imports.searchPath.unshift('../data');
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Gdk = imports.gi.Gdk;
@@ -37,7 +33,7 @@ function getArtistView() {
let player = new Player.Player();
let stack = new Gtk.Stack();
toolbar.set_stack(stack);
- view = new ArtistView(toolbar, player);
+ let view = new ArtistView(toolbar, player);
stack.add_titled(view, "Artists", "Artists");
stack.set_visible_child_name('Artists');
return view;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]