[goobox] removed all the deprecated functions



commit d1031706237176975e26498a4630cad72b5770a3
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Wed Dec 25 18:46:03 2013 +0100

    removed all the deprecated functions

 configure.ac                            |   48 ++-
 copy-n-paste/Makefile.am                |   29 +-
 po/POTFILES.in                          |   22 +-
 src/Makefile.am                         |   35 +-
 src/actions.c                           |  410 -------------
 src/actions.h                           |   55 --
 src/dlg-cover-chooser.c                 |   10 +-
 src/dlg-extract.c                       |    7 +-
 src/dlg-properties.c                    |   13 +-
 src/dlg-ripper.c                        |    2 +-
 src/glib-utils.c                        |   14 +
 src/glib-utils.h                        |    4 +
 src/goo-application-actions-callbacks.c |  161 +++++
 src/goo-application-actions-callbacks.h |   39 ++
 src/goo-application-actions-entries.h   |   43 ++
 src/goo-application.c                   |  564 ++++++++++++++++++
 src/goo-application.h                   |   51 ++
 src/goo-player-bar.c                    |  105 ++--
 src/goo-player-bar.h                    |    6 +-
 src/goo-player-info.c                   |   24 +-
 src/goo-stock.c                         |  183 ------
 src/goo-stock.h                         |   48 --
 src/goo-window-actions-callbacks.c      |  361 +++++++++++
 src/goo-window-actions-callbacks.h      |   52 ++
 src/goo-window-actions-entries.h        |   70 +++
 src/goo-window.c                        |  346 +++++-------
 src/goo-window.h                        |    5 +-
 src/goobox.gresource.xml                |    3 +-
 src/gth-toggle-menu-action.c            |  238 --------
 src/gth-toggle-menu-action.h            |   64 --
 src/gth-toggle-menu-tool-button.c       |  984 -------------------------------
 src/gth-toggle-menu-tool-button.h       |   85 ---
 src/gth-window.c                        |  526 -----------------
 src/gth-window.h                        |  107 ----
 src/gtk-utils.c                         |  251 ++++++++-
 src/gtk-utils.h                         |   64 ++-
 src/main.c                              |  700 +---------------------
 src/main.h                              |    4 +-
 src/ui.h                                |  157 -----
 src/ui/Makefile.am                      |    3 +-
 src/ui/app-menu.ui                      |    1 -
 src/ui/cover-chooser.ui                 |    9 +-
 src/ui/extract.ui                       |   10 +-
 src/ui/gears-menu.ui                    |   28 +
 src/ui/menu-toolbars.ui                 |   38 --
 src/ui/menus.ui                         |   40 ++
 src/ui/properties.ui                    |   11 +-
 47 files changed, 2063 insertions(+), 3967 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 55f8c2f..c125cad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@ GTK_REQUIRED=3.8.0
 GSTREAMER_REQUIRED=1.0.0
 LIBNOTIFY_REQUIRED=0.4.3
 LIBMUSICBRAINZ5_REQUIRED=5.0.0
-LIBCOVERART_REQUIRED=1.0.0beta1
+LIBCOVERART_REQUIRED=1.0.0
 
 dnl ===========================================================================
 
@@ -36,17 +36,15 @@ PKG_CHECK_MODULES(GOO, [
        libbrasero-media3
        libmusicbrainz5 >= $LIBMUSICBRAINZ5_REQUIRED
        libdiscid
-       ice
-       sm
 ])
 AC_SUBST(GOO_CFLAGS)
 AC_SUBST(GOO_LIBS)
 
 dnl ===========================================================================
 
-AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal)
-AC_PATH_PROG(GLIB_MKENUMS, glib-mkenums)
-AC_PATH_PROG(GLIB_COMPILE_RESOURCES, glib-compile-resources)
+AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal, glib-genmarshal)
+AC_PATH_PROG(GLIB_MKENUMS, glib-mkenums, glib-mkenums)
+AC_PATH_PROG(GLIB_COMPILE_RESOURCES, glib-compile-resources, glib-compile-resources)
 
 dnl ===========================================================================
 
@@ -174,6 +172,43 @@ AC_MSG_RESULT($enable_media_keys)
 
 dnl ===========================================================================
 
+GDK_TARGET="$($PKG_CONFIG --variable targets gdk-3.0)"
+
+AC_MSG_CHECKING([which smclient backend to use])
+AC_ARG_WITH([smclient],
+  [AS_HELP_STRING([--with-smclient=no|auto|xsmp],
+                  [Setting smclient backend (default:no)])],,
+                  [with_smclient=no])
+
+if test "$with_smclient" == "auto"; then
+  case "$GDK_TARGET" in
+    *x11*) with_smclient=xsmp ;;
+    *) with_smclient=no ;;
+  esac
+fi
+
+AC_MSG_RESULT([$with_smclient])
+
+if test "$with_smclient" != "no"; then
+  AC_DEFINE([WITH_SMCLIENT],[1],[Define if smclient is enabled])
+
+  case "$with_smclient" in
+    xsmp) SMCLIENT_PKGS="sm >= 1.0.0 ice" ;;
+    *) SMCLIENT_PKGS="" ;;
+  esac
+
+  PKG_CHECK_MODULES([SMCLIENT],[$SMCLIENT_PKGS])
+  AC_SUBST([SMCLIENT_CFLAGS])
+  AC_SUBST([SMCLIENT_LIBS])
+  AC_DEFINE(USE_SMCLIENT, 1, [Use a session menager])
+fi
+
+AM_CONDITIONAL([WITH_SMCLIENT],[test "$with_smclient" != "no"])
+AM_CONDITIONAL([WITH_SMCLIENT_XSMP],[test "$with_smclient" = "xsmp"])
+AM_CONDITIONAL([WITH_SMCLIENT_WIN32],[test "$with_smclient" = "win32"])
+
+dnl ===========================================================================
+
 SYSTEM_LIBS=""
 host=`uname -s`
 case "$host" in
@@ -258,4 +293,5 @@ Configuration:
        Enable notification  : ${enable_notification}
        Enable media keys    : ${enable_media_keys}
        Use libcoverart      : ${enable_libcoverart}
+       SM client support    : ${with_smclient}
 "
diff --git a/copy-n-paste/Makefile.am b/copy-n-paste/Makefile.am
index 1e5a0ce..8ce79a5 100644
--- a/copy-n-paste/Makefile.am
+++ b/copy-n-paste/Makefile.am
@@ -6,13 +6,26 @@ AM_CPPFLAGS =                                 \
 
 noinst_LTLIBRARIES = libeggsmclient.la
 
-libeggsmclient_la_LIBADD = $(GTK_LIBS)
-libeggsmclient_la_CFLAGS = $(GTK_CFLAGS)
-libeggsmclient_la_SOURCES = eggdesktopfile.h \
-                           eggdesktopfile.c \
-                           eggsmclient.h \
-                           eggsmclient.c \
-                           eggsmclient-private.h \
-                           eggsmclient-xsmp.c
+libeggsmclient_la_LIBADD =                     \
+       $(SMCLIENT_LIBS)                        \
+       $(GTK_LIBS)
+       
+libeggsmclient_la_CFLAGS =                     \
+       -DG_LOG_DOMAIN=\""EggSMClient"\"        \
+       -DEGG_SM_CLIENT_BACKEND_XSMP            \
+       $(SMCLIENT_CFLAGS)                      \
+       $(GTK_CFLAGS)
+
+libeggsmclient_la_SOURCES =                     \
+       eggdesktopfile.h                        \
+       eggdesktopfile.c
+
+if WITH_SMCLIENT
+libeggsmclient_la_SOURCES +=                    \
+       eggsmclient.h                           \
+       eggsmclient.c                           \
+       eggsmclient-private.h                   \
+       eggsmclient-xsmp.c
+endif
 
 -include $(top_srcdir)/git.mk
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9dec552..9005e29 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -9,8 +9,6 @@ copy-n-paste/eggsmclient-private.h
 copy-n-paste/eggsmclient-xsmp.c
 data/goobox.desktop.in.in
 data/org.gnome.Goobox.gschema.xml.in
-src/actions.c
-src/actions.h
 src/album-info.c
 src/album-info.h
 src/dlg-cover-chooser.c
@@ -30,6 +28,11 @@ src/glib-utils.h
 src/gnome-desktop-thumbnail.c
 src/gnome-desktop-thumbnail.h
 src/gnome-thumbnail-pixbuf-utils.c
+src/goo-application-actions-callbacks.c
+src/goo-application-actions-callbacks.h
+src/goo-application-actions-entries.h
+src/goo-application.c
+src/goo-application.h
 src/goo-error.c
 src/goo-error.h
 src/goo-player-bar.c
@@ -38,18 +41,13 @@ src/goo-player.c
 src/goo-player.h
 src/goo-player-info.c
 src/goo-player-info.h
-src/goo-stock.c
-src/goo-stock.h
+src/goo-window-actions-callbacks.c
+src/goo-window-actions-callbacks.h
+src/goo-window-actions-entries.h
 src/goo-window.c
 src/goo-window.h
-src/gth-toggle-menu-action.c
-src/gth-toggle-menu-action.h
-src/gth-toggle-menu-tool-button.c
-src/gth-toggle-menu-tool-button.h
 src/gth-user-dir.c
 src/gth-user-dir.h
-src/gth-window.c
-src/gth-window.h
 src/gtk-file-chooser-preview.c
 src/gtk-file-chooser-preview.h
 src/gtk-utils.c
@@ -66,8 +64,8 @@ src/typedefs.h
 [type: gettext/glade]src/ui/cover-chooser.ui
 [type: gettext/glade]src/ui/extract.ui
 [type: gettext/glade]src/ui/format-options.ui
-src/ui.h
-[type: gettext/glade]src/ui/menu-toolbars.ui
+[type: gettext/glade]src/ui/gears-menu.ui
+[type: gettext/glade]src/ui/menus.ui
 [type: gettext/glade]src/ui/message-dialog.ui
 [type: gettext/glade]src/ui/preferences.ui
 [type: gettext/glade]src/ui/properties.ui
diff --git a/src/Makefile.am b/src/Makefile.am
index 328863d..a1c8044 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,8 +9,6 @@ uidir = $(datadir)/goobox/ui
 endif
 
 AM_CPPFLAGS =                                          \
-       -I$(top_srcdir)                                 \
-       -I$(top_builddir)                               \
        -I$(top_srcdir)/copy-n-paste/                   \
        -DGOO_PREFIX=\"$(prefix)\"                      \
         -DGOO_SYSCONFDIR=\"$(sysconfdir)\"             \
@@ -18,6 +16,7 @@ AM_CPPFLAGS =                                         \
         -DGOO_LIBDIR=\"$(libdir)\"                     \
        -DGOO_UIDIR=\""$(uidir)"\"                      \
        $(GOO_CFLAGS)                                   \
+       $(SMCLIENT_CFLAGS)                              \
        $(LIBCOVERART_CFLAGS)                           \
        $(LIBNOTIFY_CFLAGS)
 
@@ -30,8 +29,6 @@ BUILT_SOURCES =                       \
        
 goobox_SOURCES =                               \
        $(BUILT_SOURCES)                        \
-       actions.c                               \
-       actions.h                               \
        album-info.c                            \
        album-info.h                            \
        dlg-cover-chooser.c                     \
@@ -51,6 +48,11 @@ goobox_SOURCES =                             \
        gnome-desktop-thumbnail.c               \
        gnome-desktop-thumbnail.h               \
        gnome-thumbnail-pixbuf-utils.c          \
+       goo-application.c                       \
+       goo-application.h                       \
+       goo-application-actions-callbacks.c     \
+       goo-application-actions-callbacks.h     \
+       goo-application-actions-entries.h       \
        goo-error.c                             \
        goo-error.h                             \
        goo-player.c                            \
@@ -59,18 +61,13 @@ goobox_SOURCES =                            \
        goo-player-bar.h                        \
        goo-player-info.c                       \
        goo-player-info.h                       \
-       goo-stock.c                             \
-       goo-stock.h                             \
        goo-window.c                            \
        goo-window.h                            \
-       gth-toggle-menu-action.c                \
-       gth-toggle-menu-action.h                \
-       gth-toggle-menu-tool-button.c           \
-       gth-toggle-menu-tool-button.h           \
+       goo-window-actions-callbacks.c          \
+       goo-window-actions-callbacks.h          \
+       goo-window-actions-entries.h            \
        gth-user-dir.c                          \
        gth-user-dir.h                          \
-       gth-window.c                            \
-       gth-window.h                            \
        gtk-file-chooser-preview.c              \
        gtk-file-chooser-preview.h              \
        gtk-utils.c                             \
@@ -82,8 +79,7 @@ goobox_SOURCES =                              \
        preferences.h                           \
        track-info.c                            \
        track-info.h                            \
-       typedefs.h                              \
-       ui.h                                    
+       typedefs.h                                      
 
 goo-marshal.h: goo-marshal.list $(GLIB_GENMARSHAL)
        $(GLIB_GENMARSHAL) $< --header --prefix=goo_marshal > $@
@@ -100,12 +96,13 @@ goo-resources.c: goobox.gresource.xml $(RESOURCES_DEP)
 goo-resources.h: goobox.gresource.xml $(RESOURCES_DEP)
        $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate --c-name goo 
$(srcdir)/goobox.gresource.xml
 
-goobox_LDADD =                                 \
+goobox_LDADD =                                                 \
        $(top_builddir)/copy-n-paste/libeggsmclient.la  \
-       $(GOO_LIBS)                     \
-       $(M_LIBS)                       \
-       $(LIBCOVERART_LIBS)             \
-       $(LIBNOTIFY_LIBS)               \
+       $(GOO_LIBS)                                     \
+       $(M_LIBS)                                       \
+       $(SMCLIENT_LIBS)                                \
+       $(LIBCOVERART_LIBS)                             \
+       $(LIBNOTIFY_LIBS)                               \
        $(SYSTEM_LIBS)
 
 EXTRA_DIST =                           \
diff --git a/src/dlg-cover-chooser.c b/src/dlg-cover-chooser.c
index 76ff251..7c82994 100644
--- a/src/dlg-cover-chooser.c
+++ b/src/dlg-cover-chooser.c
@@ -32,7 +32,7 @@
 #include "glib-utils.h"
 #include "gtk-utils.h"
 #include "goo-window.h"
-#include "goo-stock.h"
+
 
 #define BUFFER_SIZE 4096
 #define COVER_BACKUP_FILENAME "original_cover.png"
@@ -463,7 +463,6 @@ dlg_cover_chooser (GooWindow  *window,
        DialogData      *data;
        GtkListStore    *model;
        GtkCellRenderer *renderer;
-       GtkWidget       *image;
 
        data = g_new0 (DialogData, 1);
        data->window = window;
@@ -501,13 +500,6 @@ dlg_cover_chooser (GooWindow  *window,
 
        gtk_widget_set_sensitive (GET_WIDGET ("ok_button"), FALSE);
 
-       image = gtk_image_new_from_stock (GOO_STOCK_RESET, GTK_ICON_SIZE_BUTTON);
-       g_object_set (GET_WIDGET ("revert_button"),
-                     "use_stock", TRUE,
-                     "label", GOO_STOCK_RESET,
-                     "image", image,
-                     NULL);
-
        /* Set the signals handlers. */
 
        g_signal_connect (G_OBJECT (data->dialog),
diff --git a/src/dlg-extract.c b/src/dlg-extract.c
index 6d7e41d..50e466a 100644
--- a/src/dlg-extract.c
+++ b/src/dlg-extract.c
@@ -26,7 +26,6 @@
 #include "dlg-extract.h"
 #include "dlg-ripper.h"
 #include "goo-player.h"
-#include "goo-stock.h"
 #include "gtk-utils.h"
 #include "track-info.h"
 #include "typedefs.h"
@@ -117,10 +116,10 @@ dlg_extract_ask (GooWindow *window)
 
                d = _gtk_message_dialog_new (GTK_WINDOW (window),
                                             GTK_DIALOG_MODAL,
-                                            GTK_STOCK_DIALOG_ERROR,
+                                            _GTK_ICON_NAME_DIALOG_ERROR,
                                             _("No encoder available."),
                                             msg,
-                                            GTK_STOCK_OK, GTK_RESPONSE_OK,
+                                            _GTK_LABEL_OK, GTK_RESPONSE_OK,
                                             NULL);
                g_free (msg);
 
@@ -144,8 +143,6 @@ dlg_extract_ask (GooWindow *window)
        /* Get the widgets. */
 
        data->dialog = GET_WIDGET ("extract_dialog");
-       gtk_button_set_use_stock (GTK_BUTTON (GET_WIDGET ("ok_button")), TRUE);
-       gtk_button_set_label (GTK_BUTTON (GET_WIDGET ("ok_button")), GOO_STOCK_EXTRACT);
 
        /* Set widgets data. */
 
diff --git a/src/dlg-properties.c b/src/dlg-properties.c
index f5a41f9..adaffb0 100644
--- a/src/dlg-properties.c
+++ b/src/dlg-properties.c
@@ -23,7 +23,6 @@
 #include <config.h>
 #include <gtk/gtk.h>
 #include "dlg-properties.h"
-#include "goo-stock.h"
 #include "gtk-utils.h"
 #include "metadata.h"
 
@@ -270,7 +269,7 @@ search_album_by_title_ready_cb (GObject      *source_object,
        data->n_albums = g_list_length (data->albums);
 
        if (data->n_albums == 0) {
-               gtk_image_set_from_stock (GTK_IMAGE (GET_WIDGET ("info_icon")), GTK_STOCK_DIALOG_WARNING, 
GTK_ICON_SIZE_BUTTON);
+               gtk_image_set_from_icon_name (GTK_IMAGE (GET_WIDGET ("info_icon")), 
_GTK_ICON_NAME_DIALOG_WARNING, GTK_ICON_SIZE_BUTTON);
                gtk_label_set_text (GTK_LABEL (GET_WIDGET ("info_label")), _("No album found"));
                gtk_widget_show (GET_WIDGET ("info_box"));
                gtk_widget_hide (GET_WIDGET ("navigation_box"));
@@ -289,7 +288,7 @@ search_cb (GtkWidget  *widget,
 
        data->searching = TRUE;
 
-       gtk_image_set_from_stock (GTK_IMAGE (GET_WIDGET ("info_icon")), GTK_STOCK_FIND, GTK_ICON_SIZE_BUTTON);
+       gtk_image_set_from_icon_name (GTK_IMAGE (GET_WIDGET ("info_icon")), "edit-find-symbolic", 
GTK_ICON_SIZE_BUTTON);
        gtk_label_set_text (GTK_LABEL (GET_WIDGET ("info_label")), _("Searching disc info..."));
        gtk_widget_show (GET_WIDGET ("info_box"));
        gtk_widget_hide (GET_WIDGET ("navigation_box"));
@@ -485,7 +484,6 @@ void
 dlg_properties (GooWindow *window)
 {
        DialogData *data;
-        GtkWidget  *image;
 
         if (window->properties_dialog != NULL) {
                gtk_window_present (GTK_WINDOW (window->properties_dialog));
@@ -506,13 +504,6 @@ dlg_properties (GooWindow *window)
 
        /* Set widgets data. */
 
-       image = gtk_image_new_from_stock (GOO_STOCK_RESET, GTK_ICON_SIZE_BUTTON);
-       g_object_set (GET_WIDGET ("undo_button"),
-                     "use_stock", TRUE,
-                     "label", GOO_STOCK_RESET,
-                     "image", image,
-                     NULL);
-
        data->list_store = gtk_list_store_new (N_COLUMNS,
                                               G_TYPE_INT,
                                               G_TYPE_STRING,
diff --git a/src/dlg-ripper.c b/src/dlg-ripper.c
index 7b8157c..1fec348 100644
--- a/src/dlg-ripper.c
+++ b/src/dlg-ripper.c
@@ -585,7 +585,7 @@ rip_current_track (DialogData *data)
                d = _gtk_ok_dialog_with_checkbutton_new (GTK_WINDOW (data->window),
                                                         GTK_DIALOG_MODAL,
                                                         _("Tracks extracted successfully"),
-                                                        GTK_STOCK_OK,
+                                                        _GTK_LABEL_OK,
                                                         _("_View destination folder"),
                                                         data->settings_ripper,
                                                         PREF_RIPPER_VIEW_DISTINATION);
diff --git a/src/glib-utils.c b/src/glib-utils.c
index 0eb5d50..f91eb75 100644
--- a/src/glib-utils.c
+++ b/src/glib-utils.c
@@ -2234,3 +2234,17 @@ _g_format_duration_for_display (gint64 msecs)
          */
         return g_strdup_printf (C_("short time format", "%d∶%02d"), min, sec);
 }
+
+
+void
+_g_toggle_action_activated (GSimpleAction *action,
+                           GVariant      *parameter,
+                           gpointer       data)
+{
+       GVariant *state;
+
+       state = g_action_get_state (G_ACTION (action));
+       g_action_change_state (G_ACTION (action), g_variant_new_boolean (! g_variant_get_boolean (state)));
+
+       g_variant_unref (state);
+}
diff --git a/src/glib-utils.h b/src/glib-utils.h
index ea6c4a4..f1159a2 100644
--- a/src/glib-utils.h
+++ b/src/glib-utils.h
@@ -30,6 +30,7 @@
 
 G_BEGIN_DECLS
 
+#define DEF_ACTION_CALLBACK(x) void x (GSimpleAction *action, GVariant *parameter, gpointer user_data);
 #define GFILE_NAME_TYPE_ATTRIBUTES "standard::name,standard::type"
 #define GFILE_DISPLAY_ATTRIBUTES "standard::display-name,standard::icon"
 #define GFILE_BASIC_ATTRIBUTES GFILE_DISPLAY_ATTRIBUTES ",standard::name,standard::type"
@@ -261,6 +262,9 @@ char *          _g_make_temp_directory           (void);
 /* Other */
 
 char *          _g_format_duration_for_display   (gint64 msecs);
+void           _g_toggle_action_activated       (GSimpleAction *action,
+                                                 GVariant      *parameter,
+                                                 gpointer       data);
 
 G_END_DECLS
 
diff --git a/src/goo-application-actions-callbacks.c b/src/goo-application-actions-callbacks.c
new file mode 100644
index 0000000..0059e18
--- /dev/null
+++ b/src/goo-application-actions-callbacks.c
@@ -0,0 +1,161 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Goo
+ *
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "dlg-preferences.h"
+#include "dlg-properties.h"
+#include "gtk-utils.h"
+#include "goo-application.h"
+#include "goo-application-actions-callbacks.h"
+#include "goo-window.h"
+#include "preferences.h"
+
+
+void
+update_actions_sensitivity (GApplication *application)
+{
+       GVariant *state;
+       gboolean  play_all;
+
+       state = g_action_get_state (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_PLAYALL));
+       play_all = g_variant_get_boolean (state);
+       g_variant_unref (state);
+
+       g_simple_action_set_enabled (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_REPEAT)), play_all);
+       g_simple_action_set_enabled (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_SHUFFLE)), play_all);
+}
+
+
+void
+goo_application_activate_about (GSimpleAction *action,
+                               GVariant      *parameter,
+                               gpointer       user_data)
+{
+        const char *authors[] = {
+                "Paolo Bacchilega <paobac src gnome org>",
+                NULL
+        };
+        const char *documenters [] = {
+                "Paolo Bacchilega <paobac src gnome org>",
+                NULL
+        };
+        const char *translator_credits = _("translator_credits");
+
+        gtk_show_about_dialog (GTK_WINDOW (_gtk_application_get_current_window (GTK_APPLICATION 
(user_data))),
+                               "name", _("CD Player"),
+                               "version", VERSION,
+                               "copyright", _("Copyright \xc2\xa9 2004-2011 Free Software Foundation, Inc."),
+                               "comments", _("Play CDs and save the tracks to disk as files"),
+                               "authors", authors,
+                               "documenters", documenters,
+                               "translator_credits", strcmp (translator_credits, "translator_credits") != 0 
? translator_credits : NULL,
+                               "logo-icon-name", "goobox",
+                               "license-type", GTK_LICENSE_GPL_2_0,
+                               "wrap-license", TRUE,
+                               NULL);
+}
+
+
+void
+goo_application_activate_help (GSimpleAction *action,
+                              GVariant      *parameter,
+                              gpointer       user_data)
+{
+       GApplication *application = user_data;
+       GtkWidget    *window;
+
+       window = _gtk_application_get_current_window (GTK_APPLICATION (application));
+       show_help_dialog (GTK_WINDOW (window), NULL);
+}
+
+
+void
+goo_application_activate_play_all (GSimpleAction *action,
+                                  GVariant      *parameter,
+                                  gpointer       user_data)
+{
+       GApplication *application = user_data;
+       GSettings    *settings;
+
+       g_simple_action_set_state (action, parameter);
+       settings = g_settings_new (GOOBOX_SCHEMA_PLAYLIST);
+       g_settings_set_boolean (settings, PREF_PLAYLIST_PLAYALL, g_variant_get_boolean (parameter));
+       update_actions_sensitivity (application);
+
+       g_object_unref (settings);
+}
+
+
+void
+goo_application_activate_preferences (GSimpleAction *action,
+                                     GVariant      *parameter,
+                                     gpointer       user_data)
+{
+       GApplication *application = user_data;
+       GtkWidget    *window;
+
+       window = _gtk_application_get_current_window (GTK_APPLICATION (application));
+       dlg_preferences (GOO_WINDOW (window));
+}
+
+
+void
+goo_application_activate_quit (GSimpleAction *action,
+                              GVariant      *parameter,
+                              gpointer       user_data)
+{
+       g_application_quit (G_APPLICATION (user_data));
+}
+
+
+void
+goo_application_activate_repeat (GSimpleAction *action,
+                                GVariant      *parameter,
+                                gpointer       user_data)
+{
+       GApplication *application = user_data;
+       GSettings    *settings;
+
+       g_simple_action_set_state (action, parameter);
+       settings = g_settings_new (GOOBOX_SCHEMA_PLAYLIST);
+       g_settings_set_boolean (settings, PREF_PLAYLIST_REPEAT, g_variant_get_boolean (parameter));
+       update_actions_sensitivity (application);
+
+       g_object_unref (settings);
+}
+
+
+void
+goo_application_activate_shuffle (GSimpleAction *action,
+                                 GVariant      *parameter,
+                                 gpointer       user_data)
+{
+       GApplication *application = user_data;
+       GSettings    *settings;
+
+       g_simple_action_set_state (action, parameter);
+       settings = g_settings_new (GOOBOX_SCHEMA_PLAYLIST);
+       g_settings_set_boolean (settings, PREF_PLAYLIST_SHUFFLE, g_variant_get_boolean (parameter));
+       update_actions_sensitivity (application);
+
+       g_object_unref (settings);
+}
diff --git a/src/goo-application-actions-callbacks.h b/src/goo-application-actions-callbacks.h
new file mode 100644
index 0000000..ec7368d
--- /dev/null
+++ b/src/goo-application-actions-callbacks.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Goo
+ *
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GOO_APPLICATION_ACTIONS_CALLBACKS_H
+#define GOO_APPLICATION_ACTIONS_CALLBACKS_H
+
+#include <gtk/gtk.h>
+#include "glib-utils.h"
+
+void update_actions_sensitivity (GApplication *application);
+
+DEF_ACTION_CALLBACK (goo_application_activate_about)
+DEF_ACTION_CALLBACK (goo_application_activate_help)
+DEF_ACTION_CALLBACK (goo_application_activate_play_all)
+DEF_ACTION_CALLBACK (goo_application_activate_preferences)
+DEF_ACTION_CALLBACK (goo_application_activate_quit)
+DEF_ACTION_CALLBACK (goo_application_activate_repeat)
+DEF_ACTION_CALLBACK (goo_application_activate_shuffle)
+
+#endif /* GOO_APPLICATION_ACTIONS_CALLBACKS_H */
diff --git a/src/goo-application-actions-entries.h b/src/goo-application-actions-entries.h
new file mode 100644
index 0000000..8bdff65
--- /dev/null
+++ b/src/goo-application-actions-entries.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Goo
+ *
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GOO_WINDOW_ACTIONS_ENTRIES_H
+#define GOO_WINDOW_ACTIONS_ENTRIES_H
+
+#include <config.h>
+#include "glib-utils.h"
+#include "goo-application-actions-callbacks.h"
+#include "preferences.h"
+
+
+static const GActionEntry goo_application_actions[] = {
+       { "preferences",  goo_application_activate_preferences },
+       { PREF_PLAYLIST_PLAYALL, _g_toggle_action_activated, NULL, "true", goo_application_activate_play_all 
},
+       { PREF_PLAYLIST_REPEAT, _g_toggle_action_activated, NULL, "false", goo_application_activate_repeat },
+       { PREF_PLAYLIST_SHUFFLE, _g_toggle_action_activated, NULL, "true", goo_application_activate_shuffle },
+       { "help",  goo_application_activate_help },
+       { "about", goo_application_activate_about },
+       { "quit",  goo_application_activate_quit }
+};
+
+
+#endif /* GOO_WINDOW_ACTIONS_ENTRIES_H */
diff --git a/src/goo-application.c b/src/goo-application.c
new file mode 100644
index 0000000..77582b0
--- /dev/null
+++ b/src/goo-application.c
@@ -0,0 +1,564 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Goo
+ *
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <config.h>
+#include <stdlib.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <gst/gst.h>
+#ifdef USE_SMCLIENT
+#  include "eggsmclient.h"
+#endif
+#include "goo-application.h"
+#include "goo-application-actions-callbacks.h"
+#include "goo-application-actions-entries.h"
+#include "goo-window.h"
+#include "gtk-utils.h"
+#include "main.h"
+#include "preferences.h"
+
+
+/* -- command line arguments -- */
+
+static const char     *program_argv0 = NULL;
+static int             arg_toggle_play = FALSE;
+static int             arg_stop = FALSE;
+static int             arg_next = FALSE;
+static int             arg_prev = FALSE;
+static int             arg_eject = FALSE;
+static int             arg_quit = FALSE;
+static gboolean        arg_version = FALSE;
+static char           *arg_device = NULL;
+
+
+static const GOptionEntry options[] = {
+       { "device", 'd',  0, G_OPTION_ARG_STRING, &arg_device,
+         N_("CD device to be used"),
+         N_("DEVICE_PATH") },
+       { "play", '\0', 0, G_OPTION_ARG_NONE, &arg_auto_play,
+          N_("Play the CD on startup"),
+          0 },
+       { "toggle-play", '\0', 0, G_OPTION_ARG_NONE, &arg_toggle_play,
+          N_("Toggle play"),
+          0 },
+        { "stop", '\0', 0, G_OPTION_ARG_NONE, &arg_stop,
+          N_("Stop playing"),
+          0 },
+       { "next", '\0', 0, G_OPTION_ARG_NONE, &arg_next,
+          N_("Play the next track"),
+          0 },
+       { "previous", '\0', 0, G_OPTION_ARG_NONE, &arg_prev,
+          N_("Play the previous track"),
+          0 },
+       { "eject", '\0', 0, G_OPTION_ARG_NONE, &arg_eject,
+          N_("Eject the CD"),
+          0 },
+       { "toggle-visibility", '\0', 0, G_OPTION_ARG_NONE, &arg_toggle_visibility,
+          N_("Toggle the main window visibility"),
+          0 },
+       { "quit", '\0', 0, G_OPTION_ARG_NONE, &arg_quit,
+          N_("Quit the application"),
+          0 },
+        { "version", 'v', 0, G_OPTION_ARG_NONE, &arg_version,
+         N_("Show version"),
+         0 },
+       { NULL }
+};
+
+
+/* -- session management -- */
+
+
+#ifdef USE_SMCLIENT
+
+
+static void
+client_save_state (EggSMClient *client,
+                  GKeyFile    *state,
+                  gpointer     user_data)
+{
+       GApplication *application = user_data;
+       const char   *argv[2] = { NULL };
+       guint         i;
+       GList        *scan;
+
+       argv[0] = program_argv0;
+       argv[1] = NULL;
+       egg_sm_client_set_restart_command (client, 1, argv);
+
+       i = 0;
+       for (scan = gtk_application_get_windows (GTK_APPLICATION (application)); scan; scan = scan->next) {
+               GtkWidget *window = scan->data;
+               char      *key;
+
+               key = g_strdup_printf ("device%d", ++i);
+               g_key_file_set_string (state,
+                                      "Session",
+                                      key,
+                                      goo_player_get_device (goo_window_get_player (GOO_WINDOW (window))));
+
+               g_free (key);
+       }
+
+       g_key_file_set_integer (state, "Session", "devices", i);
+}
+
+
+static void
+client_quit_requested_cb (EggSMClient *client,
+                         gpointer     data)
+{
+       egg_sm_client_will_quit (client, TRUE);
+}
+
+
+static void
+client_quit_cb (EggSMClient *client,
+               gpointer     data)
+{
+       gtk_main_quit ();
+}
+
+
+static EggSMClient *
+goo_session_manager_init (GApplication *application)
+{
+       EggSMClient *client = NULL;
+
+       client = egg_sm_client_get ();
+       g_signal_connect (client,
+                         "save_state",
+                         G_CALLBACK (client_save_state),
+                         application);
+       g_signal_connect (client,
+                         "quit_requested",
+                         G_CALLBACK (client_quit_requested_cb),
+                         application);
+       g_signal_connect (client,
+                         "quit",
+                         G_CALLBACK (client_quit_cb),
+                         application);
+
+       return client;
+}
+
+
+static void
+goo_restore_session (EggSMClient  *client,
+                    GApplication *application)
+{
+       GKeyFile *state = NULL;
+       guint     i;
+
+       state = egg_sm_client_get_state_file (client);
+       i = g_key_file_get_integer (state, "Session", "devices", NULL);
+       g_assert (i > 0);
+       for (/* void */; i > 0; i--) {
+               char         *key;
+               char         *device;
+               BraseroDrive *drive;
+               GtkWidget    *window;
+
+               key = g_strdup_printf ("device%d", i);
+               device = g_key_file_get_string (state, "Session", key, NULL);
+               g_free (key);
+
+               g_assert (device != NULL);
+
+               drive = main_get_drive_for_device (device);
+               window = goo_window_new (drive);
+               gtk_widget_show (window);
+
+               g_object_unref (drive);
+               g_free (device);
+       }
+}
+
+
+#endif
+
+
+/* -- GooApplication --  */
+
+
+G_DEFINE_TYPE (GooApplication, goo_application, GTK_TYPE_APPLICATION)
+
+
+struct _GooApplicationPrivate {
+        GSettings *settings;
+};
+
+
+static void
+goo_application_finalize (GObject *object)
+{
+       GooApplication *self = (GooApplication *) object;
+
+       g_object_unref (self->priv->settings);
+       G_OBJECT_CLASS (goo_application_parent_class)->finalize (object);
+}
+
+
+static gboolean
+required_gstreamer_plugins_available (void)
+{
+       char *required_plugins[] = { "cdparanoiasrc", "audioconvert", "volume", "giosink" };
+       int   i;
+
+       for (i = 0; i < G_N_ELEMENTS (required_plugins); i++) {
+               GstElement *element;
+               gboolean    present;
+
+               element = gst_element_factory_make (required_plugins[i], NULL);
+               present = (element != NULL);
+               if (element != NULL)
+                       gst_object_unref (GST_OBJECT (element));
+
+               if (! present)
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+
+static int
+goo_application_command_line_finished (GApplication *application,
+                                       int           status)
+{
+        if (status == EXIT_SUCCESS)
+                gdk_notify_startup_complete ();
+
+        /* reset the arguments */
+
+       arg_auto_play = FALSE;
+       arg_toggle_play = FALSE;
+       arg_stop = FALSE;
+       arg_next = FALSE;
+       arg_prev = FALSE;
+       arg_eject = FALSE;
+       arg_toggle_visibility = FALSE;
+       arg_quit = FALSE;
+       g_free (arg_device);
+       arg_device = NULL;
+
+        return status;
+}
+
+
+static GOptionContext *
+goo_application_create_option_context (void)
+{
+       GOptionContext *options_context;
+       static gsize    initialized = FALSE;
+
+       options_context = g_option_context_new (N_("Play CDs and save the tracks to disk as files"));
+       g_option_context_set_translation_domain (options_context, GETTEXT_PACKAGE);
+       g_option_context_set_ignore_unknown_options (options_context, TRUE);
+       g_option_context_add_main_entries (options_context, options, GETTEXT_PACKAGE);
+
+       if (g_once_init_enter (&initialized)) {
+               g_option_context_add_group (options_context, gtk_get_option_group (TRUE));
+#if USE_SMCLIENT
+               g_option_context_add_group (options_context, egg_sm_client_get_option_group ());
+#endif
+               g_option_context_add_group (options_context, gst_init_get_option_group ());
+
+               g_once_init_leave (&initialized, TRUE);
+       }
+
+       return options_context;
+}
+
+
+static int
+goo_application_command_line (GApplication            *application,
+                             GApplicationCommandLine *command_line)
+{
+       char           **argv;
+       int              argc;
+       GOptionContext  *options_context;
+       GError          *error = NULL;
+       GtkWidget       *window;
+
+       argv = g_application_command_line_get_arguments (command_line, &argc);
+       options_context = goo_application_create_option_context ();
+       if (! g_option_context_parse (options_context, &argc, &argv, &error)) {
+               g_critical ("Failed to parse arguments: %s", error->message);
+               g_error_free (error);
+               g_option_context_free (options_context);
+               return goo_application_command_line_finished (application, EXIT_FAILURE);
+       }
+       g_option_context_free (options_context);
+
+       /* check the gstreamer plugins */
+
+       if (! required_gstreamer_plugins_available ()) {
+               GtkWidget *d;
+               d = _gtk_message_dialog_new (NULL,
+                                            0,
+                                            _GTK_ICON_NAME_DIALOG_ERROR,
+                                            _("Cannot start the CD player"),
+                                            _("In order to read CDs you have to install the gstreamer base 
plugins"),
+                                            _GTK_LABEL_OK, GTK_RESPONSE_OK,
+                                            NULL);
+               g_signal_connect_swapped (G_OBJECT (d), "response",
+                                         G_CALLBACK (gtk_widget_destroy),
+                                         d);
+               gtk_window_set_application (GTK_WINDOW (d), GTK_APPLICATION (application));
+               gtk_widget_show (d);
+
+               return goo_application_command_line_finished (application, EXIT_FAILURE);
+       }
+
+       /* restore the session */
+
+#if USE_SMCLIENT
+       {
+               EggSMClient *client;
+
+               client = goo_session_manager_init (application);
+               if (egg_sm_client_is_resumed (client)) {
+                       goo_restore_session (client, application);
+                       return goo_application_command_line_finished (application, EXIT_SUCCESS);
+               }
+       }
+#endif
+
+       /* execute the command line */
+
+       /*window = _gtk_application_get_current_window (GTK_APPLICATION (application));
+       if (window == NULL)
+               window = goo_window_new (NULL);
+       gtk_window_present (GTK_WINDOW (window));*/
+
+       window = goo_window_new (NULL);
+       gtk_window_present (GTK_WINDOW (window));
+
+       if (arg_auto_play) {
+               goo_window_play (GOO_WINDOW (window));
+       }
+       else if (arg_toggle_play) {
+               goo_window_toggle_play (GOO_WINDOW (window));
+       }
+       else if (arg_stop) {
+               goo_window_stop (GOO_WINDOW (window));
+       }
+       else if (arg_next) {
+               goo_window_next (GOO_WINDOW (window));
+       }
+       else if (arg_prev) {
+               goo_window_prev (GOO_WINDOW (window));
+       }
+       else if (arg_eject) {
+               goo_window_eject (GOO_WINDOW (window));
+       }
+       else if (arg_toggle_visibility) {
+               goo_window_toggle_visibility (GOO_WINDOW (window));
+       }
+       else if (arg_quit) {
+               goo_window_close (GOO_WINDOW (window));
+       }
+       else if (arg_device != NULL) {
+               BraseroDrive *drive;
+
+               drive = main_get_drive_for_device (arg_device);
+               window = main_get_window_from_device (arg_device);
+               if (window == NULL) {
+                       window = goo_window_new (drive);
+                       gtk_widget_show (window);
+               }
+               else
+                       goo_window_set_drive (GOO_WINDOW (window), drive);
+
+               g_object_unref (drive);
+               g_free (arg_device);
+               arg_device = NULL;
+       }
+
+       return goo_application_command_line_finished (application, EXIT_SUCCESS);
+}
+
+
+static gboolean
+goo_application_local_command_line (GApplication   *application,
+                                   char         ***arguments,
+                                   int            *exit_status)
+{
+       char           **local_argv;
+       int              local_argc;
+       GOptionContext  *options_context;
+       GError          *error = NULL;
+       gboolean         handled_locally = FALSE;
+
+       local_argv = g_strdupv (*arguments);
+       local_argc = g_strv_length (local_argv);
+
+       program_argv0 = g_strdup (local_argv[0]);
+       *exit_status = EXIT_SUCCESS;
+
+       options_context = goo_application_create_option_context ();
+       if (! g_option_context_parse (options_context, &local_argc, &local_argv, &error)) {
+               *exit_status = EXIT_FAILURE;
+               g_critical ("Failed to parse arguments: %s", error->message);
+               g_clear_error (&error);
+               handled_locally = TRUE;
+       }
+
+       if (arg_version) {
+               g_printf ("%s %s, Copyright © 2001-2013 Free Software Foundation, Inc.\n", PACKAGE_NAME, 
PACKAGE_VERSION);
+               handled_locally = TRUE;
+       }
+
+       g_option_context_free (options_context);
+       g_strfreev (local_argv);
+
+       return handled_locally;
+}
+
+
+/* -- goo_application_startup -- */
+
+
+static void
+pref_playlist_playall_changed (GSettings  *settings,
+                              const char *key,
+                              gpointer    user_data)
+{
+       GooApplication *application = user_data;
+
+       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_PLAYALL)),
+                                  g_variant_new_boolean (g_settings_get_boolean 
(application->priv->settings, PREF_PLAYLIST_PLAYALL)));
+       update_actions_sensitivity (G_APPLICATION (application));
+}
+
+
+static void
+pref_playlist_repeat_changed (GSettings  *settings,
+                             const char *key,
+                             gpointer    user_data)
+{
+       GooApplication *application = user_data;
+
+       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_REPEAT)),
+                                  g_variant_new_boolean (g_settings_get_boolean 
(application->priv->settings, PREF_PLAYLIST_REPEAT)));
+       update_actions_sensitivity (G_APPLICATION (application));
+}
+
+
+static void
+pref_playlist_shuffle_changed (GSettings  *settings,
+                              const char *key,
+                              gpointer    user_data)
+{
+       GooApplication *application = user_data;
+
+       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_SHUFFLE)),
+                                  g_variant_new_boolean (g_settings_get_boolean 
(application->priv->settings, PREF_PLAYLIST_SHUFFLE)));
+       update_actions_sensitivity (G_APPLICATION (application));
+}
+
+
+static void
+initialize_app_menu (GApplication *application)
+{
+       GooApplication *self = (GooApplication *) application;
+       GtkBuilder     *builder;
+
+       g_action_map_add_action_entries (G_ACTION_MAP (application),
+                                        goo_application_actions,
+                                        G_N_ELEMENTS (goo_application_actions),
+                                        application);
+
+       builder = _gtk_builder_new_from_resource ("app-menu.ui");
+       gtk_application_set_app_menu (GTK_APPLICATION (application),
+                                     G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu")));
+
+       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_PLAYALL)),
+                                  g_variant_new_boolean (g_settings_get_boolean (self->priv->settings, 
PREF_PLAYLIST_PLAYALL)));
+       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_REPEAT)),
+                                  g_variant_new_boolean (g_settings_get_boolean (self->priv->settings, 
PREF_PLAYLIST_REPEAT)));
+       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_SHUFFLE)),
+                                  g_variant_new_boolean (g_settings_get_boolean (self->priv->settings, 
PREF_PLAYLIST_SHUFFLE)));
+
+       g_signal_connect (self->priv->settings,
+                         "changed::" PREF_PLAYLIST_PLAYALL,
+                         G_CALLBACK (pref_playlist_playall_changed),
+                         self);
+       g_signal_connect (self->priv->settings,
+                         "changed::" PREF_PLAYLIST_SHUFFLE,
+                         G_CALLBACK (pref_playlist_shuffle_changed),
+                         self);
+       g_signal_connect (self->priv->settings,
+                         "changed::" PREF_PLAYLIST_REPEAT,
+                         G_CALLBACK (pref_playlist_repeat_changed),
+                         self);
+
+       g_object_unref (builder);
+}
+
+
+static void
+goo_application_startup (GApplication *application)
+{
+       G_APPLICATION_CLASS (goo_application_parent_class)->startup (application);
+       initialize_app_menu (application);
+}
+
+
+static void
+goo_application_class_init (GooApplicationClass *klass)
+{
+       GObjectClass      *object_class;
+       GApplicationClass *application_class;
+
+       g_type_class_add_private (klass, sizeof (GooApplicationPrivate));
+
+       object_class = G_OBJECT_CLASS (klass);
+       object_class->finalize = goo_application_finalize;
+
+       application_class = G_APPLICATION_CLASS (klass);
+       application_class->command_line = goo_application_command_line;
+       application_class->local_command_line = goo_application_local_command_line;
+       application_class->startup = goo_application_startup;
+}
+
+
+static void
+goo_application_init (GooApplication *self)
+{
+       self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GOO_TYPE_APPLICATION, GooApplicationPrivate);
+       self->priv->settings = g_settings_new (GOOBOX_SCHEMA_PLAYLIST);
+
+       g_set_application_name (_("CD Player"));
+       gtk_window_set_default_icon_name ("goobox");
+}
+
+
+GtkApplication *
+goo_application_new (void)
+{
+       return g_object_new (GOO_TYPE_APPLICATION,
+                            "application-id", "org.gnome.Goobox",
+                            "flags", 0,
+                            NULL);
+}
diff --git a/src/goo-application.h b/src/goo-application.h
new file mode 100644
index 0000000..7b8321a
--- /dev/null
+++ b/src/goo-application.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Goo
+ *
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef GOO_APPLICATION_H
+#define GOO_APPLICATION_H
+
+#include <gtk/gtk.h>
+
+#define GOO_TYPE_APPLICATION            (goo_application_get_type ())
+#define GOO_APPLICATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_APPLICATION, 
GooApplication))
+#define GOO_APPLICATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_APPLICATION, 
GooApplicationClass))
+#define GOO_IS_APPLICATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_APPLICATION))
+#define GOO_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_APPLICATION))
+#define GOO_APPLICATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GOO_TYPE_APPLICATION, 
GooApplicationClass))
+
+typedef struct _GooApplication         GooApplication;
+typedef struct _GooApplicationClass    GooApplicationClass;
+typedef struct _GooApplicationPrivate  GooApplicationPrivate;
+
+struct _GooApplication {
+       GtkApplication __parent;
+       GooApplicationPrivate *priv;
+};
+
+struct _GooApplicationClass {
+       GtkApplicationClass __parent_class;
+};
+
+GType                  goo_application_get_type        (void);
+GtkApplication *       goo_application_new             (void);
+
+#endif /* GOO_APPLICATION_H */
diff --git a/src/goo-player-bar.c b/src/goo-player-bar.c
index 0c57db1..858f341 100644
--- a/src/goo-player-bar.c
+++ b/src/goo-player-bar.c
@@ -25,9 +25,8 @@
 #include <glib/gi18n.h>
 #include "goo-player-bar.h"
 #include "goo-marshal.h"
-#include "goo-stock.h"
 #include "glib-utils.h"
-#include "gth-toggle-menu-action.h"
+#include "gtk-utils.h"
 
 
 #define SCALE_WIDTH 150
@@ -46,6 +45,7 @@ struct _GooPlayerBarPrivateData {
        GtkWidget *remaining_time_label;
        GtkWidget *time_scale;
        GtkWidget *time_box;
+       GtkWidget *play_button_image;
        gint64     track_length;
        gint64     current_time;
        gboolean   dragging;
@@ -198,22 +198,6 @@ goo_player_bar_init (GooPlayerBar *self)
 
 
 static GtkWidget *
-_gtk_button_new_from_icon_name (const char *icon_name,
-                               GtkIconSize size)
-{
-       GtkWidget *button;
-       GtkWidget *image;
-
-       button = gtk_button_new ();
-       image = gtk_image_new_from_icon_name (icon_name, size);
-       gtk_widget_show (image);
-       gtk_container_add (GTK_CONTAINER (button), image);
-
-       return button;
-}
-
-
-static GtkWidget *
 _gtk_menu_button_new_from_icon_name (const char *icon_name)
 {
        GtkWidget *button;
@@ -229,41 +213,14 @@ _gtk_menu_button_new_from_icon_name (const char *icon_name)
 
 
 static void
-toggle_play_notify_icon_name_cb (GObject    *gobject,
-                                GParamSpec *pspec,
-                                gpointer    user_data)
-{
-       GtkWidget *button = user_data;
-       GtkWidget *image;
-
-       image = gtk_bin_get_child (GTK_BIN (button));
-       if ((image != NULL) && GTK_IS_IMAGE (image))
-               gtk_image_set_from_icon_name (GTK_IMAGE (image), gtk_action_get_icon_name (GTK_ACTION 
(gobject)), PLAY_BUTTON_SIZE);
-}
-
-
-static void
-_gtk_button_sync_with_action (GtkWidget *button,
-                             GtkAction *action)
-{
-       gtk_activatable_set_related_action (GTK_ACTIVATABLE (button), action);
-       gtk_widget_set_tooltip_text (button, gtk_action_get_tooltip (action));
-       if (GTK_IS_MENU_BUTTON (button))
-               g_object_set (button,
-                             "popup", gth_toggle_menu_action_get_menu (GTH_TOGGLE_MENU_ACTION (action)),
-                             NULL);
-}
-
-
-static void
-goo_player_bar_construct (GooPlayerBar   *self,
-                         GtkActionGroup *actions)
+goo_player_bar_construct (GooPlayerBar *self,
+                         GActionMap    *action_map)
 {
        GtkWidget *frame;
        GtkWidget *main_box;
        GtkWidget *button_box;
        GtkWidget *button;
-       gboolean rtl;
+       gboolean   rtl;
 
        rtl = gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL;
 
@@ -281,24 +238,22 @@ goo_player_bar_construct (GooPlayerBar   *self,
 
        /* Play buttons */
 
-       button = _gtk_button_new_from_icon_name (rtl ? GOO_STOCK_PLAY_RTL : GOO_STOCK_PLAY, PLAY_BUTTON_SIZE);
-       _gtk_button_sync_with_action (button, gtk_action_group_get_action (actions, "TogglePlay"));
-       g_signal_connect (gtk_action_group_get_action (actions, "TogglePlay"),
-                         "notify::icon-name",
-                         G_CALLBACK (toggle_play_notify_icon_name_cb),
-                         button);
+       self->priv->play_button_image = gtk_image_new_from_icon_name (rtl ? GOO_ICON_NAME_PLAY_RTL : 
GOO_ICON_NAME_PLAY, PLAY_BUTTON_SIZE);
+       button = gtk_button_new ();
+       gtk_container_add (GTK_CONTAINER (button), self->priv->play_button_image);
+       gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.toggle-play");
        gtk_box_pack_start (GTK_BOX (main_box), button, FALSE, FALSE, 0);
 
        button_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
        gtk_style_context_add_class (gtk_widget_get_style_context (button_box), GTK_STYLE_CLASS_LINKED);
        gtk_box_pack_start (GTK_BOX (main_box), button_box, FALSE, FALSE, 0);
 
-       button = _gtk_button_new_from_icon_name (rtl ? GOO_STOCK_PREV_RTL : GOO_STOCK_PREV, 
GTK_ICON_SIZE_SMALL_TOOLBAR);
-       _gtk_button_sync_with_action (button, gtk_action_group_get_action (actions, "Prev"));
+       button = gtk_button_new_from_icon_name (rtl ? GOO_ICON_NAME_PREV_RTL : GOO_ICON_NAME_PREV, 
GTK_ICON_SIZE_SMALL_TOOLBAR);
+       gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.previous-track");
        gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
 
-       button = _gtk_button_new_from_icon_name (rtl ? GOO_STOCK_NEXT_RTL : GOO_STOCK_NEXT, 
GTK_ICON_SIZE_SMALL_TOOLBAR);
-       _gtk_button_sync_with_action (button, gtk_action_group_get_action (actions, "Next"));
+       button = gtk_button_new_from_icon_name (rtl ? GOO_ICON_NAME_NEXT_RTL : GOO_ICON_NAME_NEXT, 
GTK_ICON_SIZE_SMALL_TOOLBAR);
+       gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.next-track");
        gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
 
        /* Time */
@@ -331,13 +286,20 @@ goo_player_bar_construct (GooPlayerBar   *self,
        gtk_box_set_spacing (GTK_BOX (button_box), 6);
        gtk_box_pack_end (GTK_BOX (main_box), button_box, FALSE, FALSE, 0);
 
-       button = _gtk_button_new_from_icon_name (GOO_STOCK_EXTRACT, GTK_ICON_SIZE_SMALL_TOOLBAR);
-       _gtk_button_sync_with_action (button, gtk_action_group_get_action (actions, "Extract"));
+       button = gtk_button_new_from_icon_name (GOO_ICON_NAME_EXTRACT, GTK_ICON_SIZE_SMALL_TOOLBAR);
+       gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.extract");
        gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
 
-       button = _gtk_menu_button_new_from_icon_name ("emblem-system-symbolic");
-       _gtk_button_sync_with_action (button, gtk_action_group_get_action (actions, "OtherActions"));
-       gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
+       {
+               GtkBuilder *builder;
+
+               builder = _gtk_builder_new_from_resource ("gears-menu.ui");
+               button = _gtk_menu_button_new_from_icon_name ("emblem-system-symbolic");
+               gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), G_MENU_MODEL 
(gtk_builder_get_object (builder, "gears-menu")));
+               gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
+
+               g_object_unref (builder);
+       }
 
        /* signals */
 
@@ -487,10 +449,21 @@ player_state_changed_cb (GooPlayer     *player,
 
 
 static void
+_goo_player_bar_update_play_button_icon (GooPlayerBar *self,
+                                        gboolean      playing)
+{
+       gtk_image_set_from_icon_name (GTK_IMAGE (self->priv->play_button_image),
+                                     playing ? GOO_ICON_NAME_PAUSE : (gtk_widget_get_default_direction () == 
GTK_TEXT_DIR_RTL ? GOO_ICON_NAME_PLAY_RTL : GOO_ICON_NAME_PLAY),
+                                     PLAY_BUTTON_SIZE);
+}
+
+
+static void
 player_start_cb (GooPlayer       *player,
                 GooPlayerAction  action,
                 GooPlayerBar    *self)
 {
+       _goo_player_bar_update_play_button_icon (self, action == GOO_PLAYER_ACTION_PLAY);
        goo_player_bar_update_state (self);
 }
 
@@ -529,8 +502,8 @@ player_done_cb (GooPlayer       *player,
 
 
 GtkWidget *
-goo_player_bar_new (GooPlayer      *player,
-                   GtkActionGroup *actions)
+goo_player_bar_new (GooPlayer  *player,
+                   GActionMap  *action_map)
 {
        GooPlayerBar *self;
 
@@ -538,7 +511,7 @@ goo_player_bar_new (GooPlayer      *player,
 
        self = GOO_PLAYER_BAR (g_object_new (GOO_TYPE_PLAYER_BAR, NULL));
        self->priv->player = g_object_ref (player);
-       goo_player_bar_construct (self, actions);
+       goo_player_bar_construct (self, action_map);
 
        g_signal_connect (player,
                          "start",
diff --git a/src/goo-player-bar.h b/src/goo-player-bar.h
index 00d80fc..e07b669 100644
--- a/src/goo-player-bar.h
+++ b/src/goo-player-bar.h
@@ -55,8 +55,8 @@ struct _GooPlayerBarClass
 };
 
 GType       goo_player_bar_get_type      (void);
-GtkWidget * goo_player_bar_new           (GooPlayer      *player,
-                                         GtkActionGroup *actions);
-double      goo_player_bar_get_progress  (GooPlayerBar *info);
+GtkWidget * goo_player_bar_new           (GooPlayer    *player,
+                                         GActionMap    *action_map);
+double      goo_player_bar_get_progress  (GooPlayerBar *info);
 
 #endif /* GOO_PLAYER_BAR_H */
diff --git a/src/goo-player-info.c b/src/goo-player-info.c
index 5d932d0..2401ae3 100644
--- a/src/goo-player-info.c
+++ b/src/goo-player-info.c
@@ -25,9 +25,9 @@
 #include <glib/gi18n.h>
 #include "goo-player-info.h"
 #include "goo-marshal.h"
-#include "goo-stock.h"
 #include "goo-window.h"
 #include "glib-utils.h"
+#include "gtk-utils.h"
 
 #define TITLE1_FORMAT "<span size='large'>%s</span>"
 #define TITLE2_FORMAT "%s"
@@ -266,7 +266,7 @@ goo_player_info_construct (GooPlayerInfo *info)
                          G_CALLBACK (cover_button_drag_data_received),
                          info);
 
-       priv->cover_image = gtk_image_new_from_stock (GOO_STOCK_NO_DISC, GTK_ICON_SIZE_DIALOG);
+       priv->cover_image = gtk_image_new_from_icon_name (GOO_ICON_NAME_NO_DISC, GTK_ICON_SIZE_DIALOG);
        gtk_widget_set_size_request (priv->cover_image, COVER_SIZE, COVER_SIZE);
        gtk_widget_show (priv->cover_image);
 
@@ -274,7 +274,7 @@ goo_player_info_construct (GooPlayerInfo *info)
 
        /* Status image */
 
-       priv->status_image = gtk_image_new_from_stock (GOO_STOCK_NO_DISC, GTK_ICON_SIZE_DIALOG);
+       priv->status_image = gtk_image_new_from_icon_name (GOO_ICON_NAME_NO_DISC, GTK_ICON_SIZE_DIALOG);
        gtk_widget_set_size_request (priv->status_image, COVER_SIZE, COVER_SIZE);
        gtk_widget_show (priv->cover_image);
        /*gtk_container_set_border_width (GTK_CONTAINER (priv->status_image), 6);*/
@@ -514,21 +514,21 @@ goo_player_info_set_cover (GooPlayerInfo *info,
 
        if (strcmp (cover, "no-disc") == 0) {
                gtk_notebook_set_current_page (GTK_NOTEBOOK (info->priv->notebook), 0);
-               gtk_image_set_from_stock (GTK_IMAGE (info->priv->status_image),
-                                         GOO_STOCK_NO_DISC,
-                                         GTK_ICON_SIZE_DIALOG);
+               gtk_image_set_from_icon_name (GTK_IMAGE (info->priv->status_image),
+                                             GOO_ICON_NAME_NO_DISC,
+                                             GTK_ICON_SIZE_DIALOG);
        }
        else if (strcmp (cover, "data-disc") == 0) {
                gtk_notebook_set_current_page (GTK_NOTEBOOK (info->priv->notebook), 0);
-               gtk_image_set_from_stock (GTK_IMAGE (info->priv->status_image),
-                                         GOO_STOCK_DATA_DISC,
-                                         GTK_ICON_SIZE_DIALOG);
+               gtk_image_set_from_icon_name (GTK_IMAGE (info->priv->status_image),
+                                             GOO_ICON_NAME_DATA_DISC,
+                                             GTK_ICON_SIZE_DIALOG);
        }
        else if (strcmp (cover, "audio-cd") == 0) {
                gtk_notebook_set_current_page (GTK_NOTEBOOK (info->priv->notebook), 1);
-               gtk_image_set_from_stock (GTK_IMAGE (info->priv->cover_image),
-                                         GOO_STOCK_AUDIO_CD,
-                                         GTK_ICON_SIZE_DIALOG);
+               gtk_image_set_from_icon_name (GTK_IMAGE (info->priv->cover_image),
+                                             GOO_ICON_NAME_NO_DISC,
+                                             GTK_ICON_SIZE_DIALOG);
        }
        else {
                info->priv->original_cover = gdk_pixbuf_new_from_file (cover, NULL);
diff --git a/src/goo-window-actions-callbacks.c b/src/goo-window-actions-callbacks.c
new file mode 100644
index 0000000..0271357
--- /dev/null
+++ b/src/goo-window-actions-callbacks.c
@@ -0,0 +1,361 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Goo
+ *
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "dlg-extract.h"
+#include "dlg-preferences.h"
+#include "dlg-properties.h"
+#include "gtk-utils.h"
+#include "goo-window.h"
+#include "goo-window-actions-callbacks.h"
+#include "preferences.h"
+
+
+void
+goo_window_activate_play (GSimpleAction *action,
+                         GVariant      *parameter,
+                         gpointer       user_data)
+{
+       goo_window_play (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_play_selected (GSimpleAction *action,
+                                  GVariant      *parameter,
+                                  gpointer       user_data)
+{
+       goo_window_play_selected (GOO_WINDOW (user_data));
+}
+
+
+
+void
+goo_window_activate_pause (GSimpleAction *action,
+                          GVariant      *parameter,
+                          gpointer       user_data)
+{
+       goo_window_pause (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_toggle_play (GSimpleAction *action,
+                                GVariant      *parameter,
+                                gpointer       user_data)
+{
+       goo_window_toggle_play (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_stop (GSimpleAction *action,
+                         GVariant      *parameter,
+                         gpointer       user_data)
+{
+       goo_window_stop (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_next_track (GSimpleAction *action,
+                               GVariant      *parameter,
+                               gpointer       user_data)
+{
+       goo_window_next (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_previous_track (GSimpleAction *action,
+                                   GVariant      *parameter,
+                                   gpointer       user_data)
+{
+       goo_window_prev (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_eject (GSimpleAction *action,
+                          GVariant      *parameter,
+                          gpointer       user_data)
+{
+       goo_window_eject (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_reload (GSimpleAction *action,
+                           GVariant      *parameter,
+                           gpointer       user_data)
+{
+       goo_window_update (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_close (GSimpleAction *action,
+                          GVariant      *parameter,
+                          gpointer       user_data)
+{
+       goo_window_close (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_play_all (GSimpleAction *action,
+                             GVariant      *parameter,
+                             gpointer       user_data)
+{
+       GSettings *settings;
+
+       g_simple_action_set_state (action, parameter);
+       settings = g_settings_new (GOOBOX_SCHEMA_PLAYLIST);
+       g_settings_set_boolean (settings, PREF_PLAYLIST_PLAYALL, g_variant_get_boolean (parameter));
+
+       g_object_unref (settings);
+}
+
+
+void
+goo_window_activate_repeat (GSimpleAction *action,
+                           GVariant      *parameter,
+                           gpointer       user_data)
+{
+       GSettings *settings;
+
+       g_simple_action_set_state (action, parameter);
+       settings = g_settings_new (GOOBOX_SCHEMA_PLAYLIST);
+       g_settings_set_boolean (settings, PREF_PLAYLIST_REPEAT, g_variant_get_boolean (parameter));
+
+       g_object_unref (settings);
+}
+
+
+void
+goo_window_activate_shuffle (GSimpleAction *action,
+                            GVariant      *parameter,
+                            gpointer       user_data)
+{
+       GSettings *settings;
+
+       g_simple_action_set_state (action, parameter);
+       settings = g_settings_new (GOOBOX_SCHEMA_PLAYLIST);
+       g_settings_set_boolean (settings, PREF_PLAYLIST_SHUFFLE, g_variant_get_boolean (parameter));
+
+       g_object_unref (settings);
+}
+
+
+/* -- goo_window_activate_copy_disc -- */
+
+
+static void
+external_app_watch_func (GPid     pid,
+                        gint     status,
+                        gpointer data)
+{
+       g_spawn_close_pid (pid);
+       goo_window_set_hibernate (GOO_WINDOW (data), FALSE);
+}
+
+
+static gboolean
+exec_external_app (GdkScreen   *screen,
+                  const char  *command_line,
+                  GError     **error,
+                  gpointer     data)
+{
+       gboolean   retval;
+       gchar    **argv = NULL;
+       GPid       child_pid;
+
+       g_return_val_if_fail (command_line != NULL, FALSE);
+
+       if (! g_shell_parse_argv (command_line, NULL, &argv, error))
+               return FALSE;
+
+       retval = g_spawn_async (NULL,
+                               argv,
+                               NULL,
+                               G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+                               NULL,
+                               NULL,
+                               &child_pid,
+                               error);
+       g_child_watch_add (child_pid, external_app_watch_func, data);
+
+       g_strfreev (argv);
+
+       return retval;
+}
+
+
+void
+goo_window_activate_copy_disc (GSimpleAction *action,
+                              GVariant      *parameter,
+                              gpointer       user_data)
+{
+       GooWindow *window = user_data;
+       char      *command;
+       GError    *error = NULL;
+
+       command = g_strconcat ("brasero --copy=",
+                              goo_player_get_device (goo_window_get_player (window)),
+                              NULL);
+
+       goo_window_set_hibernate (window, TRUE);
+       if (! exec_external_app (gtk_widget_get_screen (GTK_WIDGET (window)),
+                                command,
+                                &error,
+                                window))
+       {
+               _gtk_error_dialog_from_gerror_run (GTK_WINDOW (window),
+                                                  _("Could not execute command"),
+                                                  &error);
+               goo_window_set_hibernate (window, FALSE);
+       }
+
+       g_free (command);
+}
+
+
+void
+goo_window_activate_extract (GSimpleAction *action,
+                            GVariant      *parameter,
+                            gpointer       user_data)
+{
+       GooWindow *window = user_data;
+       GSettings *settings;
+       gboolean   use_sound_juicer;
+       GError    *error = NULL;
+
+       settings = g_settings_new (GOOBOX_SCHEMA_GENERAL);
+       use_sound_juicer = g_settings_get_boolean (settings, PREF_GENERAL_USE_SJ);
+       g_object_unref (settings);
+
+       if (! use_sound_juicer) {
+               dlg_extract (window);
+               return;
+       }
+
+       goo_window_set_hibernate (window, TRUE);
+
+       if (! exec_external_app (gtk_widget_get_screen (GTK_WIDGET (window)),
+                                "sound-juicer",
+                                &error,
+                                window))
+       {
+               _gtk_error_dialog_from_gerror_run (GTK_WINDOW (window),
+                                                  _("Could not execute command"),
+                                                  &error);
+               goo_window_set_hibernate (window, FALSE);
+       }
+}
+
+
+void
+goo_window_activate_extract_selected (GSimpleAction *action,
+                                     GVariant      *parameter,
+                                     gpointer       user_data)
+{
+       GooWindow *window = user_data;
+       GSettings *settings;
+       gboolean   use_sound_juicer;
+       GError    *error = NULL;
+
+       settings = g_settings_new (GOOBOX_SCHEMA_GENERAL);
+       use_sound_juicer = g_settings_get_boolean (settings, PREF_GENERAL_USE_SJ);
+       g_object_unref (settings);
+
+       if (! use_sound_juicer) {
+               dlg_extract_selected (window);
+               return;
+       }
+
+       goo_window_set_hibernate (window, TRUE);
+
+       if (! exec_external_app (gtk_widget_get_screen (GTK_WIDGET (window)),
+                                "sound-juicer",
+                                &error,
+                                window))
+       {
+               _gtk_error_dialog_from_gerror_run (GTK_WINDOW (window),
+                                                  _("Could not execute command"),
+                                                  &error);
+               goo_window_set_hibernate (window, FALSE);
+       }
+}
+
+
+void
+goo_window_activate_preferences (GSimpleAction *action,
+                                GVariant      *parameter,
+                                gpointer       user_data)
+{
+       dlg_preferences (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_pick_cover_from_disk (GSimpleAction *action,
+                                         GVariant      *parameter,
+                                         gpointer       user_data)
+{
+       goo_window_pick_cover_from_disk (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_search_cover (GSimpleAction *action,
+                                 GVariant      *parameter,
+                                 gpointer       user_data)
+{
+       goo_window_search_cover_on_internet (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_remove_cover (GSimpleAction *action,
+                                 GVariant      *parameter,
+                                 gpointer       user_data)
+{
+       goo_window_remove_cover (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_toggle_visibility (GSimpleAction *action,
+                                      GVariant      *parameter,
+                                      gpointer       user_data)
+{
+       goo_window_toggle_visibility (GOO_WINDOW (user_data));
+}
+
+
+void
+goo_window_activate_properties (GSimpleAction *action,
+                               GVariant      *parameter,
+                               gpointer       user_data)
+{
+       dlg_properties (GOO_WINDOW (user_data));
+}
diff --git a/src/goo-window-actions-callbacks.h b/src/goo-window-actions-callbacks.h
new file mode 100644
index 0000000..40c501c
--- /dev/null
+++ b/src/goo-window-actions-callbacks.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Goo
+ *
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GOO_WINDOW_ACTIONS_CALLBACKS_H
+#define GOO_WINDOW_ACTIONS_CALLBACKS_H
+
+#include <gtk/gtk.h>
+#include "glib-utils.h"
+
+DEF_ACTION_CALLBACK (goo_window_activate_play)
+DEF_ACTION_CALLBACK (goo_window_activate_play_selected)
+DEF_ACTION_CALLBACK (goo_window_activate_pause)
+DEF_ACTION_CALLBACK (goo_window_activate_toggle_play)
+DEF_ACTION_CALLBACK (goo_window_activate_stop)
+DEF_ACTION_CALLBACK (goo_window_activate_next_track)
+DEF_ACTION_CALLBACK (goo_window_activate_previous_track)
+DEF_ACTION_CALLBACK (goo_window_activate_eject)
+DEF_ACTION_CALLBACK (goo_window_activate_reload)
+DEF_ACTION_CALLBACK (goo_window_activate_close)
+DEF_ACTION_CALLBACK (goo_window_activate_play_all)
+DEF_ACTION_CALLBACK (goo_window_activate_repeat)
+DEF_ACTION_CALLBACK (goo_window_activate_shuffle)
+DEF_ACTION_CALLBACK (goo_window_activate_copy_disc)
+DEF_ACTION_CALLBACK (goo_window_activate_extract)
+DEF_ACTION_CALLBACK (goo_window_activate_extract_selected)
+DEF_ACTION_CALLBACK (goo_window_activate_preferences)
+DEF_ACTION_CALLBACK (goo_window_activate_pick_cover_from_disk)
+DEF_ACTION_CALLBACK (goo_window_activate_search_cover)
+DEF_ACTION_CALLBACK (goo_window_activate_remove_cover)
+DEF_ACTION_CALLBACK (goo_window_activate_toggle_visibility)
+DEF_ACTION_CALLBACK (goo_window_activate_properties)
+
+#endif /* GOO_WINDOW_ACTIONS_CALLBACKS_H */
diff --git a/src/goo-window-actions-entries.h b/src/goo-window-actions-entries.h
new file mode 100644
index 0000000..8dd3ebc
--- /dev/null
+++ b/src/goo-window-actions-entries.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Goo
+ *
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GOO_WINDOW_ACTIONS_ENTRIES_H
+#define GOO_WINDOW_ACTIONS_ENTRIES_H
+
+#include <config.h>
+#include "gtk-utils.h"
+#include "goo-window-actions-callbacks.h"
+
+
+static const GActionEntry goo_window_actions[] = {
+       { "play", goo_window_activate_play },
+       { "play-selected", goo_window_activate_play_selected },
+       { "pause", goo_window_activate_pause },
+       { "toggle-play", goo_window_activate_toggle_play },
+       { "stop", goo_window_activate_stop },
+       { "next-track", goo_window_activate_next_track },
+       { "previous-track", goo_window_activate_previous_track },
+       { "eject", goo_window_activate_eject },
+       { "reload", goo_window_activate_reload },
+       { "close", goo_window_activate_close },
+       { "play-all", goo_window_activate_play_all },
+       { "repeat", goo_window_activate_repeat },
+       { "shuffle", goo_window_activate_shuffle },
+       { "copy-disc", goo_window_activate_copy_disc },
+       { "extract", goo_window_activate_extract },
+       { "extract-selected", goo_window_activate_extract_selected },
+       { "preferences", goo_window_activate_preferences },
+       { "pick-cover-from-disk", goo_window_activate_pick_cover_from_disk },
+       { "search-cover", goo_window_activate_search_cover },
+       { "remove-cover", goo_window_activate_remove_cover },
+       { "toggle-visibility", goo_window_activate_toggle_visibility },
+       { "properties", goo_window_activate_properties }
+};
+
+
+static const _GtkAccelerator goo_window_accelerators[] = {
+        { "close", "<Control>w" },
+        { "toggle-play", "space" },
+        { "stop", "Escape" },
+        { "next-track", "n" },
+        { "previous-track", "p" },
+        { "eject", "j" },
+        { "extract", "e" },
+        { "close", "<Control>w" },
+        { "properties", "<Control>Return" }
+};
+
+
+#endif /* GOO_WINDOW_ACTIONS_ENTRIES_H */
diff --git a/src/goo-window.c b/src/goo-window.c
index 4155bfc..5d94c60 100644
--- a/src/goo-window.c
+++ b/src/goo-window.c
@@ -27,16 +27,14 @@
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
 #include <gst/gst.h>
-#include "actions.h"
 #include "gio-utils.h"
 #include "dlg-cover-chooser.h"
 #include "goo-marshal.h"
-#include "goo-stock.h"
 #include "goo-player.h"
 #include "goo-player-bar.h"
 #include "goo-player-info.h"
 #include "goo-window.h"
-#include "gth-toggle-menu-action.h"
+#include "goo-window-actions-entries.h"
 #include "gth-user-dir.h"
 #include "gtk-utils.h"
 #include "gtk-file-chooser-preview.h"
@@ -44,10 +42,8 @@
 #include "main.h"
 #include "preferences.h"
 #include "typedefs.h"
-#include "ui.h"
 #include "icons/pixbufs.h"
 
-#define ICON_GTK_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
 #define FILES_TO_PROCESS_AT_ONCE 500
 #define HIDE_TRACK_LIST N_("Hide _tracks")
 #define SHOW_TRACK_LIST N_("Show _tracks")
@@ -62,7 +58,6 @@
 #define MAX_WINDOW_HEIGHT_PERCENTAGE 0.80
 
 struct _GooWindowPrivate {
-       GtkUIManager      *ui;
        GtkWidget         *list_view;
        GtkListStore      *list_store;
        GtkWidget         *list_scrolled_window;
@@ -77,15 +72,11 @@ struct _GooWindowPrivate {
        GtkWidget         *info;
        GtkWidget         *player_bar;
 
-       guint              help_message_cid;
-       guint              list_info_cid;
-       guint              progress_cid;
-
        guint              first_time_event;
        guint              next_timeout_handle;
        gint               activity_ref;              /* when > 0 some activity
                                                        * is present. */
-       GtkActionGroup    *actions;
+       GtkAccelGroup     *accel_group;
        GSettings         *settings_general;
        GSettings         *settings_ui;
        GSettings         *settings_playlist;
@@ -132,23 +123,8 @@ enum {
        NUMBER_OF_COLUMNS
 };
 
-#define GOO_WINDOW_GET_PRIVATE_DATA(object) \
-       (G_TYPE_INSTANCE_GET_PRIVATE ((object), GOO_TYPE_WINDOW, GooWindowPrivate))
-
-
-G_DEFINE_TYPE (GooWindow, goo_window, GTH_TYPE_WINDOW)
-
 
-static void
-set_sensitive (GooWindow  *window,
-              const char *action_name,
-              gboolean    sensitive)
-{
-       GtkAction *action;
-
-       action = gtk_action_group_get_action (window->priv->actions, action_name);
-       g_object_set (action, "sensitive", sensitive, NULL);
-}
+G_DEFINE_TYPE (GooWindow, goo_window, GTK_TYPE_APPLICATION_WINDOW)
 
 
 static void
@@ -170,39 +146,33 @@ window_update_sensitivity (GooWindow *window)
        paused            = state == GOO_PLAYER_STATE_PAUSED;
        audio_cd          = (! error) && (goo_player_get_discid (window->priv->player) != NULL);
 
-       set_sensitive (window, "Play", audio_cd && !playing);
-       set_sensitive (window, "PlaySelected", audio_cd && one_file_selected);
-       set_sensitive (window, "Pause", audio_cd && playing);
-       set_sensitive (window, "Stop", audio_cd && (playing || paused));
-       set_sensitive (window, "TogglePlay", audio_cd);
-       set_sensitive (window, "Next", audio_cd);
-       set_sensitive (window, "Prev", audio_cd);
-
-       set_sensitive (window, "Extract", audio_cd && (window->priv->album->n_tracks > 0));
-       set_sensitive (window, "CopyDisc", audio_cd && (window->priv->album->n_tracks > 0));
-       set_sensitive (window, "Properties", audio_cd);
-       set_sensitive (window, "PickCoverFromDisk", audio_cd);
-       set_sensitive (window, "RemoveCover", audio_cd);
-       set_sensitive (window, "SearchCoverFromWeb", audio_cd);
-
        gtk_widget_set_sensitive (window->priv->list_view, audio_cd);
 
-       set_sensitive (window, "Eject", ! window->priv->hibernate);
-       set_sensitive (window, "EjectToolBar", ! window->priv->hibernate);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "play", audio_cd && ! playing);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "play-selected", audio_cd && one_file_selected);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "pause", audio_cd && playing);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "stop", audio_cd && (playing || paused));
+       _g_action_map_enable_action (G_ACTION_MAP (window), "toggle-play", audio_cd);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "next-track", audio_cd);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "previous-track", audio_cd);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "extract", audio_cd && 
(window->priv->album->n_tracks > 0));
+       _g_action_map_enable_action (G_ACTION_MAP (window), "copy-disc", audio_cd && 
(window->priv->album->n_tracks > 0));
+       _g_action_map_enable_action (G_ACTION_MAP (window), "properties", audio_cd);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "pick-cover-from-disk", audio_cd);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "remove-cover", audio_cd);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "search-cover", audio_cd);
+       _g_action_map_enable_action (G_ACTION_MAP (window), "eject", ! window->priv->hibernate);
 }
 
 
 static int
-get_icon_size_from_settings (GtkWidget   *widget,
-                            GtkIconSize  _gtk_icon_size)
+get_icon_size_from_settings (GtkIconSize gtk_icon_size)
 {
-       GtkSettings *settings;
-       int          width;
-       int          height;
-       int          icon_size;
+       int width;
+       int height;
+       int icon_size;
 
-       settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
-       if (gtk_icon_size_lookup_for_settings (settings, _gtk_icon_size, &width, &height))
+       if (gtk_icon_size_lookup (gtk_icon_size, &width, &height))
                icon_size = MAX (width, height);
        else
                icon_size = FALLBACK_ICON_SIZE;
@@ -217,7 +187,7 @@ create_void_icon (GooWindow *window)
        int        icon_size;
        GdkPixbuf *icon;
 
-       icon_size = get_icon_size_from_settings (GTK_WIDGET (window), GTK_ICON_SIZE_MENU);
+       icon_size = get_icon_size_from_settings (GTK_ICON_SIZE_MENU);
        icon = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, icon_size, icon_size);
        gdk_pixbuf_fill (icon, 0x00000000);
 
@@ -255,18 +225,18 @@ get_iter_from_track_number (GooWindow   *window,
 static void
 set_track_icon (GooWindow  *window,
                int         track_number,
-               const char *stock_id)
+               const char *icon_name)
 {
        GtkTreeIter  iter;
        GdkPixbuf   *icon;
 
-       if (!get_iter_from_track_number (window, track_number, &iter))
+       if (! get_iter_from_track_number (window, track_number, &iter))
                return;
 
-       if (stock_id != NULL)
+       if (icon_name != NULL)
                icon = gtk_icon_theme_load_icon (gtk_icon_theme_get_for_screen (gtk_widget_get_screen 
(GTK_WIDGET (window))),
-                                                stock_id,
-                                                get_icon_size_from_settings (GTK_WIDGET (window), 
GTK_ICON_SIZE_MENU),
+                                                icon_name,
+                                                get_icon_size_from_settings (GTK_ICON_SIZE_MENU),
                                                 0,
                                                 NULL);
        else
@@ -280,10 +250,10 @@ set_track_icon (GooWindow  *window,
 
 static void
 set_current_track_icon (GooWindow  *window,
-                       const char *stock_id)
+                       const char *icon_name)
 {
        if (window->priv->current_track != NULL)
-               set_track_icon (window, window->priv->current_track->number, stock_id);
+               set_track_icon (window, window->priv->current_track->number, icon_name);
 }
 
 
@@ -306,7 +276,7 @@ window_update_size (GooWindow *window)
        GdkGeometry  hints;
 
        window_height_without_playlist = 0;
-       vbox = gth_window_get_content (GTH_WINDOW (window), 0);
+       vbox = gtk_bin_get_child (GTK_BIN (window));
        for (scan = gtk_container_get_children (GTK_CONTAINER (vbox)); scan; scan = scan->next) {
                GtkWidget     *child = scan->data;
                GtkAllocation  allocation;
@@ -473,6 +443,7 @@ goo_window_finalize (GObject *object)
 
                /**/
 
+               _g_object_unref (window->priv->accel_group);
                _g_object_unref (window->priv->settings_ui);
                _g_object_unref (window->priv->settings_general);
                _g_object_unref (window->priv->settings_playlist);
@@ -1004,53 +975,11 @@ goo_window_show (GtkWidget *widget)
 }
 
 
-static gboolean
-check_state_for_closing_cb (gpointer data)
-{
-       GooWindow *self = data;
-
-       g_source_remove (self->priv->check_id);
-       self->priv->check_id = 0;
-
-       if (! goo_player_get_is_busy (self->priv->player)) {
-               gtk_widget_destroy (GTK_WIDGET (self));
-               return FALSE;
-       }
-
-       self->priv->check_id = g_timeout_add (PLAYER_CHECK_RATE,
-                                             check_state_for_closing_cb,
-                                             self);
-
-       return FALSE;
-}
-
-
-static void
-goo_window_real_close (GthWindow *base)
-{
-       GooWindow *self = GOO_WINDOW (base);
-
-       self->priv->exiting = TRUE;
-       if (goo_player_get_is_busy (self->priv->player)) {
-               gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
-
-               if (self->priv->check_id != 0)
-                       g_source_remove (self->priv->check_id);
-               self->priv->check_id = g_timeout_add (PLAYER_CHECK_RATE,
-                                                     check_state_for_closing_cb,
-                                                     self);
-       }
-       else
-               gtk_widget_destroy (GTK_WIDGET (self));
-}
-
-
 static void
 goo_window_class_init (GooWindowClass *class)
 {
        GObjectClass   *gobject_class;
        GtkWidgetClass *widget_class;
-       GthWindowClass *window_class;
 
        g_type_class_add_private (class, sizeof (GooWindowPrivate));
 
@@ -1061,9 +990,6 @@ goo_window_class_init (GooWindowClass *class)
        widget_class->unrealize = goo_window_unrealize;
        widget_class->show = goo_window_show;
 
-       window_class = (GthWindowClass *) class;
-       window_class->close = goo_window_real_close;
-
        goo_window_signals[UPDATE_COVER] =
                 g_signal_new ("update-cover",
                              G_TYPE_FROM_CLASS (class),
@@ -1084,7 +1010,7 @@ window_delete_event_cb (GtkWidget  *caller,
        if (goo_player_get_state (window->priv->player) == GOO_PLAYER_STATE_PLAYING)
                gtk_window_iconify (GTK_WINDOW (window));
        else
-               activate_action_quit (NULL, window);
+               gtk_widget_destroy (GTK_WIDGET (window));
 
        return TRUE;
 }
@@ -1258,25 +1184,6 @@ get_action_name (GooPlayerAction action)
 }
 
 
-static void
-_gtk_action_set_label_and_icon (GooWindow  *window,
-                               const char *action_name,
-                               const char *label,
-                               const char *tooltip,
-                               const char *icon_name)
-{
-       GtkAction *action;
-
-       action = gtk_action_group_get_action (window->priv->actions, action_name);
-       if (action != NULL)
-               g_object_set (G_OBJECT (action),
-                             /*"label", label,*/
-                             "tooltip", tooltip,
-                             "icon-name", icon_name,
-                             NULL);
-}
-
-
 static gboolean
 notify_current_state_cb (gpointer user_data)
 {
@@ -1366,10 +1273,6 @@ player_start_cb (GooPlayer       *player,
 
        switch (action) {
        case GOO_PLAYER_ACTION_PLAY:
-               _gtk_action_set_label_and_icon (window, "TogglePlay", _("_Pause"), _("Pause"), 
GOO_STOCK_PAUSE);
-               notify_current_state (window, action);
-               break;
-
        case GOO_PLAYER_ACTION_METADATA:
                notify_current_state (window, action);
                break;
@@ -1668,25 +1571,23 @@ player_done_cb (GooPlayer       *player,
        case GOO_PLAYER_ACTION_SEEK_SONG:
                goo_window_set_current_track (window, goo_player_get_current_track (window->priv->player));
                goo_window_select_current_track (window);
-               set_current_track_icon (window, GOO_STOCK_PLAY);
+               set_current_track_icon (window, GOO_ICON_NAME_PLAY);
                break;
 
        case GOO_PLAYER_ACTION_PLAY:
        case GOO_PLAYER_ACTION_STOP:
        case GOO_PLAYER_ACTION_MEDIUM_REMOVED:
-               _gtk_action_set_label_and_icon (window, "TogglePlay", _("_Play"), _("Play"), GOO_STOCK_PLAY);
                if (action == GOO_PLAYER_ACTION_PLAY) {
-                       set_current_track_icon (window, GOO_STOCK_PLAY);
+                       set_current_track_icon (window, GOO_ICON_NAME_PLAY);
                        window->priv->next_timeout_handle = g_idle_add (next_time_idle, window);
                }
                else if (action == GOO_PLAYER_ACTION_STOP)
-                       set_current_track_icon (window, GOO_STOCK_STOP);
+                       set_current_track_icon (window, GOO_ICON_NAME_STOP);
                notify_current_state (window, action);
                break;
 
        case GOO_PLAYER_ACTION_PAUSE:
-               set_current_track_icon (window, GOO_STOCK_PAUSE);
-               _gtk_action_set_label_and_icon (window, "TogglePlay", _("_Play"), _("Play"), GOO_STOCK_PLAY);
+               set_current_track_icon (window, GOO_ICON_NAME_PAUSE);
                notify_current_state (window, action);
                break;
 
@@ -1962,18 +1863,66 @@ window_key_press_cb (GtkWidget   *widget,
 }
 
 
+/* -- fr_window_add_accelerators -- */
+
+
+static GtkAccelGroup *
+goo_window_get_accel_group (GooWindow *window)
+{
+       if (window->priv->accel_group == NULL) {
+               window->priv->accel_group = gtk_accel_group_new ();
+               gtk_window_add_accel_group (GTK_WINDOW (window), window->priv->accel_group);
+       }
+
+       return window->priv->accel_group;
+}
+
+
+static void
+goo_window_add_accelerators (GooWindow                *window,
+                            const _GtkAccelerator    *accelerators,
+                            int                       n_accelerators)
+{
+       GtkAccelGroup *accel_group;
+       int            i;
+
+       accel_group = goo_window_get_accel_group (window);
+       for (i = 0; i < n_accelerators; i++) {
+               const _GtkAccelerator *acc = accelerators + i;
+
+               _gtk_window_add_accelerator_for_action (GTK_WINDOW (window),
+                                                       accel_group,
+                                                       acc->action_name,
+                                                       acc->accelerator,
+                                                       NULL);
+       }
+}
+
+
 static void
 goo_window_init (GooWindow *window)
 {
-       window->priv = GOO_WINDOW_GET_PRIVATE_DATA (window);
+       window->priv = G_TYPE_INSTANCE_GET_PRIVATE (window, GOO_TYPE_WINDOW, GooWindowPrivate);
        window->priv->exiting = FALSE;
        window->priv->check_id = 0;
        window->priv->url_list = NULL;
        window->priv->hibernate = FALSE;
        window->priv->album = album_info_new ();
        window->priv->resizable_playlist = FALSE;
+       window->priv->accel_group = gtk_accel_group_new ();
+       gtk_window_add_accel_group (GTK_WINDOW (window), window->priv->accel_group);
 
        gtk_window_set_title (GTK_WINDOW (window), _("CD Player"));
+
+       g_action_map_add_action_entries (G_ACTION_MAP (window),
+                                        goo_window_actions,
+                                        G_N_ELEMENTS (goo_window_actions),
+                                                window);
+       goo_window_add_accelerators (window,
+                                    goo_window_accelerators,
+                                    G_N_ELEMENTS (goo_window_accelerators));
+
+       gtk_window_set_application (GTK_WINDOW (window), Main_Application);
 }
 
 
@@ -2087,11 +2036,6 @@ goo_window_construct (GooWindow    *window,
        GtkWidget        *vbox;
        GtkWidget        *hbox;
        GtkTreeSelection *selection;
-       GtkActionGroup   *actions;
-       GtkAction        *action;
-       GtkAction        *other_actions_action;
-       GtkUIManager     *ui;
-       GError           *error = NULL;
 
        gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), 
"goobox-main-window");
        gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), 
GTK_STYLE_CLASS_VIEW);
@@ -2105,13 +2049,8 @@ goo_window_construct (GooWindow    *window,
                          G_CALLBACK (window_key_press_cb),
                          window);
 
-       if (icon_size == 0) {
-               int icon_width, icon_height;
-               gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (window)),
-                                                  ICON_GTK_SIZE,
-                                                  &icon_width, &icon_height);
-               icon_size = MAX (icon_width, icon_height);
-       }
+       if (icon_size == 0)
+               icon_size = get_icon_size_from_settings (GTK_ICON_SIZE_LARGE_TOOLBAR);
 
        /* Create the data */
 
@@ -2203,45 +2142,20 @@ goo_window_construct (GooWindow    *window,
        gtk_widget_set_hexpand (scrolled_window, TRUE);
        gtk_container_add (GTK_CONTAINER (scrolled_window), window->priv->list_view);
 
-       /* Build the menu and the toolbar. */
-
-       window->priv->actions = actions = gtk_action_group_new ("Actions");
-       gtk_action_group_set_translation_domain (actions, NULL);
+        /* popup menus */
+        {
+               GtkBuilder *builder;
 
-       other_actions_action = g_object_new (GTH_TYPE_TOGGLE_MENU_ACTION,
-                                            "name", "OtherActions",
-                                            "label", _("Other actions"),
-                                            "tooltip", _("Other actions"),
-                                            "icon-name", "emblem-system-symbolic",
-                                            "menu-halign", GTK_ALIGN_START,
-                                            "show-arrow", FALSE,
-                                            NULL);
-       gtk_action_group_add_action (actions, other_actions_action);
+               builder = _gtk_builder_new_from_resource ("menus.ui");
 
-       gtk_action_group_add_actions (actions,
-                                     action_entries,
-                                     n_action_entries,
-                                     window);
+               window->priv->file_popup_menu = gtk_menu_new_from_model (G_MENU_MODEL (gtk_builder_get_object 
(builder, "track-list-popup")));
+               gtk_menu_attach_to_widget (GTK_MENU (window->priv->file_popup_menu), GTK_WIDGET (window), 
NULL);
 
-       action = gtk_action_group_get_action (actions, "TogglePlay");
-       g_object_set (action, "always-show-image", TRUE, NULL);
+               window->priv->cover_popup_menu = gtk_menu_new_from_model (G_MENU_MODEL 
(gtk_builder_get_object (builder, "cover-popup")));
+               gtk_menu_attach_to_widget (GTK_MENU (window->priv->cover_popup_menu), GTK_WIDGET (window), 
NULL);
 
-       window->priv->ui = ui = gtk_ui_manager_new ();
-
-       gtk_ui_manager_insert_action_group (ui, actions, 0);
-       gtk_window_add_accel_group (GTK_WINDOW (window),
-                                   gtk_ui_manager_get_accel_group (ui));
-
-       if (! gtk_ui_manager_add_ui_from_resource (ui, "/org/gnome/Goobox/ui/menu-toolbars.ui", &error)) {
-               g_message ("building menus failed: %s", error->message);
-               g_error_free (error);
-       }
-
-       g_object_set (other_actions_action, "menu", gtk_ui_manager_get_widget (ui, "/OtherActionsMenu"), 
NULL);
-        g_object_unref (other_actions_action);
-
-       window->priv->file_popup_menu = gtk_ui_manager_get_widget (ui, "/ListPopupMenu");
-       window->priv->cover_popup_menu = gtk_ui_manager_get_widget (ui, "/CoverPopupMenu");
+               g_object_unref (builder);
+        }
 
        /**/
 
@@ -2264,7 +2178,7 @@ goo_window_construct (GooWindow    *window,
 
        gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
 
-       window->priv->player_bar = goo_player_bar_new (window->priv->player, actions);
+       window->priv->player_bar = goo_player_bar_new (window->priv->player, G_ACTION_MAP (window));
        g_signal_connect (window->priv->player_bar,
                          "skip-to",
                          G_CALLBACK (player_bar_skip_to_cb),
@@ -2277,8 +2191,7 @@ goo_window_construct (GooWindow    *window,
        gtk_widget_show_all (vbox);
        gtk_widget_hide (window->priv->list_scrolled_window);
 
-       gth_window_attach_content (GTH_WINDOW (window), 0, vbox);
-       gth_window_set_current_page (GTH_WINDOW (window), 0);
+       gtk_container_add (GTK_CONTAINER (window), vbox);
 
        gtk_widget_grab_focus (window->priv->list_view);
 
@@ -2328,19 +2241,54 @@ goo_window_new (BraseroDrive *drive)
 
        g_return_val_if_fail (drive != NULL, NULL);
 
-       window = (GooWindow*) g_object_new (GOO_TYPE_WINDOW,
-                                           "n-pages", 1,
-                                           NULL);
+       window = (GooWindow*) g_object_new (GOO_TYPE_WINDOW, NULL);
        goo_window_construct (window, drive);
 
        return (GtkWidget *) window;
 }
 
 
+/* -- goo_window_close -- */
+
+
+static gboolean
+check_state_for_closing_cb (gpointer data)
+{
+       GooWindow *self = data;
+
+       g_source_remove (self->priv->check_id);
+       self->priv->check_id = 0;
+
+       if (! goo_player_get_is_busy (self->priv->player)) {
+               gtk_widget_destroy (GTK_WIDGET (self));
+               return FALSE;
+       }
+
+       self->priv->check_id = g_timeout_add (PLAYER_CHECK_RATE,
+                                             check_state_for_closing_cb,
+                                             self);
+
+       return FALSE;
+}
+
+
 void
-goo_window_close (GooWindow *window)
+goo_window_close (GooWindow *base)
 {
-       gth_window_close (GTH_WINDOW (window));
+       GooWindow *self = GOO_WINDOW (base);
+
+       self->priv->exiting = TRUE;
+       if (goo_player_get_is_busy (self->priv->player)) {
+               gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
+
+               if (self->priv->check_id != 0)
+                       g_source_remove (self->priv->check_id);
+               self->priv->check_id = g_timeout_add (PLAYER_CHECK_RATE,
+                                                     check_state_for_closing_cb,
+                                                     self);
+       }
+       else
+               gtk_widget_destroy (GTK_WIDGET (self));
 }
 
 
@@ -2372,7 +2320,7 @@ goo_window_play (GooWindow *window)
                        play_track (window, 0);
        }
        else {
-               set_current_track_icon (window, GOO_STOCK_PLAY);
+               set_current_track_icon (window, GOO_ICON_NAME_PLAY);
                goo_player_play (window->priv->player);
        }
 }
@@ -2713,8 +2661,8 @@ goo_window_pick_cover_from_disk (GooWindow *window)
        file_sel = gtk_file_chooser_dialog_new (_("Choose Disc Cover Image"),
                                                GTK_WINDOW (window),
                                                GTK_FILE_CHOOSER_ACTION_OPEN,
-                                               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                               GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+                                               _GTK_LABEL_CANCEL, GTK_RESPONSE_CANCEL,
+                                               _GTK_LABEL_OPEN, GTK_RESPONSE_ACCEPT,
                                                NULL);
        gtk_window_set_modal (GTK_WINDOW (file_sel), TRUE);
        gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (file_sel), TRUE);
@@ -2771,10 +2719,10 @@ goo_window_search_cover_on_internet (GooWindow *window)
        if ((window->priv->album->title == NULL) || (window->priv->album->artist == NULL)) {
                _gtk_message_dialog_new (GTK_WINDOW (window),
                                         GTK_DIALOG_MODAL,
-                                        GTK_STOCK_DIALOG_ERROR,
+                                        _GTK_ICON_NAME_DIALOG_ERROR,
                                         _("Could not search for a cover on Internet"),
                                         _("You have to enter the artist and album names in order to find the 
album cover."),
-                                        GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+                                        _GTK_LABEL_CLOSE, GTK_RESPONSE_CLOSE,
                                         NULL);
                return;
        }
@@ -2815,16 +2763,12 @@ goo_window_toggle_visibility (GooWindow *window)
                                         &window->priv->pos_x,
                                         &window->priv->pos_y);
                gtk_widget_hide (GTK_WIDGET (window));
-
-               _gtk_action_set_label_and_icon (window, "ToggleVisibility", _("_Show Window"), _("Show the 
main window"), NULL);
        }
        else {
                gtk_window_move (GTK_WINDOW (window),
                                 window->priv->pos_x,
                                 window->priv->pos_y);
                gtk_window_present (GTK_WINDOW (window));
-
-               _gtk_action_set_label_and_icon (window, "ToggleVisibility", _("_Hide Window"), _("Hide the 
main window"), NULL);
        }
 }
 
diff --git a/src/goo-window.h b/src/goo-window.h
index 133ce86..e2fa9a6 100644
--- a/src/goo-window.h
+++ b/src/goo-window.h
@@ -27,7 +27,6 @@
 #include <brasero3/brasero-drive.h>
 #include "album-info.h"
 #include "goo-player.h"
-#include "gth-window.h"
 
 #define GOO_TYPE_WINDOW              (goo_window_get_type ())
 #define GOO_WINDOW(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_WINDOW, GooWindow))
@@ -42,7 +41,7 @@ typedef struct _GooWindowPrivate GooWindowPrivate;
 
 struct _GooWindow
 {
-       GthWindow __parent;
+       GtkApplicationWindow __parent;
        GtkWidget *preferences_dialog;
        GtkWidget *properties_dialog;
        GooWindowPrivate *priv;
@@ -50,7 +49,7 @@ struct _GooWindow
 
 struct _GooWindowClass
 {
-       GthWindowClass __parent_class;
+       GtkApplicationWindowClass __parent_class;
 
        /*<signals>*/
 
diff --git a/src/goobox.gresource.xml b/src/goobox.gresource.xml
index d186507..5ff3077 100644
--- a/src/goobox.gresource.xml
+++ b/src/goobox.gresource.xml
@@ -5,8 +5,9 @@
     <file compressed="true">ui/cover-chooser.ui</file>
     <file compressed="true">ui/extract.ui</file>
     <file compressed="true">ui/format-options.ui</file>
+    <file compressed="true">ui/gears-menu.ui</file>
     <file compressed="true">ui/goobox.css</file>
-    <file compressed="true">ui/menu-toolbars.ui</file>
+    <file compressed="true">ui/menus.ui</file>
     <file compressed="true">ui/message-dialog.ui</file>
     <file compressed="true">ui/preferences.ui</file>
     <file compressed="true">ui/properties.ui</file>
diff --git a/src/gtk-utils.c b/src/gtk-utils.c
index d1c4b59..470a33c 100644
--- a/src/gtk-utils.c
+++ b/src/gtk-utils.c
@@ -34,7 +34,7 @@
 GtkWidget *
 _gtk_message_dialog_new (GtkWindow        *parent,
                         GtkDialogFlags    flags,
-                        const char       *stock_id,
+                        const char       *icon_name,
                         const char       *message,
                         const char       *secondary_message,
                         const char       *first_button_text,
@@ -60,9 +60,9 @@ _gtk_message_dialog_new (GtkWindow        *parent,
 
        /* set the icon */
 
-       gtk_image_set_from_stock (GTK_IMAGE (_gtk_builder_get_widget (builder, "icon_image")),
-                                 stock_id,
-                                 GTK_ICON_SIZE_DIALOG);
+       gtk_image_set_from_icon_name (GTK_IMAGE (_gtk_builder_get_widget (builder, "icon_image")),
+                                     icon_name,
+                                     GTK_ICON_SIZE_DIALOG);
 
        /* set the message */
 
@@ -160,7 +160,7 @@ _gtk_ok_dialog_with_checkbutton_new (GtkWindow        *parent,
 
        d = _gtk_message_dialog_new (parent,
                                     flags,
-                                    GTK_STOCK_DIALOG_INFO,
+                                    _GTK_ICON_NAME_DIALOG_INFO,
                                     message,
                                     NULL,
                                     ok_button_text, GTK_RESPONSE_OK,
@@ -200,10 +200,10 @@ _gtk_error_dialog_from_gerror_run (GtkWindow   *parent,
 
        d = _gtk_message_dialog_new (parent,
                                     GTK_DIALOG_DESTROY_WITH_PARENT,
-                                    GTK_STOCK_DIALOG_ERROR,
+                                    _GTK_ICON_NAME_DIALOG_ERROR,
                                     title,
                                     (*gerror)->message,
-                                    GTK_STOCK_OK, GTK_RESPONSE_OK,
+                                    _GTK_LABEL_OK, GTK_RESPONSE_OK,
                                     NULL);
        gtk_dialog_run (GTK_DIALOG (d));
 
@@ -230,10 +230,10 @@ _gtk_error_dialog_from_gerror_show (GtkWindow   *parent,
 
        d = _gtk_message_dialog_new (parent,
                                     GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                    GTK_STOCK_DIALOG_ERROR,
+                                    _GTK_ICON_NAME_DIALOG_ERROR,
                                     title,
                                     (gerror != NULL) ? (*gerror)->message : NULL,
-                                    GTK_STOCK_OK, GTK_RESPONSE_OK,
+                                    _GTK_LABEL_OK, GTK_RESPONSE_OK,
                                     NULL);
        g_signal_connect (d, "response", G_CALLBACK (error_dialog_response_cb), NULL);
 
@@ -260,10 +260,10 @@ _gtk_error_dialog_run (GtkWindow        *parent,
 
        d =  _gtk_message_dialog_new (parent,
                                      GTK_DIALOG_MODAL,
-                                     GTK_STOCK_DIALOG_ERROR,
+                                     _GTK_ICON_NAME_DIALOG_ERROR,
                                      message,
                                      NULL,
-                                     GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL,
+                                     _GTK_LABEL_CLOSE, GTK_RESPONSE_CANCEL,
                                      NULL);
        g_free (message);
 
@@ -290,10 +290,10 @@ _gtk_info_dialog_run (GtkWindow        *parent,
 
        d =  _gtk_message_dialog_new (parent,
                                      GTK_DIALOG_MODAL,
-                                     GTK_STOCK_DIALOG_INFO,
+                                     _GTK_ICON_NAME_DIALOG_INFO,
                                      message,
                                      NULL,
-                                     GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL,
+                                     _GTK_LABEL_CLOSE, GTK_RESPONSE_CANCEL,
                                      NULL);
        g_free (message);
 
@@ -478,9 +478,8 @@ _gtk_icon_get_pixel_size (GtkWidget   *widget,
 {
        int icon_width, icon_height;
 
-       gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
-                                          size,
-                                          &icon_width, &icon_height);
+       gtk_icon_size_lookup (size, &icon_width, &icon_height);
+
        return MAX (icon_width, icon_height);
 }
 
@@ -498,10 +497,10 @@ show_help_dialog (GtkWindow  *parent,
 
                dialog = _gtk_message_dialog_new (parent,
                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
-                                                 GTK_STOCK_DIALOG_ERROR,
+                                                 _GTK_ICON_NAME_DIALOG_ERROR,
                                                  _("Could not display help"),
                                                  error->message,
-                                                 GTK_STOCK_OK, GTK_RESPONSE_OK,
+                                                 _GTK_LABEL_OK, GTK_RESPONSE_OK,
                                                  NULL);
                gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 
@@ -825,3 +824,219 @@ _gtk_count_selected (GtkTreeSelection *selection)
        return n;
 }
 
+
+/* -- _gtk_window_add_accelerator_for_action -- */
+
+
+typedef struct {
+       GtkWindow *window;
+       char      *action_name;
+       GVariant  *target;
+} AccelData;
+
+
+static void
+accel_data_free (gpointer  user_data,
+                 GClosure *closure)
+{
+       AccelData *accel_data = user_data;
+
+       g_return_if_fail (accel_data != NULL);
+
+       if (accel_data->target != NULL)
+               g_variant_unref (accel_data->target);
+       g_free (accel_data->action_name);
+       g_free (accel_data);
+}
+
+
+static void
+window_accelerator_activated_cb (GtkAccelGroup  *accel_group,
+                                GObject                *object,
+                                guint           key,
+                                GdkModifierType         mod,
+                                gpointer                user_data)
+{
+       AccelData *accel_data = user_data;
+       GAction   *action;
+
+       action = g_action_map_lookup_action (G_ACTION_MAP (accel_data->window), accel_data->action_name);
+       if (action != NULL)
+               g_action_activate (action, accel_data->target);
+}
+
+
+void
+_gtk_window_add_accelerator_for_action (GtkWindow       *window,
+                                       GtkAccelGroup   *accel_group,
+                                       const char      *action_name,
+                                       const char      *accel,
+                                       GVariant        *target)
+{
+       AccelData       *accel_data;
+       guint            key;
+       GdkModifierType  mods;
+       GClosure        *closure;
+
+       if ((action_name == NULL) || (accel == NULL))
+               return;
+
+       if (g_str_has_prefix (action_name, "app."))
+               return;
+
+       accel_data = g_new0 (AccelData, 1);
+       accel_data->window = window;
+       /* remove the win. prefix from the action name */
+       if (g_str_has_prefix (action_name, "win."))
+               accel_data->action_name = g_strdup (action_name + strlen ("win."));
+       else
+               accel_data->action_name = g_strdup (action_name);
+       if (target != NULL)
+               accel_data->target = g_variant_ref (target);
+
+       gtk_accelerator_parse (accel, &key, &mods);
+       closure = g_cclosure_new (G_CALLBACK (window_accelerator_activated_cb),
+                                 accel_data,
+                                 accel_data_free);
+       gtk_accel_group_connect (accel_group,
+                                key,
+                                mods,
+                                0,
+                                closure);
+}
+
+
+/* -- _gtk_window_add_accelerators_from_menu --  */
+
+
+static void
+add_accelerators_from_menu_item (GtkWindow      *window,
+                                GtkAccelGroup  *accel_group,
+                                GMenuModel     *model,
+                                int             item)
+{
+       GMenuAttributeIter      *iter;
+       const char              *key;
+       GVariant                *value;
+       const char              *accel = NULL;
+       const char              *action = NULL;
+       GVariant                *target = NULL;
+
+       iter = g_menu_model_iterate_item_attributes (model, item);
+       while (g_menu_attribute_iter_get_next (iter, &key, &value)) {
+                       if (g_str_equal (key, "action") && g_variant_is_of_type (value, 
G_VARIANT_TYPE_STRING))
+                               action = g_variant_get_string (value, NULL);
+                       else if (g_str_equal (key, "accel") && g_variant_is_of_type (value, 
G_VARIANT_TYPE_STRING))
+                               accel = g_variant_get_string (value, NULL);
+                       else if (g_str_equal (key, "target"))
+                               target = g_variant_ref (value);
+                       g_variant_unref (value);
+       }
+       g_object_unref (iter);
+
+       _gtk_window_add_accelerator_for_action (window,
+                                               accel_group,
+                                               action,
+                                               accel,
+                                               target);
+
+               if (target != NULL)
+                       g_variant_unref (target);
+}
+
+static void
+add_accelerators_from_menu (GtkWindow      *window,
+                           GtkAccelGroup  *accel_group,
+                           GMenuModel     *model)
+{
+       int              i;
+       GMenuLinkIter   *iter;
+       const char      *key;
+       GMenuModel      *m;
+
+       for (i = 0; i < g_menu_model_get_n_items (model); i++) {
+               add_accelerators_from_menu_item (window, accel_group, model, i);
+
+               iter = g_menu_model_iterate_item_links (model, i);
+               while (g_menu_link_iter_get_next (iter, &key, &m)) {
+                       add_accelerators_from_menu (window, accel_group, m);
+                       g_object_unref (m);
+               }
+               g_object_unref (iter);
+       }
+}
+
+
+void
+_gtk_window_add_accelerators_from_menu (GtkWindow  *window,
+                                       GMenuModel *menu)
+{
+       GtkAccelGroup *accel_group;
+
+       accel_group = gtk_accel_group_new ();
+       add_accelerators_from_menu (window, accel_group, menu);
+       gtk_window_add_accel_group (window, accel_group);
+}
+
+
+void
+_g_action_map_enable_action (GActionMap *action_map,
+                            const char *action_name,
+                            gboolean    enabled)
+{
+       GAction *action;
+
+       action = g_action_map_lookup_action (action_map, action_name);
+       g_return_if_fail (action != NULL);
+
+       g_object_set (action, "enabled", enabled, NULL);
+}
+
+
+void
+_g_action_map_set_action_state (GActionMap *action_map,
+                               const char *action_name,
+                               gboolean    active)
+{
+        GAction *action;
+
+        action = g_action_map_lookup_action (action_map, action_name);
+        g_return_if_fail (action != NULL);
+
+        g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (active));
+}
+
+
+void
+_g_action_map_change_action_state (GActionMap *action_map,
+                                  const char *action_name,
+                                  gboolean    value)
+{
+        GAction  *action;
+        GVariant *old_state;
+        GVariant *new_state;
+
+        action = g_action_map_lookup_action (action_map, action_name);
+        g_return_if_fail (action != NULL);
+
+        old_state = g_action_get_state (action);
+        new_state = g_variant_new_boolean (value);
+        if ((old_state == NULL) || ! g_variant_equal (old_state, new_state))
+                g_action_change_state (action, new_state);
+
+        if (old_state != NULL)
+                g_variant_unref (old_state);
+}
+
+
+GtkWidget *
+_gtk_application_get_current_window (GtkApplication *application)
+{
+       GList *windows;
+
+       windows = gtk_application_get_windows (application);
+       if (windows == NULL)
+               return NULL;
+
+       return GTK_WIDGET (windows->data);
+}
diff --git a/src/gtk-utils.h b/src/gtk-utils.h
index b42c752..4eee433 100644
--- a/src/gtk-utils.h
+++ b/src/gtk-utils.h
@@ -29,6 +29,43 @@
 
 G_BEGIN_DECLS
 
+#define _GTK_ICON_NAME_DIALOG_ERROR "dialog-error-symbolic"
+#define _GTK_ICON_NAME_DIALOG_INFO "dialog-information-symbolic"
+#define _GTK_ICON_NAME_DIALOG_QUESTION "dialog-question-symbolic"
+#define _GTK_ICON_NAME_DIALOG_WARNING "dialog-warning-symbolic"
+
+#define _GTK_LABEL_CANCEL _("_Cancel")
+#define _GTK_LABEL_CLOSE _("_Close")
+#define _GTK_LABEL_OK _("_Ok")
+#define _GTK_LABEL_OPEN _("_Open")
+#define _GTK_LABEL_RESET _("_Reset")
+
+#define GOO_ICON_NAME_PLAY        "media-playback-start-symbolic"
+#define GOO_ICON_NAME_PLAY_RTL    "media-playback-start-rtl-symbolic"
+#define GOO_ICON_NAME_PAUSE       "media-playback-pause-symbolic"
+#define GOO_ICON_NAME_STOP        "media-playback-stop-symbolic"
+#define GOO_ICON_NAME_NEXT        "media-skip-forward-symbolic"
+#define GOO_ICON_NAME_NEXT_RTL    "media-skip-forward-rtl-symbolic"
+#define GOO_ICON_NAME_PREV        "media-skip-backward-symbolic"
+#define GOO_ICON_NAME_PREV_RTL    "media-skip-backward-rtl-symbolic"
+#define GOO_ICON_NAME_EJECT       "media-eject-symbolic"
+#define GOO_ICON_NAME_EXTRACT     "document-save-symbolic"
+#define GOO_ICON_NAME_RESET       "goo-reset"
+#define GOO_ICON_NAME_NO_DISC     "media-optical-symbolic"
+#define GOO_ICON_NAME_DATA_DISC   "drive-harddisk-symbolic"
+#define GOO_ICON_NAME_AUDIO_CD    "media-optical-symbolic"
+#define GOO_ICON_NAME_VOLUME_MAX  "audio-volume-high-symbolic"
+#define GOO_ICON_NAME_VOLUME_MED  "audio-volume-medium-symbolic"
+#define GOO_ICON_NAME_VOLUME_MIN  "audio-volume-low-symbolic"
+#define GOO_ICON_NAME_VOLUME_ZERO "audio-volume-muted-symbolic"
+
+
+typedef struct {
+        const char *action_name;
+        const char *accelerator;
+} _GtkAccelerator;
+
+
 GtkWidget*  _gtk_message_dialog_new        (GtkWindow        *parent,
                                            GtkDialogFlags    flags,
                                            const char       *stock_id,
@@ -98,11 +135,28 @@ void        _gtk_tree_path_list_free       (GList            *list);
 int         _gtk_paned_get_position2       (GtkPaned         *paned);
 void        _gtk_paned_set_position2       (GtkPaned         *paned,
                                            int               pos);
-void        _g_launch_command              (GtkWidget        *parent,
-                                           const char       *command,
-                                           const char       *name,
-                                           GList            *files);
-int         _gtk_count_selected            (GtkTreeSelection *selection);
+void           _g_launch_command                       (GtkWidget              *parent,
+                                                        const char             *command,
+                                                        const char             *name,
+                                                        GList                  *files);
+int            _gtk_count_selected                     (GtkTreeSelection       *selection);
+void           _gtk_window_add_accelerator_for_action  (GtkWindow              *window,
+                                                        GtkAccelGroup          *accel_group,
+                                                        const char             *action_name,
+                                                        const char             *accel,
+                                                        GVariant               *target);
+void           _gtk_window_add_accelerators_from_menu  (GtkWindow              *window,
+                                                        GMenuModel             *menu);
+void           _g_action_map_enable_action             (GActionMap             *action_map,
+                                                        const char             *action_name,
+                                                        gboolean                enabled);
+void           _g_action_map_set_action_state          (GActionMap             *action_map,
+                                                        const char             *action_name,
+                                                        gboolean                active);
+void           _g_action_map_change_action_state       (GActionMap             *action_map,
+                                                        const char             *action_name,
+                                                        gboolean                value);
+GtkWidget *    _gtk_application_get_current_window     (GtkApplication         *application);
 
 G_END_DECLS
 
diff --git a/src/main.c b/src/main.c
index 862a5fb..09908b2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -27,694 +27,34 @@
 #include <glib.h>
 #include <glib/gprintf.h>
 #include <gtk/gtk.h>
-#include "actions.h"
-#include "eggsmclient.h"
+#include "glib-utils.h"
+#include "goo-application.h"
 #include "goo-player-info.h"
-#include "goo-stock.h"
 #include "goo-window.h"
-#include "typedefs.h"
-#include "preferences.h"
-#include "main.h"
 #include "gtk-utils.h"
-#include "glib-utils.h"
+#include "main.h"
+#include "preferences.h"
+#include "typedefs.h"
 #ifdef ENABLE_NOTIFICATION
 #include <libnotify/notify.h>
 #ifndef NOTIFY_CHECK_VERSION
 #define NOTIFY_CHECK_VERSION(x,y,z) 0
 #endif
 static NotifyNotification *notification = NULL;
-gboolean                   notification_supports_persistence = FALSE;
-gboolean                   notification_supports_actions = FALSE;
+static gboolean            notification_supports_persistence = FALSE;
+static gboolean            notification_supports_actions = FALSE;
 #endif /* ENABLE_NOTIFICATION */
 
 
-#define VOLUME_STEP 0.10
-
-
-/* -- command line arguments -- */
-
-
-int                    arg_auto_play = FALSE;
-int                    arg_toggle_visibility = FALSE;
-static int             arg_toggle_play = FALSE;
-static int             arg_stop = FALSE;
-static int             arg_next = FALSE;
-static int             arg_prev = FALSE;
-static int             arg_eject = FALSE;
-static int             arg_quit = FALSE;
-static gboolean        arg_version = FALSE;
-static char           *arg_device = NULL;
-static const char     *program_argv0; /* argv[0] from main(); used as the command to restart the program */
-
-
-static const GOptionEntry options[] = {
-       { "device", 'd',  0, G_OPTION_ARG_STRING, &arg_device,
-         N_("CD device to be used"),
-         N_("DEVICE_PATH") },
-       { "play", '\0', 0, G_OPTION_ARG_NONE, &arg_auto_play,
-          N_("Play the CD on startup"),
-          0 },
-       { "toggle-play", '\0', 0, G_OPTION_ARG_NONE, &arg_toggle_play,
-          N_("Toggle play"),
-          0 },
-        { "stop", '\0', 0, G_OPTION_ARG_NONE, &arg_stop,
-          N_("Stop playing"),
-          0 },
-       { "next", '\0', 0, G_OPTION_ARG_NONE, &arg_next,
-          N_("Play the next track"),
-          0 },
-       { "previous", '\0', 0, G_OPTION_ARG_NONE, &arg_prev,
-          N_("Play the previous track"),
-          0 },
-       { "eject", '\0', 0, G_OPTION_ARG_NONE, &arg_eject,
-          N_("Eject the CD"),
-          0 },
-       { "toggle-visibility", '\0', 0, G_OPTION_ARG_NONE, &arg_toggle_visibility,
-          N_("Toggle the main window visibility"),
-          0 },
-       { "quit", '\0', 0, G_OPTION_ARG_NONE, &arg_quit,
-          N_("Quit the application"),
-          0 },
-        { "version", 'v', 0, G_OPTION_ARG_NONE, &arg_version,
-         N_("Show version"),
-         0 },
-       { NULL }
-};
-
-
-/* -- session management -- */
-
-
-static void
-client_save_state (EggSMClient *client,
-                  GKeyFile    *state,
-                  gpointer     user_data)
-{
-       GApplication *application = user_data;
-       const char   *argv[2] = { NULL };
-       guint         i;
-       GList        *scan;
-
-       argv[0] = program_argv0;
-       argv[1] = NULL;
-       egg_sm_client_set_restart_command (client, 1, argv);
-
-       i = 0;
-       for (scan = gtk_application_get_windows (GTK_APPLICATION (application)); scan; scan = scan->next) {
-               GtkWidget *window = scan->data;
-               char      *key;
-
-               key = g_strdup_printf ("device%d", ++i);
-               g_key_file_set_string (state,
-                                      "Session",
-                                      key,
-                                      goo_player_get_device (goo_window_get_player (GOO_WINDOW (window))));
-
-               g_free (key);
-       }
-
-       g_key_file_set_integer (state, "Session", "devices", i);
-}
-
-
-static void
-client_quit_requested_cb (EggSMClient *client,
-                         gpointer     data)
-{
-       egg_sm_client_will_quit (client, TRUE);
-}
-
-
-static void
-client_quit_cb (EggSMClient *client,
-               gpointer     data)
-{
-       gtk_main_quit ();
-}
-
-
-static void
-goo_session_manager_init (GApplication *application)
-{
-       EggSMClient *client = NULL;
-
-       client = egg_sm_client_get ();
-       g_signal_connect (client,
-                         "save_state",
-                         G_CALLBACK (client_save_state),
-                         application);
-       g_signal_connect (client,
-                         "quit_requested",
-                         G_CALLBACK (client_quit_requested_cb),
-                         application);
-       g_signal_connect (client,
-                         "quit",
-                         G_CALLBACK (client_quit_cb),
-                         application);
-}
-
-
-static void
-goo_restore_session (EggSMClient  *client,
-                    GApplication *application)
-{
-       GKeyFile *state = NULL;
-       guint     i;
-
-       state = egg_sm_client_get_state_file (client);
-       i = g_key_file_get_integer (state, "Session", "devices", NULL);
-       g_assert (i > 0);
-       for (/* void */; i > 0; i--) {
-               char         *key;
-               char         *device;
-               BraseroDrive *drive;
-               GtkWidget    *window;
-
-               key = g_strdup_printf ("device%d", i);
-               device = g_key_file_get_string (state, "Session", key, NULL);
-               g_free (key);
-
-               g_assert (device != NULL);
-
-               drive = main_get_drive_for_device (device);
-               window = goo_window_new (drive);
-               gtk_window_set_application (GTK_WINDOW (window), GTK_APPLICATION (application));
-               gtk_widget_show (window);
-
-               g_object_unref (drive);
-               g_free (device);
-       }
-}
-
-
-/* -- main application -- */
-
-
 GtkApplication *Main_Application = NULL;
-
-
-typedef struct {
-       GtkApplication __parent;
-       GSettings *settings;
-} GooApplication;
-
-
-typedef GtkApplicationClass GooApplicationClass;
-
-
-G_DEFINE_TYPE (GooApplication, goo_application, GTK_TYPE_APPLICATION)
-
-
-static void
-goo_application_finalize (GObject *object)
-{
-       GooApplication *self = (GooApplication *) object;
-
-       g_object_unref (self->settings);
-       G_OBJECT_CLASS (goo_application_parent_class)->finalize (object);
-}
-
-
-static void
-goo_application_init (GooApplication *self)
-{
-       g_set_application_name (_("CD Player"));
-
-       self->settings = g_settings_new (GOOBOX_SCHEMA_PLAYLIST);
-}
-
-
-static void
-goo_application_activate (GApplication *application)
-{
-       GtkWidget *window;
-
-       window = goo_window_new (NULL);
-       gtk_widget_show (window);
-}
-
-
-static gboolean
-required_gstreamer_plugins_available (void)
-{
-       char *required_plugins[] = { "cdparanoiasrc", "audioconvert", "volume", "giosink" };
-       int   i;
-
-       for (i = 0; i < G_N_ELEMENTS (required_plugins); i++) {
-               GstElement *element;
-               gboolean    present;
-
-               element = gst_element_factory_make (required_plugins[i], NULL);
-               present = (element != NULL);
-               if (element != NULL)
-                       gst_object_unref (GST_OBJECT (element));
-
-               if (! present)
-                       return FALSE;
-       }
-
-       return TRUE;
-}
-
-
-static gboolean
-init_application (GApplication *application)
-{
-       EggSMClient *client = NULL;
-
-        gtk_window_set_default_icon_name ("goobox");
-        goo_stock_init ();
-
-       if (! required_gstreamer_plugins_available ()) {
-               GtkWidget *d;
-               d = _gtk_message_dialog_new (NULL,
-                                            0,
-                                            GTK_STOCK_DIALOG_ERROR,
-                                            _("Cannot start the CD player"),
-                                            _("In order to read CDs you have to install the gstreamer base 
plugins"),
-                                            GTK_STOCK_OK, GTK_RESPONSE_OK,
-                                            NULL);
-               g_signal_connect_swapped (G_OBJECT (d), "response",
-                                         G_CALLBACK (gtk_widget_destroy),
-                                         d);
-               gtk_window_set_application (GTK_WINDOW (d), GTK_APPLICATION (application));
-               gtk_widget_show (d);
-
-               return FALSE;
-       }
-
-#ifdef ENABLE_NOTIFICATION
-       if (! notify_init (g_get_application_name ()))
-                g_warning ("Cannot initialize notification system.");
-#endif /* ENABLE_NOTIFICATION */
-
-       goo_session_manager_init (application);
-
-       client = egg_sm_client_get ();
-       if (egg_sm_client_is_resumed (client)) {
-               goo_restore_session (client, application);
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
-
-static int
-goo_application_command_line (GApplication            *application,
-                             GApplicationCommandLine *command_line)
-{
-       char           **argv;
-       int              argc;
-       GOptionContext  *options_context;
-       GError          *error = NULL;
-       GList           *window_list;
-       GtkWidget       *window;
-
-       argv = g_application_command_line_get_arguments (command_line, &argc);
-
-       options_context = g_option_context_new (N_("Play CDs and save the tracks to disk as files"));
-       g_option_context_set_translation_domain (options_context, GETTEXT_PACKAGE);
-       g_option_context_add_main_entries (options_context, options, GETTEXT_PACKAGE);
-       g_option_context_add_group (options_context, gtk_get_option_group (TRUE));
-       g_option_context_add_group (options_context, egg_sm_client_get_option_group ());
-       g_option_context_add_group (options_context, gst_init_get_option_group ());
-       g_option_context_set_ignore_unknown_options (options_context, TRUE);
-       if (! g_option_context_parse (options_context, &argc, &argv, &error)) {
-               g_critical ("Failed to parse arguments: %s", error->message);
-               g_error_free (error);
-               return EXIT_FAILURE;
-       }
-
-       window_list = gtk_application_get_windows (GTK_APPLICATION (application));
-       if (window_list == NULL) {
-               if (! init_application (application))
-                       return 0;
-               window = goo_window_new (NULL);
-               gtk_window_set_application (GTK_WINDOW (window), GTK_APPLICATION (application));
-               gtk_widget_show (window);
-       }
-       else
-               window = window_list->data;
-
-       if (arg_auto_play) {
-               goo_window_play (GOO_WINDOW (window));
-       }
-       else if (arg_toggle_play) {
-               goo_window_toggle_play (GOO_WINDOW (window));
-       }
-       else if (arg_stop) {
-               goo_window_stop (GOO_WINDOW (window));
-       }
-       else if (arg_next) {
-               goo_window_next (GOO_WINDOW (window));
-       }
-       else if (arg_prev) {
-               goo_window_prev (GOO_WINDOW (window));
-       }
-       else if (arg_eject) {
-               goo_window_eject (GOO_WINDOW (window));
-       }
-       else if (arg_toggle_visibility) {
-               goo_window_toggle_visibility (GOO_WINDOW (window));
-       }
-       else if (arg_quit) {
-               goo_window_close (GOO_WINDOW (window));
-       }
-       else if (arg_device != NULL) {
-               BraseroDrive *drive;
-
-               drive = main_get_drive_for_device (arg_device);
-               window = main_get_window_from_device (arg_device);
-               if (window == NULL) {
-                       window = goo_window_new (drive);
-                       gtk_window_set_application (GTK_WINDOW (window), GTK_APPLICATION (application));
-                       gtk_widget_show (window);
-               }
-               else
-                       goo_window_set_drive (GOO_WINDOW (window), drive);
-
-               g_object_unref (drive);
-               g_free (arg_device);
-               arg_device = NULL;
-       }
-
-       /* reset arguments */
-
-       arg_auto_play = FALSE;
-       arg_toggle_play = FALSE;
-       arg_stop = FALSE;
-       arg_next = FALSE;
-       arg_prev = FALSE;
-       arg_eject = FALSE;
-       arg_toggle_visibility = FALSE;
-       arg_quit = FALSE;
-       g_free (arg_device);
-       arg_device = NULL;
-
-       return 0;
-}
-
-
-static gboolean
-goo_application_local_command_line (GApplication   *application,
-                                   char         ***arguments,
-                                   int            *exit_status)
-{
-       char           **local_argv;
-       int              local_argc;
-       GOptionContext  *options_context;
-       GError          *error = NULL;
-       gboolean         handled_locally = FALSE;
-
-       local_argv = g_strdupv (*arguments);
-       local_argc = g_strv_length (local_argv);
-
-       *exit_status = 0;
-
-       options_context = g_option_context_new (N_("Play CDs and save the tracks to disk as files"));
-       g_option_context_set_translation_domain (options_context, GETTEXT_PACKAGE);
-       g_option_context_add_main_entries (options_context, options, GETTEXT_PACKAGE);
-       g_option_context_add_group (options_context, gtk_get_option_group (TRUE));
-       g_option_context_add_group (options_context, egg_sm_client_get_option_group ());
-       g_option_context_add_group (options_context, gst_init_get_option_group ());
-       g_option_context_set_ignore_unknown_options (options_context, TRUE);
-       if (! g_option_context_parse (options_context, &local_argc, &local_argv, &error)) {
-               *exit_status = EXIT_FAILURE;
-               g_critical ("Failed to parse arguments: %s", error->message);
-               g_clear_error (&error);
-               handled_locally = TRUE;
-       }
-
-       if (arg_version) {
-               g_printf ("%s %s, Copyright © 2001-2011 Free Software Foundation, Inc.\n", PACKAGE_NAME, 
PACKAGE_VERSION);
-               handled_locally = TRUE;
-       }
-
-       g_strfreev (local_argv);
-
-       return handled_locally;
-}
-
-
-/* -- application menu  -- */
-
-
-static void
-toggle_action_activated (GSimpleAction *action,
-                         GVariant      *parameter,
-                         gpointer       data)
-{
-       GVariant *state;
-
-       state = g_action_get_state (G_ACTION (action));
-       g_action_change_state (G_ACTION (action), g_variant_new_boolean (! g_variant_get_boolean (state)));
-
-       g_variant_unref (state);
-}
-
-
-static void
-update_app_menu_sensitivity (GooApplication *application)
-{
-       GVariant *state;
-       gboolean  play_all;
-
-       state = g_action_get_state (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_PLAYALL));
-       play_all = g_variant_get_boolean (state);
-       g_variant_unref (state);
-
-       g_simple_action_set_enabled (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_REPEAT)), play_all);
-       g_simple_action_set_enabled (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_SHUFFLE)), play_all);
-}
-
-
-static void
-activate_play_all (GSimpleAction *action,
-                  GVariant      *parameter,
-                  gpointer       user_data)
-{
-       GooApplication *application = user_data;
-
-       g_simple_action_set_state (action, parameter);
-       g_settings_set_boolean (application->settings, PREF_PLAYLIST_PLAYALL, g_variant_get_boolean 
(parameter));
-       update_app_menu_sensitivity (application);
-}
-
-
-static void
-activate_repeat (GSimpleAction *action,
-                GVariant      *parameter,
-                gpointer       user_data)
-{
-       GooApplication *application = user_data;
-
-       g_simple_action_set_state (action, parameter);
-       g_settings_set_boolean (application->settings, PREF_PLAYLIST_REPEAT, g_variant_get_boolean 
(parameter));
-       update_app_menu_sensitivity (application);
-}
-
-
-static void
-activate_shuffle (GSimpleAction *action,
-                 GVariant      *parameter,
-                 gpointer       user_data)
-{
-       GooApplication *application = user_data;
-
-       g_simple_action_set_state (action, parameter);
-       g_settings_set_boolean (application->settings, PREF_PLAYLIST_SHUFFLE, g_variant_get_boolean 
(parameter));
-       update_app_menu_sensitivity (application);
-}
-
-
-static void
-activate_preferences (GSimpleAction *action,
-                     GVariant      *parameter,
-                     gpointer       user_data)
-{
-       GApplication *application = user_data;
-       GList        *windows;
-
-       windows = gtk_application_get_windows (GTK_APPLICATION (application));
-       if (windows != NULL)
-               activate_action_preferences (NULL, windows->data);
-}
-
-
-static void
-activate_help (GSimpleAction *action,
-               GVariant      *parameter,
-               gpointer       user_data)
-{
-       GApplication *application = user_data;
-       GList        *windows;
-
-       windows = gtk_application_get_windows (GTK_APPLICATION (application));
-       if (windows != NULL)
-               activate_action_manual (NULL, windows->data);
-}
-
-
-static void
-activate_about (GSimpleAction *action,
-               GVariant      *parameter,
-               gpointer       user_data)
-{
-       GApplication *application = user_data;
-       GList        *windows;
-
-       windows = gtk_application_get_windows (GTK_APPLICATION (application));
-       if (windows != NULL)
-               activate_action_about (NULL, windows->data);
-}
-
-
-static void
-activate_quit (GSimpleAction *action,
-               GVariant      *parameter,
-               gpointer       user_data)
-{
-       GApplication *application = user_data;
-       GList        *windows;
-
-       windows = gtk_application_get_windows (GTK_APPLICATION (application));
-       if (windows != NULL)
-               activate_action_quit (NULL, windows->data);
-}
-
-
-static void
-pref_playlist_playall_changed (GSettings  *settings,
-                              const char *key,
-                              gpointer    user_data)
-{
-       GooApplication *application = user_data;
-
-       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_PLAYALL)),
-                                  g_variant_new_boolean (g_settings_get_boolean (application->settings, 
PREF_PLAYLIST_PLAYALL)));
-       update_app_menu_sensitivity (application);
-}
-
-
-static void
-pref_playlist_repeat_changed (GSettings  *settings,
-                             const char *key,
-                             gpointer    user_data)
-{
-       GooApplication *application = user_data;
-
-       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_REPEAT)),
-                                  g_variant_new_boolean (g_settings_get_boolean (application->settings, 
PREF_PLAYLIST_REPEAT)));
-       update_app_menu_sensitivity (application);
-}
-
-
-static void
-pref_playlist_shuffle_changed (GSettings  *settings,
-                              const char *key,
-                              gpointer    user_data)
-{
-       GooApplication *application = user_data;
-
-       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_SHUFFLE)),
-                                  g_variant_new_boolean (g_settings_get_boolean (application->settings, 
PREF_PLAYLIST_SHUFFLE)));
-       update_app_menu_sensitivity (application);
-}
-
-
-static const GActionEntry app_menu_entries[] = {
-       { "preferences",  activate_preferences },
-       { PREF_PLAYLIST_PLAYALL, toggle_action_activated, NULL, "true", activate_play_all },
-       { PREF_PLAYLIST_REPEAT, toggle_action_activated, NULL, "false", activate_repeat },
-       { PREF_PLAYLIST_SHUFFLE, toggle_action_activated, NULL, "true", activate_shuffle },
-       { "help",  activate_help },
-       { "about", activate_about },
-       { "quit",  activate_quit }
-};
-
-
-static void
-initialize_app_menu (GApplication *application)
-{
-       GooApplication *self = (GooApplication *) application;
-       GtkBuilder     *builder;
-
-       g_action_map_add_action_entries (G_ACTION_MAP (application),
-                                        app_menu_entries,
-                                        G_N_ELEMENTS (app_menu_entries),
-                                        application);
-
-       builder = _gtk_builder_new_from_resource ("app-menu.ui");
-       gtk_application_set_app_menu (GTK_APPLICATION (application),
-                                     G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu")));
-
-       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_PLAYALL)),
-                                  g_variant_new_boolean (g_settings_get_boolean (self->settings, 
PREF_PLAYLIST_PLAYALL)));
-       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_REPEAT)),
-                                  g_variant_new_boolean (g_settings_get_boolean (self->settings, 
PREF_PLAYLIST_REPEAT)));
-       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_SHUFFLE)),
-                                  g_variant_new_boolean (g_settings_get_boolean (self->settings, 
PREF_PLAYLIST_SHUFFLE)));
-
-       g_signal_connect (self->settings,
-                         "changed::" PREF_PLAYLIST_PLAYALL,
-                         G_CALLBACK (pref_playlist_playall_changed),
-                         self);
-       g_signal_connect (self->settings,
-                         "changed::" PREF_PLAYLIST_SHUFFLE,
-                         G_CALLBACK (pref_playlist_shuffle_changed),
-                         self);
-       g_signal_connect (self->settings,
-                         "changed::" PREF_PLAYLIST_REPEAT,
-                         G_CALLBACK (pref_playlist_repeat_changed),
-                         self);
-
-       g_object_unref (builder);
-}
-
-
-static void
-goo_application_startup (GApplication *application)
-{
-       G_APPLICATION_CLASS (goo_application_parent_class)->startup (application);
-       initialize_app_menu (application);
-}
-
-
-static void
-goo_application_class_init (GooApplicationClass *klass)
-{
-       GObjectClass      *object_class;
-       GApplicationClass *application_class;
-
-       object_class = G_OBJECT_CLASS (klass);
-       object_class->finalize = goo_application_finalize;
-
-       application_class = G_APPLICATION_CLASS (klass);
-       application_class->activate = goo_application_activate;
-       application_class->command_line = goo_application_command_line;
-       application_class->local_command_line = goo_application_local_command_line;
-       application_class->startup = goo_application_startup;
-}
-
-
-static GtkApplication *
-goo_application_new (void)
-{
-       return g_object_new (goo_application_get_type (),
-                            "application-id", "org.gnome.Goobox",
-                            "flags", 0,
-                            NULL);
-}
+int            arg_auto_play = FALSE;
+int            arg_toggle_visibility = FALSE;
 
 
 int
 main (int argc, char *argv[])
 {
-       GtkApplication *application;
-       int             status;
-
-       program_argv0 = argv[0];
+       int status;
 
        /* text domain */
 
@@ -724,16 +64,22 @@ main (int argc, char *argv[])
 
        /* run the main application */
 
-       application = Main_Application = goo_application_new ();
-       status = g_application_run (G_APPLICATION (application), argc, argv);
+       Main_Application = goo_application_new ();
+
+#ifdef ENABLE_NOTIFICATION
+       if (! notify_init (g_get_application_name ()))
+                g_warning ("Cannot initialize notification system.");
+#endif /* ENABLE_NOTIFICATION */
+
+       status = g_application_run (G_APPLICATION (Main_Application), argc, argv);
 
-       g_object_unref (application);
+       g_object_unref (Main_Application);
 
        return status;
 }
 
 
-/* -- utility functions -- */
+/* -- utilities -- */
 
 
 GtkWidget *
@@ -919,21 +265,21 @@ system_notify (GooWindow       *window,
 
                if (goo_player_get_state (goo_window_get_player (window)) == GOO_PLAYER_STATE_PLAYING)
                        notify_notification_add_action (notification,
-                                                       GOO_STOCK_PAUSE,
+                                                       GOO_ICON_NAME_PAUSE,
                                                        _("Pause"),
                                                        notify_action_toggle_play_cb,
                                                        window,
                                                        NULL);
                else
                        notify_notification_add_action (notification,
-                                                       GOO_STOCK_PLAY,
+                                                       GOO_ICON_NAME_PLAY,
                                                        _("Play"),
                                                        notify_action_toggle_play_cb,
                                                        window,
                                                        NULL);
 
                notify_notification_add_action (notification,
-                                               GOO_STOCK_NEXT,
+                                               GOO_ICON_NAME_NEXT,
                                                _("Next"),
                                                notify_action_next_cb,
                                                window,
diff --git a/src/main.h b/src/main.h
index ebb136c..d5731ae 100644
--- a/src/main.h
+++ b/src/main.h
@@ -28,8 +28,8 @@
 #include "goo-window.h"
 
 extern GtkApplication *Main_Application;
-extern int             arg_auto_play;
-extern int             arg_toggle_visibility;
+extern int            arg_auto_play;
+extern int            arg_toggle_visibility;
 
 GtkWidget *     main_get_window_from_device  (const char      *device);
 BraseroDrive *  main_get_most_likely_drive   (void);
diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am
index 9ae838b..fb15022 100644
--- a/src/ui/Makefile.am
+++ b/src/ui/Makefile.am
@@ -3,8 +3,9 @@ EXTRA_DIST =                    \
        cover-chooser.ui        \
        extract.ui              \
        format-options.ui       \
+       gears-menu.ui           \
        goobox.css              \
-       menu-toolbars.ui        \
+       menus.ui                \
        message-dialog.ui       \
        preferences.ui          \
        properties.ui           \
diff --git a/src/ui/app-menu.ui b/src/ui/app-menu.ui
index ccf64d2..0ae9aee 100644
--- a/src/ui/app-menu.ui
+++ b/src/ui/app-menu.ui
@@ -7,7 +7,6 @@
       </item>
     </section>
     <section>
-      <attribute name="label" translatable="yes">Play Mode</attribute>
       <item>
         <attribute name="action">app.play-all</attribute>
         <attribute name="label" translatable="yes">Play _All</attribute>
diff --git a/src/ui/cover-chooser.ui b/src/ui/cover-chooser.ui
index 33bd90d..1a36464 100644
--- a/src/ui/cover-chooser.ui
+++ b/src/ui/cover-chooser.ui
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.16.1 -->
 <interface>
-  <!-- interface-requires gtk+ 3.0 -->
+  <requires lib="gtk+" version="3.10"/>
   <object class="GtkDialog" id="cover_chooser_dialog">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
@@ -21,12 +22,12 @@
             <property name="layout_style">end</property>
             <child>
               <object class="GtkButton" id="revert_button">
-                <property name="label">gtk-undo</property>
+                <property name="label">_Reset</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
                 <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
+                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -111,7 +112,7 @@
                           <object class="GtkImage" id="image1">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="stock">gtk-cancel</property>
+                            <property name="icon_name">process-stop-symbolic</property>
                           </object>
                         </child>
                       </object>
diff --git a/src/ui/extract.ui b/src/ui/extract.ui
index 0bc82d1..c33113a 100644
--- a/src/ui/extract.ui
+++ b/src/ui/extract.ui
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.16.1 -->
 <interface>
-  <!-- interface-requires gtk+ 3.0 -->
+  <requires lib="gtk+" version="3.0"/>
   <object class="GtkDialog" id="extract_dialog">
     <property name="width_request">300</property>
     <property name="can_focus">False</property>
@@ -42,7 +43,12 @@
                 <property name="can_default">True</property>
                 <property name="receives_default">False</property>
                 <child>
-                  <placeholder/>
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">_Extract</property>
+                    <property name="use_underline">True</property>
+                  </object>
                 </child>
               </object>
               <packing>
diff --git a/src/ui/gears-menu.ui b/src/ui/gears-menu.ui
new file mode 100644
index 0000000..009b1e8
--- /dev/null
+++ b/src/ui/gears-menu.ui
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="gears-menu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">Copy _Disk</attribute>
+        <attribute name="action">win.copy-disk</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">_Eject</attribute>
+        <attribute name="action">win.eject</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Properties</attribute>
+        <attribute name="action">win.properties</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Close</attribute>
+        <attribute name="action">win.close</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/src/ui/menus.ui b/src/ui/menus.ui
new file mode 100644
index 0000000..b8e7275
--- /dev/null
+++ b/src/ui/menus.ui
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="track-list-popup">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Play</attribute>
+        <attribute name="action">win.play</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">E_xtract Tracks</attribute>
+        <attribute name="action">win.extract</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Properties</attribute>
+        <attribute name="action">win.properties</attribute>
+      </item>
+    </section>
+  </menu>
+  <menu id="cover-popup">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Choose File…</attribute>
+        <attribute name="action">win.pick-cover-from-disk</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">_Search on Internet</attribute>
+        <attribute name="action">win.search-cover</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Remove</attribute>
+        <attribute name="action">win.remove-cover</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/src/ui/properties.ui b/src/ui/properties.ui
index 4428b70..17e2e60 100644
--- a/src/ui/properties.ui
+++ b/src/ui/properties.ui
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.16.1 -->
 <interface>
-  <!-- interface-requires gtk+ 3.0 -->
+  <requires lib="gtk+" version="3.10"/>
   <object class="GtkAdjustment" id="adjustment1">
     <property name="upper">9999</property>
     <property name="value">2000</property>
@@ -41,12 +42,12 @@
             <property name="layout_style">end</property>
             <child>
               <object class="GtkButton" id="undo_button">
-                <property name="label">gtk-undo</property>
+                <property name="label">_Reset</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
                 <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
+                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -289,7 +290,7 @@
                               <object class="GtkImage" id="image5">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="stock">gtk-find</property>
+                                <property name="icon_name">edit-find-symbolic</property>
                               </object>
                             </child>
                           </object>
@@ -326,7 +327,7 @@
                                       <object class="GtkImage" id="info_icon">
                                         <property name="visible">True</property>
                                         <property name="can_focus">False</property>
-                                        <property name="stock">gtk-dialog-warning</property>
+                                        <property name="icon_name">dialog-warning-symbolic</property>
                                       </object>
                                       <packing>
                                         <property name="expand">False</property>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]