[SCM] gnome-mpv/master: Imported Upstream version 0.9

infinity0 at users.alioth.debian.org infinity0 at users.alioth.debian.org
Fri May 20 23:52:18 UTC 2016


The following commit has been merged in the master branch:
commit b046c79c900c2b1aa72101798a1a4b2562d9eecd
Author: Ximin Luo <infinity0 at debian.org>
Date:   Fri May 20 13:21:30 2016 +0200

    Imported Upstream version 0.9

diff --git a/README.md b/README.md
index a79759f..1ff388d 100644
--- a/README.md
+++ b/README.md
@@ -4,17 +4,20 @@ GNOME MPV is a simple GTK+ frontend for mpv. GNOME MPV interacts with mpv via
 the client API exported by libmpv, allowing access to mpv's powerful playback
 capabilities.
 
+![Screenshot](https://gnome-mpv.github.io/images/screenshot-0.png)
+
 ## Dependencies
 
 - appstream-glib<sup>[[1]](#note)</sup> (build)
-- autotools<sup>[[1]](#note)</sup> (build)
+- autoconf >= 2.69<sup>[[1]](#note)</sup> (build)
 - autoconf-archive<sup>[[1]](#note)</sup> (build)
+- automake >= 1.12<sup>[[1]](#note)</sup> (build)
 - python2<sup>[[1]](#note)</sup> (build)
-- intltool (build)
+- intltool >= 0.40.6 (build)
 - pkg-config (build)
 - gcc (build)
-- glib2 >= 2.40
-- gtk3 >= 3.20
+- glib2 >= 2.44
+- gtk3 >= 3.18
 - mpv >= 0.17
 - epoxy
 - lua (optional)
diff --git a/configure.ac b/configure.ac
index 615c035..12fb452 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,12 +1,12 @@
 AC_PREREQ([2.69])
 
 AC_INIT(	[gnome-mpv],
-		[0.8],
+		[0.9],
 		[http://github.com/gnome-mpv/gnome-mpv/issues],
 		[gnome-mpv],
 		[http://github.com/gnome-mpv/gnome-mpv] )
 
-AC_CONFIG_SRCDIR([src/main.c])
+AC_CONFIG_SRCDIR([src/gmpv_main.c])
 AC_CONFIG_MACRO_DIR([m4])
 AC_USE_SYSTEM_EXTENSIONS
 AM_INIT_AUTOMAKE([1.12 tar-pax dist-xz no-dist-gzip subdir-objects foreign -Wall -Wno-portability])
@@ -83,10 +83,20 @@ AS_IF([test "x$GLIB_GENMARSHAL" = "x"], [
 	AC_MSG_ERROR([Could not find glib-genmarshal])
 ])
 
-PKG_CHECK_MODULES(DEPS, [gtk+-3.0 >= 3.20 glib-2.0 >= 2.40 mpv >= 1.20 epoxy])
+PKG_CHECK_MODULES(DEPS, [gtk+-3.0 glib-2.0 >= 2.44 mpv >= 1.20 epoxy])
 
-AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_40], [Dont warn using older APIs])
-AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_40], [Prevents using newer APIs])
+AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_44], [Dont warn using older APIs])
+AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_44], [Prevents using newer APIs])
+
+AM_CONDITIONAL([NEW_GTK], PKG_CHECK_EXISTS([gtk+-3.0 >= 3.20], true, false))
+
+AM_COND_IF([NEW_GTK],[
+	AC_DEFINE([GDK_VERSION_MIN_REQUIRED], [GDK_VERSION_3_20], [Dont warn using older APIs])
+	AC_DEFINE([GDK_VERSION_MAX_ALLOWED], [GDK_VERSION_3_20], [Prevents using newer APIs])
+],[
+	AC_DEFINE([GDK_VERSION_MIN_REQUIRED], [GDK_VERSION_3_18], [Dont warn using older APIs])
+	AC_DEFINE([GDK_VERSION_MAX_ALLOWED], [GDK_VERSION_3_18], [Prevents using newer APIs])
+])
 
 # Checks for header files.
 AC_CHECK_HEADERS([string.h stdio.h stdlib.h locale.h ctype.h execinfo.h],[],[
diff --git a/data/Makefile.am b/data/Makefile.am
index bf543e1..03d0542 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -22,7 +22,8 @@ symicon_DATA = gnome-mpv-symbolic.svg
 
 EXTRA_DIST =	$(appstream_in_files) $(desktop_in_files) \
 		gnome-mpv.svg gnome-mpv-symbolic.svg \
-		io.github.GnomeMpv.gschema.xml.in org.gnome-mpv.gschema.xml.in \
-		mpris_gdbus.xml marshal.lst
+		org.gnome-mpv.gschema.xml \
+		io.github.GnomeMpv.gschema.xml \
+		gmpv_mpris_gdbus.xml gmpv_marshal.lst
 
-DISTCLEANFILES = $(appstream_XML) $(gsettings_SCHEMAS) $(desktop_DATA)
+DISTCLEANFILES = $(appstream_XML) $(desktop_DATA)
diff --git a/data/marshal.lst b/data/gmpv_marshal.lst
similarity index 54%
rename from data/marshal.lst
rename to data/gmpv_marshal.lst
index 1f953dd..24a84cb 100644
--- a/data/marshal.lst
+++ b/data/gmpv_marshal.lst
@@ -1 +1,2 @@
 VOID:INT,INT
+VOID:INT64
diff --git a/data/mpris_gdbus.xml b/data/gmpv_mpris_gdbus.xml
similarity index 100%
rename from data/mpris_gdbus.xml
rename to data/gmpv_mpris_gdbus.xml
diff --git a/data/io.github.GnomeMpv.desktop.in b/data/io.github.GnomeMpv.desktop.in
index 5d07b9c..071d395 100644
--- a/data/io.github.GnomeMpv.desktop.in
+++ b/data/io.github.GnomeMpv.desktop.in
@@ -7,5 +7,7 @@ Icon=gnome-mpv
 Terminal=false
 Type=Application
 StartupNotify=true
-Categories=GTK;GNOME;AudioVideo;Player;Video;
-MimeType=application/ogg;application/x-ogg;application/sdp;application/smil;application/x-smil;application/streamingmedia;application/x-streamingmedia;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/aac;audio/x-aac;audio/m4a;audio/x-m4a;audio/mp1;audio/x-mp1;audio/mp2;audio/x-mp2;audio/mp3;audio/x-mp3;audio/mpeg;audio/x-mpeg;audio/mpegurl;audio/x-mpegurl;audio/mpg;audio/x-mpg;audio/rn-mpeg;audio/scpls;audio/x-scpls;audio/vnd.rn-realaudio;audio/wav;audio/x-pn-windows-pcm;audio/x-realaudio;audio/x-pn-realaudio;audio/x-ms-wma;audio/x-pls;audio/x-wav;video/mpeg;video/x-mpeg;video/x-mpeg2;video/mp4;video/msvideo;video/x-msvideo;video/quicktime;video/vnd.rn-realvideo;video/x-ms-afs;video/x-ms-asf;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-avi;video/x-fli;video/x-flv;video/x-theora;video/x-matroska;video/webm;audio/x-flac;audio/x-vorbis+ogg;video/x-ogm+ogg;
+Categories=GTK;GNOME;AudioVideo;Player;Video;TV;
+MimeType=application/ogg;application/x-ogg;application/sdp;application/smil;application/x-smil;application/streamingmedia;application/x-streamingmedia;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/aac;audio/x-aac;audio/m4a;audio/x-m4a;audio/mp1;audio/x-mp1;audio/mp2;audio/x-mp2;audio/mp3;audio/x-mp3;audio/mpeg;audio/x-mpeg;audio/mpegurl;audio/x-mpegurl;audio/mpg;audio/x-mpg;audio/rn-mpeg;audio/ogg;audio/scpls;audio/x-scpls;audio/vnd.rn-realaudio;audio/wav;audio/x-pn-windows-pcm;audio/x-realaudio;audio/x-pn-realaudio;audio/x-ms-wma;audio/x-pls;audio/x-wav;video/mpeg;video/x-mpeg;video/x-mpeg2;video/mp4;video/msvideo;video/x-msvideo;video/ogg;video/quicktime;video/vnd.rn-realvideo;video/x-ms-afs;video/x-ms-asf;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-avi;video/x-fli;video/x-flv;video/x-theora;video/x-matroska;video/webm;audio/x-flac;audio/x-vorbis+ogg;video/x-ogm+ogg;audio/x-shorten;audio/x-ape;audio/x-wavpack;audio/x-tta;audio/AMR;audio/ac3;video/mp2t;audio/flac;audio/mp4;
+X-KDE-Protocols=ftp,http,https,mms,rtmp,rtsp,sftp,smb
+
diff --git a/data/io.github.GnomeMpv.gschema.xml.in b/data/io.github.GnomeMpv.gschema.xml
similarity index 100%
rename from data/io.github.GnomeMpv.gschema.xml.in
rename to data/io.github.GnomeMpv.gschema.xml
diff --git a/data/org.gnome-mpv.gschema.xml.in b/data/org.gnome-mpv.gschema.xml
similarity index 100%
rename from data/org.gnome-mpv.gschema.xml.in
rename to data/org.gnome-mpv.gschema.xml
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4bcf68d..d224234 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,19 +1,19 @@
-[type: gettext/gsettings]data/org.gnome-mpv.gschema.xml.in
-[type: gettext/gsettings]data/io.github.GnomeMpv.gschema.xml.in
+[type: gettext/gsettings]data/org.gnome-mpv.gschema.xml
+[type: gettext/gsettings]data/io.github.GnomeMpv.gschema.xml
 [type: gettext/xml]data/io.github.GnomeMpv.appdata.xml.in
 [type: gettext/ini]data/io.github.GnomeMpv.desktop.in
-src/actionctl.c
-src/application.c
-src/common.c
-src/control_box.c
-src/main.c
-src/main_window.c
-src/menu.c
-src/mpv_obj.c
-src/open_loc_dialog.c
-src/playlist.c
-src/playlist_widget.c
-src/plugins_manager.c
-src/plugins_manager_item.c
-src/pref_dialog.c
-src/shortcuts_window.c
+src/gmpv_actionctl.c
+src/gmpv_application.c
+src/gmpv_common.c
+src/gmpv_control_box.c
+src/gmpv_main.c
+src/gmpv_main_window.c
+src/gmpv_menu.c
+src/gmpv_mpv_obj.c
+src/gmpv_open_loc_dialog.c
+src/gmpv_playlist.c
+src/gmpv_playlist_widget.c
+src/gmpv_plugins_manager.c
+src/gmpv_plugins_manager_item.c
+src/gmpv_pref_dialog.c
+src/gmpv_shortcuts_window.c
diff --git a/po/ca.po b/po/ca.po
index f9caf24..35f8030 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -3,8 +3,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-04-11 06:53+0700\n"
-"PO-Revision-Date: 2016-04-18 01:29-0400\n"
+"POT-Creation-Date: 2016-05-11 04:21+0700\n"
+"PO-Revision-Date: 2016-04-27 01:06-0400\n"
 "Last-Translator: Adolfo Jayme <fitoschido at gmail.com>\n"
 "Language-Team: Catalan\n"
 "MIME-Version: 1.0\n"
@@ -12,82 +12,82 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: ca\n"
 "Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr "Habilita o inhabilita el tema fosc"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr "Habilita o inhabilita les decoracions del client"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr ""
 "Si el quadre de diàleg de selecció de fitxers haurà de recordar la darrera "
 "carpeta accedida"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr "Opcions que passar a l’MPV"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr "Camí al fitxer de configuració de l’MPV"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr "Carrega o no un fitxer de configuració de l’MPV"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr "Camí al fitxer de configuració d’entrada de l’MPV"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr "Carrega o no un fitxer de configuració d’entrada de l’MPV"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr "Amplada de la finestra"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr "Alçada de la finestra"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr "Volum del reproductor"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr "Amplada de la llista de reproducció"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr "Mostra o amaga la llista de reproducció"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr "URI de la darrera carpeta accedida"
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 msgid ""
 "Whether the settings has already been migrated from the previous version"
 msgstr "Si els paràmetres ja s’han migrat des d’una versió anterior"
@@ -137,7 +137,7 @@ msgstr "La finestra principal amb la CSD inhabilitada"
 msgid "The main window with playlist open"
 msgstr "La finestra principal amb la llista de reproducció oberta"
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -145,33 +145,35 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr "Frontal en GTK+ per a l’mpv"
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 msgid "Add File to Playlist"
 msgstr "Afegeix un fitxer a una llista de reproducció"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "Obre un fitxer"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "_Cancel·la"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "_Obre"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 msgid "Save Playlist"
 msgstr "Desa la llista de reproducció"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "_Desa"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
@@ -180,306 +182,311 @@ msgstr ""
 "Cal que reinicieu el %s per tal d’habilitar o inhabilitar les decoracions "
 "del client."
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr ""
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "Un frontal en GTK per a l’MPV"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
 msgstr "Adolfo Jayme Barrientos <fitojb at ubuntu.com>"
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 msgid "Playing"
 msgstr "En reproducció"
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr "Error"
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
 msgstr "Reprodueix"
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
 msgstr "Atura"
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
 msgstr "Avança"
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
 msgstr "Rebobina"
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
 msgstr "Capítol següent"
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
 msgstr "Capítol anterior"
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
 msgstr "Commuta la pantalla completa"
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
 msgstr "Posa en pausa"
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr "Cap"
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr "Desconegut"
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "_Fitxer"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "_Surt"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "Obre una _ubicació"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "_Desa la llista de reproducció"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "_Edita"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "_Preferències"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "_Visualitza"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "_Commuta la llista de reproducció"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "_Pantalla completa"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "Mida _normal"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "Mida _doble"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "_Meitat de la mida"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "_Ajuda"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "_Quant a"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr "Pista de _vídeo"
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr ""
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr "Pista d’_àudio"
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr "Pista de s_ubtítols"
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr "La reproducció ha terminat de forma anòmala. Motiu: %s"
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr "No s’han pogut aplicar alguns paràmetres de l’MPV."
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "Ubicació:"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "Obre una ubicació"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr "_Afegeix…"
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr "Repetició"
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "Llista de reproducció"
 
-#: ../src/plugins_manager.c:137
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
+msgstr ""
+
+#: ../src/gmpv_plugins_manager.c:142
 msgid "Cancel"
 msgstr "Cancel·la"
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
 msgstr "Obre"
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
 msgstr "No s’ha pogut copiar el fitxer de «%s» a «%s». Motiu: %s"
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
 msgstr "No s’ha trobat cap «script» en Lua"
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
 msgstr "Suprimeix"
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
 msgstr ""
 "Esteu segur que voleu suprimir aquest «script»? Aquesta acció no es pot "
 "desfer."
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
 msgstr "No s’ha pogut suprimir el fitxer «%s». Motiu: %s"
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
 msgstr "<b>Interfície de l’usuari</b>"
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "Habilita les decoracions del client"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "Habilita el tema fosc"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr "Recorda la ubicació del darrer fitxer"
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>Paràmetres de l’MPV</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "Carrega un fitxer de configuració de l’MPV"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "Fitxer de configuració de l’MPV:"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>Assignacions de tecles</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
-msgstr ""
+msgstr "Carrega un fitxer de configuració d’entrada de l’MPV"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
-msgstr ""
+msgstr "Fitxer de configuració d’entrada de l’MPV:"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
-msgstr ""
+msgstr "<b>Altres</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
-msgstr ""
+msgstr "Opcions addicionals de l’MPV:"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
-msgstr ""
+msgstr "Generals"
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
-msgstr ""
+msgstr "«Scripts» en Lua"
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "Preferències"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
 msgstr "Obre un fitxer"
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
 msgstr "Obre una ubicació"
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
 msgstr "Surt"
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
 msgstr "Mostra el quadre de diàleg Preferències"
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
 msgstr "Commuta la llista de reproducció"
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
 msgstr "Desa la llista de reproducció"
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
 msgstr "Treu l’element seleccionat de la llista"
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
 msgstr "Commuta el mode de pantalla completa"
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
 msgstr "Surt del mode de pantalla completa"
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
 msgstr "Mida normal"
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
 msgstr "Mida doble"
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
 msgstr "Meitat de la mida"
diff --git a/po/cs.po b/po/cs.po
index 99ef882..fb12147 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -18,80 +18,80 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: cs\n"
 "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr ""
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 msgid ""
 "Whether the settings has already been migrated from the previous version"
 msgstr ""
@@ -133,7 +133,7 @@ msgstr ""
 msgid "The main window with playlist open"
 msgstr ""
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -141,35 +141,37 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr ""
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 #, fuzzy
 msgid "Add File to Playlist"
 msgstr "_Přepnout seznam skladeb"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "Otevřít soubor"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "_Zrušit"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "_Otevřít"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 #, fuzzy
 msgid "Save Playlist"
 msgstr "_Uložit seznam skladeb"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "_Uložit"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
@@ -177,304 +179,309 @@ msgid ""
 msgstr ""
 "Povolení nebo zakázání dekorací na straně klienta vyžaduje restartování %s."
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr ""
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "GTK frontend pro MPV"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
 msgstr "Tomáš Marný"
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 msgid "Playing"
 msgstr ""
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr ""
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
 msgstr ""
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
 msgstr ""
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
 msgstr ""
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
 msgstr ""
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
 msgstr ""
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
 msgstr ""
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
 msgstr ""
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
 msgstr ""
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr ""
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr ""
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "_Soubor"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "_Ukončit"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "_Otevřít umístění"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "_Uložit seznam skladeb"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "_Upravit"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "_Předvolby"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "_Zobrazit"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "_Přepnout seznam skladeb"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "_Celá obrazovka"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "_Normální velikost"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "_Dvojnásobná velikost"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "_Poloviční velikost"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "_Nápověda"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "_O programu"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr ""
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr ""
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr ""
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr ""
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr ""
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr ""
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "Umístění:"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "Otevřít umístění"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr ""
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr ""
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "Seznam skladeb"
 
-#: ../src/plugins_manager.c:137
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
+msgstr ""
+
+#: ../src/gmpv_plugins_manager.c:142
 msgid "Cancel"
 msgstr ""
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
 msgstr ""
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
 msgstr ""
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
 msgstr ""
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "Povolit dekorace na straně klienta"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "Povolit tmavý motiv"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr ""
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>Nastavení MPV</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "Načíst konfigurační soubor MPV"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "Konfigurační soubor MPV:"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>Klávesové zkratky</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
 msgstr "Načíst vstupní konfigurační soubor MPV"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
 msgstr "Vstupní konfigurační soubor MPV:"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
 msgstr "<b>Různé</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
 msgstr "Extra možnosti MPV:"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
 msgstr ""
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
 msgstr ""
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "Předvolby"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
 msgstr ""
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
 msgstr ""
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
 msgstr ""
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
 msgstr ""
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
 msgstr ""
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
 msgstr ""
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
 msgstr ""
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
 msgstr ""
diff --git a/po/de_DE.po b/po/de_DE.po
index 042b3b5..2733f2e 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -11,7 +11,7 @@ msgstr ""
 "Project-Id-Version: gnome-mpv 0.6\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-23 10:58-0500\n"
-"PO-Revision-Date: 2016-04-16 07:35-0400\n"
+"PO-Revision-Date: 2016-05-14 09:47-0400\n"
 "Last-Translator: Vincent Bermel <willovince at openmailbox.org>\n"
 "Language-Team: German Translations\n"
 "MIME-Version: 1.0\n"
@@ -19,80 +19,80 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: de-DE\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr "Dunkles Thema verwenden"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr "Kombinierte Titel-/Menüleiste (CSD)"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr "Speicherort der zuletzt gespielten Datei merken"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr "MPV-Einstellungen"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr "MPV-Konfigurationsdatei"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr "MPV-Konfiguration aus Datei laden"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr "Datei mit MPV-Tastenbelegungen"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr "MPV-Konfiguration aus Datei laden"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr "Fensterbreite"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr "Fensterhöhe"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr "Lautstärke"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr "Breite der Wiedergabeliste"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr "Wiedergabeliste anzeigen"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr "Zuletzt geöffnetes Verzeichnis"
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 #, fuzzy
 msgid ""
 "Whether the settings has already been migrated from the previous version"
@@ -142,7 +142,7 @@ msgstr "Das Hauptfenster ohne CSD-Titelleiste"
 msgid "The main window with playlist open"
 msgstr "Das Hauptfenster mit Wiedergabeliste"
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -150,338 +150,345 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr "Eine GTK-Oberfläche für den Medienspieler mpv"
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 msgid "Add File to Playlist"
 msgstr "Datei zur _Wiedergabeliste hinzufügen"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "Datei öffnen"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "_Abbrechen"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "Ö_ffnen"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 msgid "Save Playlist"
 msgstr "Wiedergabeliste speichern"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "_Speichern"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
 " effect."
 msgstr "Die Änderungen erfordern einen Neustart von %s."
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr "Importieren"
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "Eine GTK-Oberfläche für MPV"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
 msgstr "Vincent Bermel"
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 #, fuzzy
 msgid "Playing"
 msgstr "Wiedergabe"
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr "Fehler"
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
 msgstr "Abspielen"
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
 msgstr "Stoppen"
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
 msgstr "Vorspulen"
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
 msgstr "Zurückspulen"
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
 msgstr "Weiterspringen"
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
 msgstr "Zurückspringen"
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
 msgstr "Vollbild"
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
 msgstr "Pause"
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr "Keine"
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr "Originalspur"
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "_Datei"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "_Beenden"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "_Adresse öffnen"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "Wiedergabeliste _speichern"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "_Bearbeiten"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "_Einstellungen"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "_Ansicht"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "_Wiedergabeliste ein/aus"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "_Vollbild"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "_Normale Videogröße"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "_Doppelte Videogröße"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "_Halbe Videogröße"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "_Hilfe"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "_Info"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr "_Videospur"
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr "_Importieren"
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr "_Tonspur"
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr "_Untertitel"
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr "Wiedergabe wurde abgebrochen. Grund: %s."
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr "MPV-Optionen konnten nicht angewendet werden."
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "Adresse (lokal oder Web):"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "Adresse öffnen"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr "_Hinzufügen"
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr "Wiederholen"
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "Wiedergabeliste"
 
-#: ../src/plugins_manager.c:137
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
+msgstr "Lua-Skript hinzufügen"
+
+#: ../src/gmpv_plugins_manager.c:142
 msgid "Cancel"
 msgstr "Abbrechen"
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
 msgstr "Öffnen"
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
 msgstr "Datei konnte nicht von '%s' nach '%s' kopiert werden. Grund: %s."
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
 msgstr "Es wurde kein Lua-Skript gefunden."
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
 msgstr "Entfernen"
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
 msgstr "Wollen Sie dieses Skript unwiderruflich entfernen?"
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
 msgstr "Datei '%s' konnte nicht gelöscht werden. Grund: %s."
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
 msgstr "<b>Benutzeroberfläche</b>"
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "Kombinierte Titel-/Menüleiste (CSD)"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "Dunkles Thema verwenden"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr "Speicherort der zuletzt gespielten Datei merken"
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>MPV-Einstellungen</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "MPV-Konfiguration aus Datei laden"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "MPV-Konfigurationsdatei"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>Tastenbelegungen</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
 msgstr "MPV-Tastenbelegung aus Datei laden"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
 msgstr "Datei mit MPV-Tastenbelegungen"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
 msgstr "<b>Sonstiges</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
 msgstr "Weitere Optionen für MPV"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
 msgstr "Allgemein"
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
 msgstr "Lua-Skripte"
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "Einstellungen"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
 msgstr "Öffnen"
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
 msgstr "Adresse öffnen"
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
 msgstr "Beenden"
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
 msgstr "Einstellungen anzeigen"
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
 msgstr "Wiedergabeliste ein/aus"
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
 msgstr "Wiedergabeliste speichern"
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
 msgstr "Aus Wiedergabeliste entfernen"
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
 msgstr "Vollbild"
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
 msgstr "Vollbildmodus verlassen"
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
 msgstr "Normale Videogröße"
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
 msgstr "Doppelte Videogröße"
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
 msgstr "Halbe Videogröße"
diff --git a/po/fr.po b/po/fr.po
index 72fcddf..a32047b 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -18,83 +18,83 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: fr\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 "X-Poedit-Basepath: ../src\n"
 "X-Poedit-SearchPath-0: .\n"
 "X-Poedit-SearchPathExcluded-0: mpv.c\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr ""
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 msgid ""
 "Whether the settings has already been migrated from the previous version"
 msgstr ""
@@ -136,7 +136,7 @@ msgstr ""
 msgid "The main window with playlist open"
 msgstr ""
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -144,35 +144,37 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr ""
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 #, fuzzy
 msgid "Add File to Playlist"
 msgstr "_Afficher la liste de lecture"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "Ouvrir un fichier"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "_Annuler"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "_Ouvrir"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 #, fuzzy
 msgid "Save Playlist"
 msgstr "_Enregistrer la liste de lecture"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "_Enregistrer"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
@@ -181,304 +183,309 @@ msgstr ""
 "L'activation ou la désactivation des décorations fenêtre prendra effet après"
 " un redémarrage de %s."
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr ""
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "Une interface GTK pour MPV"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
 msgstr "Harenome Ranaivorarivony Razanajato"
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 msgid "Playing"
 msgstr ""
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr ""
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
 msgstr ""
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
 msgstr ""
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
 msgstr ""
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
 msgstr ""
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
 msgstr ""
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
 msgstr ""
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
 msgstr ""
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
 msgstr ""
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr ""
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr ""
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "_Fichier"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "_Quitter"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "Ouvrir un _répertoire"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "_Enregistrer la liste de lecture"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "É_diter"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "_Préférences"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "_Vue"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "_Afficher la liste de lecture"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "_Plein écran"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "Taille _Normale"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "Taille _Double"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "Taille _Moitié"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "_Aide"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "À _propos"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr ""
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr ""
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr ""
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr ""
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr ""
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr ""
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "Emplacement:"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "Ouvrir un répertoire"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr ""
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr ""
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "Liste de lecture"
 
-#: ../src/plugins_manager.c:137
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
+msgstr ""
+
+#: ../src/gmpv_plugins_manager.c:142
 msgid "Cancel"
 msgstr ""
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
 msgstr ""
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
 msgstr ""
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
 msgstr ""
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "Activer les décorations fenêtre"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "Activer le thème sombre"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr ""
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>Configuration MPV</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "Charger un fichier de configuration MPV"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "Fichier de configuration MPV:"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>Raccourcis clavier</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
 msgstr "Charger un fichier de configuration des raccourcis clavier MPV"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
 msgstr "Fichier de configuration des raccourcis clavier MPV:"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
 msgstr "<b>Divers</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
 msgstr "Options supplémentaires pour MPV"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
 msgstr ""
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
 msgstr ""
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "Préférences"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
 msgstr ""
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
 msgstr ""
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
 msgstr ""
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
 msgstr ""
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
 msgstr ""
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
 msgstr ""
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
 msgstr ""
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
 msgstr ""
diff --git a/po/ja.po b/po/ja.po
index 213081b..3e2d154 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -18,80 +18,80 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: ja\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr ""
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 msgid ""
 "Whether the settings has already been migrated from the previous version"
 msgstr ""
@@ -133,7 +133,7 @@ msgstr ""
 msgid "The main window with playlist open"
 msgstr ""
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -141,338 +141,345 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr ""
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 msgid "Add File to Playlist"
 msgstr "プレイリストの表示・非表示"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "ファイルを開く"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "キャンセル(_C)"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "開く(_O)"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 #, fuzzy
 msgid "Save Playlist"
 msgstr "_プレイリストの保存"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "保存(_S)"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
 " effect."
 msgstr "CSDの有効・無効は %s の再起動が必要です。"
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr ""
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "MPVのGTKフロントエンド"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
 msgstr "Tista"
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 msgid "Playing"
 msgstr ""
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr ""
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
 msgstr ""
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
 msgstr ""
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
 msgstr ""
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
 msgstr ""
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
 msgstr ""
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
 msgstr ""
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
 msgstr ""
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
 msgstr ""
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr ""
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr ""
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "ファイル(_F)"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "終了(_Q)"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "開く場所(_L)"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "プレイリストの保存(_S)"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "編集(_E)"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "設定(_P)"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "表示(_V)"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "プレイリストの表示・非表示(_T)"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "全画面表示(_F)"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "通常のサイズ(_N)"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "2倍のサイズ(_D)"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "半分のサイズ(_H)"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "ヘルプ(_H)"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "このアプリケーションについて(_A)"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr ""
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr ""
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr ""
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr ""
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr ""
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr ""
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "場所:"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "場所を開く"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr ""
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr ""
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "プレイリスト"
 
-#: ../src/plugins_manager.c:137
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
+msgstr ""
+
+#: ../src/gmpv_plugins_manager.c:142
 msgid "Cancel"
 msgstr ""
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
 msgstr ""
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
 msgstr ""
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
 msgstr ""
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "CSDを有効にする"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "暗いテーマを有効にする"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr ""
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>MPVの設定</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "MPV設定ファイルをロードする"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "MPV設定ファイル:"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>キーバインド</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
 msgstr "MPV入力設定ファイルをロードする"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
 msgstr "MPV入力設定ファイル:"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
 msgstr "<b>その他</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
 msgstr "その他のMPVオプション:"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
 msgstr ""
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
 msgstr ""
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "設定"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
 msgstr ""
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
 msgstr ""
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
 msgstr ""
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
 msgstr ""
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
 msgstr ""
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
 msgstr ""
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
 msgstr ""
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
 msgstr ""
diff --git a/po/pl.po b/po/pl.po
index 55f139b..65ca42c 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -3,8 +3,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-04-11 06:53+0700\n"
-"PO-Revision-Date: 2016-03-16 02:37-0400\n"
+"POT-Creation-Date: 2016-05-11 04:21+0700\n"
+"PO-Revision-Date: 2016-04-27 10:30-0400\n"
 "Last-Translator: Piotr Sokół <psokol.l10n at gmail.com>\n"
 "Language-Team: Polish\n"
 "MIME-Version: 1.0\n"
@@ -12,82 +12,82 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: pl\n"
 "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr "Przełącza ciemny styl"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr "Przełącza wyświetlanie obramowania po stronie klienta"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr ""
 "Przełącza przechowywanie ścieżki ostatnio używanego katalogu przez okno "
 "wyboru pliku"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr "Określa opcje przekazywane do mpv"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr "Wskazuje ścieżkę pliku konfiguracyjnego mpv"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr "Przełącza wczytywanie pliku konfiguracyjnego mpv"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr "Wskazuje ścieżkę pliku konfiguracyjnego skrótów programu mpv"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr "Przełącza wczytywanie pliku konfiguracyjnego skrótów programu mpv"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr "Określa szerokość okna"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr "Określa wysokość okna"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr "Ustala głośność odtwarzania dźwięku"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr "Określa szerokość listy odtwarzania"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr "Przełącza wyświetlanie listy odtwarzania"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr "Przechowuje adres URI ostatnio używanego katalogu"
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 msgid ""
 "Whether the settings has already been migrated from the previous version"
 msgstr ""
@@ -136,7 +136,7 @@ msgstr "Głowne okno programu z wyłączonym obramowaniem po stronie klienta"
 msgid "The main window with playlist open"
 msgstr "Główne okno programu z listą odtwarzania"
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -144,33 +144,35 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr "Wykorzystuje interfejs GTK do obsługi programu MPV"
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 msgid "Add File to Playlist"
 msgstr "Dodawanie pliku do listy odtwarzania"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "Wybór pliku"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "_Anuluj"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "_Otwórz"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 msgid "Save Playlist"
 msgstr "Zapisywanie listy odtwarzania"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "_Zapisz"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
@@ -179,304 +181,309 @@ msgstr ""
 "Przełączenie wyświetlania obramowań okien po stronie klienta wymaga "
 "ponownego uruchomienia programu %s w celu wprowadzenia zmian."
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr "Wczytaj zewnętrzną..."
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "Wykorzystuje interfejs GTK do obsługi programu MPV"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
 msgstr "Piotr Sokół <psokol.l10n at gmail.com>, 2016"
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 msgid "Playing"
 msgstr "Odtwarzanie"
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr "Błąd"
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
-msgstr "Odtwarzaj"
+msgstr "Rozpoczyna odtwarznie"
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
-msgstr "Zatrzymaj"
+msgstr "Zatrzymuje odtwarzanie"
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
-msgstr "Naprzód"
+msgstr "Przechodzi naprzód"
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
-msgstr "Wstecz"
+msgstr "Przechodzi wstecz"
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
 msgstr "Następny rozdział"
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
 msgstr "Poprzedni rozdział"
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
 msgstr "Przełącza wyświetlanie na pełnym ekranie"
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
-msgstr "Wstrzymaj"
+msgstr "Wstrzymuje odtwarzanie"
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr "Brak"
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr "Nieznana"
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "_Plik"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "Za_kończ"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "Otwórz położe_nie"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "Z_apisz listę odtwarzania"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "_Edycja"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "P_referencje"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "_Widok"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "_Lista odtwarzania"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "_Pełny ekran"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "_Zwykły rozmiar"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "Dwukrotnie _większy rozmiar"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "Dwukrotnie _mniejszy rozmiar"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "Pomo_c"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "_O programie"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr "Ścieżka _wideo"
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr "_Wczytaj zewnętrzną..."
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr "Ścieżka _dźwiękowa"
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr "Ścieżka _napisów"
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr "Zakończono odtwarzanie w nieprawidłowy sposób. Powód: %s"
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr "Nie udało się wprowadzić jednej lub więcej opcji MPV."
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "Położenie:"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "Otwieranie położenia"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr "_Dodaj..."
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr "Powtarzanie"
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "Lista odtwarzania"
 
-#: ../src/plugins_manager.c:137
-msgid "Cancel"
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
 msgstr ""
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:142
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
-msgstr ""
+msgstr "Otwórz"
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
-msgstr ""
+msgstr "Nie udało się skopiować pliku z położenia „%s” do „%s”. Powód: %s"
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
-msgstr ""
+msgstr "Nie odnaleziono skryptów Lua"
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
-msgstr ""
+msgstr "Usuń"
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
-msgstr ""
+msgstr "Usunąć ten skrypt? Tej czynności nie można cofnąć."
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
-msgstr ""
+msgstr "Nie można usunąć pliku „%s”. Powód: %s"
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
-msgstr ""
+msgstr "<b>Interfejs użytkownika</b>"
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "Obramowania okien po stronie klienta"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "Ciemny styl"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr "Przechowywanie położenia ostatnich plików"
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>Konfiguracja MPV</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "Wczytywanie pliku konfiguracji MPV"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "Plik konfiguracji MPV:"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>Skróty klawiszowe</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
 msgstr "Wczytywanie pliku konfiguracji skrótów MPV"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
 msgstr "Plik konfiguracji skrótów MPV:"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
 msgstr "<b>Różne</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
 msgstr "Dodatkowe opcje MPV:"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
-msgstr ""
+msgstr "Ogólne"
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
-msgstr ""
+msgstr "Skrypty Lua"
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "Preferencje"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
 msgstr ""
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
 msgstr ""
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
-msgstr ""
+msgstr "Zakończ"
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
-msgstr ""
+msgstr "Wyświetla okno preferencji"
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
 msgstr ""
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
-msgstr ""
+msgstr "Zwykły rozmiar"
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
-msgstr ""
+msgstr "Dwukrotnie większy rozmiar"
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
-msgstr ""
+msgstr "Dwukrotnie mniejszy rozmiar"
diff --git a/po/pt_PT.po b/po/pt_PT.po
index 6e0dc15..daabd5d 100644
--- a/po/pt_PT.po
+++ b/po/pt_PT.po
@@ -5,89 +5,89 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-04-11 06:53+0700\n"
-"PO-Revision-Date: 2016-03-04 02:19-0500\n"
-"Last-Translator: gnome-mpv <gnome-mpv at openmailbox.org>\n"
+"POT-Creation-Date: 2016-05-11 04:21+0700\n"
+"PO-Revision-Date: 2016-05-08 11:01-0400\n"
+"Last-Translator: Bruno Guerreiro <american.jesus.pt at gmail.com>\n"
 "Language-Team: Portuguese\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Language: pt-PT\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr "Ativar ou desativar tema escuro"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr "Ativar ou desativar decorações do lado do cliente"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr "Se deve ou não fazer diálogo de seleção lembrar ultima pasta acedida"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr "Opções de mpv adicionais"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr "Localização do ficheiro de configuração mpv"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr "Carregar ou não o ficheiro de configuração mpv"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr "Localização do ficheiro input mpv"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr "Carregar ou não ficheiro input mpv"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr "Largura da janela"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr "Altura da janela"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr "Volume da aplicação"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr "Largura da lista de reprodução"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr "Mostrar ou não lista de reprodução"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr "URI da última pasta acedida"
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 msgid ""
 "Whether the settings has already been migrated from the previous version"
 msgstr "Se as configurações já foi migrado da versão anterior"
@@ -135,7 +135,7 @@ msgstr "Janela principal com CSD desativada"
 msgid "The main window with playlist open"
 msgstr "Janela principal com lista de reprodução aberta"
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -143,33 +143,35 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr "Interface GTK+ para mpv"
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 msgid "Add File to Playlist"
 msgstr "Adicionar ficheiro a lista de reprodução"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "Abrir Ficheiro"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "_Cancelar"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "_Abrir"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 msgid "Save Playlist"
 msgstr "Guardar Lista de Reprodução"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "_Gravar"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
@@ -178,304 +180,310 @@ msgstr ""
 "A ativação ou desativação decorações do lado do cliente requer reiniciar %s "
 "para ter efeito."
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr "A carregar Externo…"
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "Uma interface GTK para MPV"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
 msgstr "Bruno Guerreiro"
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 msgid "Playing"
 msgstr "A reproduzir"
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr "Erro"
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
-msgstr ""
+msgstr "Reproduzir"
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
-msgstr ""
+msgstr "Parar"
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
-msgstr ""
+msgstr "Avançar"
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
-msgstr ""
+msgstr "Recuar"
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
-msgstr ""
+msgstr "Próximo capítulo"
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
-msgstr ""
+msgstr "Capítulo anterior"
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
-msgstr ""
+msgstr "Alternar ecrã completo"
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
-msgstr ""
+msgstr "Pausa"
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr "Nenhum"
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr "Desconhecido"
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "_Ficheiro"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "_Sair"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "Abrir _Localização"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "_Guardar Lista de Reprodução"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "_Editar"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "_Preferências"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "_Ver"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "_Alternar Lista de Reprodução"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "_Ecrã completo"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "_Tamanho Normal"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "_Duplo Tamanho"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "_Metade do tamanho"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "_Ajuda"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "_Sobre"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr "_Faixa de vídeo"
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr "_Abrir Externo…"
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr "_Faixa de áudio"
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr "Faixa de legendas"
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr "A reprodução foi terminada de forma anormal. Motivo: %s."
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr "Falha ao aplicar uma ou mais opções de MPV."
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "Localização:"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "Abrir Localização"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr "_Adicionar…"
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr "Ciclo"
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "Lista de reprodução"
 
-#: ../src/plugins_manager.c:137
-msgid "Cancel"
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
 msgstr ""
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:142
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
-msgstr ""
+msgstr "Abrir"
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
-msgstr ""
+msgstr "Falha ao copiar ficheiro de '%s' para '%s'. Motivo: %s"
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
-msgstr ""
+msgstr "Nenhum script lua encontrado"
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
-msgstr ""
+msgstr "Remover"
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
 msgstr ""
+"Tem certeza que deseja remover este script? Essa ação não pode ser desfeita."
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
-msgstr ""
+msgstr "Falha ao excluir ficheiro '%s'. Motivo: %s"
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
-msgstr ""
+msgstr "<b>Interface de Utilizador<b>"
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "Ativar decorações do lado do cliente"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "Ativar tema escuro"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr "Lembrar localizações dos últimos ficheiros"
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>Configuração do MPV</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "Carregar ficheiro de configuração do MPV"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "Ficheiro de configuração do MPV:"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>Teclas de atalho</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
 msgstr "Carregar ficheiro input do MPV"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
 msgstr "Ficheiro input do MPV:"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
 msgstr "<b>Outras</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
 msgstr "Opções extra do MPV:"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
-msgstr ""
+msgstr "Geral"
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
-msgstr ""
+msgstr "Scripts Lua"
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "Preferências"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
-msgstr ""
+msgstr "Abrir ficheiro"
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
-msgstr ""
+msgstr "Abrir localização"
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
-msgstr ""
+msgstr "Sair"
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
-msgstr ""
+msgstr "Mostrar dialogo de preferências"
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
-msgstr ""
+msgstr "Alternar lista de reprodução"
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
-msgstr ""
+msgstr "Guardar lista de reprodução"
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
-msgstr ""
+msgstr "Remover item de lista de reprodução selecionada"
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
-msgstr ""
+msgstr "Alternar modo ecrã completo"
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
-msgstr ""
+msgstr "Deixa modo ecrã completo"
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
-msgstr ""
+msgstr "Tamanho normal"
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
-msgstr ""
+msgstr "Duplo tamanho"
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
-msgstr ""
+msgstr "Metade do tamanho"
diff --git a/po/ro.po b/po/ro.po
index f6c32d4..38ba1e1 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-04-11 06:53+0700\n"
+"POT-Creation-Date: 2016-05-11 04:21+0700\n"
 "PO-Revision-Date: 2016-03-04 02:20-0500\n"
 "Last-Translator: gnome-mpv <gnome-mpv at openmailbox.org>\n"
 "Language-Team: Romanian Translations\n"
@@ -18,80 +18,80 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: ro\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr ""
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr ""
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 msgid ""
 "Whether the settings has already been migrated from the previous version"
 msgstr ""
@@ -133,7 +133,7 @@ msgstr ""
 msgid "The main window with playlist open"
 msgstr ""
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -141,33 +141,35 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr ""
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 msgid "Add File to Playlist"
 msgstr "Adaugă un fișier Listei de Redare"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "Deschide Fișier"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "_Anulează"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "_Deschide"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 msgid "Save Playlist"
 msgstr "Salvează Lista de Redare"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "_Salvează"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
@@ -176,304 +178,309 @@ msgstr ""
 "Activarea sau dezactivarea decorațiilor ferestrelor (CSD) necesită "
 "repornirea %s."
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr ""
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "O interfață GTK pentru MPV"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
 msgstr "Robert Datcu"
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 msgid "Playing"
 msgstr ""
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr ""
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
 msgstr ""
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
 msgstr ""
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
 msgstr ""
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
 msgstr ""
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
 msgstr ""
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
 msgstr ""
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
 msgstr ""
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
 msgstr ""
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr ""
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr ""
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "_Fișier"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "Î_nchide"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "_Deschide Adresa"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "_Salvează Lista Redare"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "_Modifică"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "_Preferințe"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "_Vizualizare"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "_Afișează Lista Redare"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "_Tot ecranul"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "_Dimensiune Normală"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "_Dimensiune Dublă"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "_Dimensiune Înjumătățită"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "_Ajutor"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "_Despre"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr ""
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr ""
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr ""
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr ""
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr ""
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr ""
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "Adresă:"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "Deschide Adresa"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr ""
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr "Buclă"
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "Listă de redare"
 
-#: ../src/plugins_manager.c:137
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
+msgstr ""
+
+#: ../src/gmpv_plugins_manager.c:142
 msgid "Cancel"
 msgstr ""
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
 msgstr ""
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
 msgstr ""
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
 msgstr ""
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "Activează decorațiile ferestrelor (CSD)"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "Activează tema întunecată"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr "Ține minte adresa ultimului fișier"
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>Configurare MPV</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "Încarcă fișierul de configurare MPV"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "fișier configurare MPV:"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>Combinații Taste</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
 msgstr "Încarcă fișierul MPV de combinații taste"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
 msgstr "fișier MPV configurare combinații taste:"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
 msgstr "<b>Diverse</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
 msgstr "Extraopțiuni MPV:"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
 msgstr ""
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
 msgstr ""
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "Preferințe"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
 msgstr ""
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
 msgstr ""
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
 msgstr ""
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
 msgstr ""
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
 msgstr ""
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
 msgstr ""
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
 msgstr ""
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
 msgstr ""
diff --git a/po/ru.po b/po/ru.po
index 1e34e05..783682f 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -4,7 +4,7 @@ msgstr ""
 "Project-Id-Version: 0.6\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2016-01-04 00:00+0700\n"
-"PO-Revision-Date: 2016-04-11 07:22-0400\n"
+"PO-Revision-Date: 2016-05-13 07:15-0400\n"
 "Last-Translator: Maxim Orlov <murmansksity at gmail.com>\n"
 "Language-Team: Russian\n"
 "MIME-Version: 1.0\n"
@@ -12,80 +12,80 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: ru\n"
 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr "Включить или отключить тёмную тему"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr "Включить или отключить декорирование на стороне клиента"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr "Запомнить или нет последнее расположение в диалоге открытия файла"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr "Перейти к опциям MPV"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr "Путь к файлу конфигурации MPV"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr "Загрузить файл конфигурации MPV"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr "Путь к файлу конфигурации ввода MPV"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr "Загрузить файл конфигурации ввода MPV"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr "Ширина окна"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr "Высота окна"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr "Громкость плеера"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr "Ширина списка воспроизведения"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr "Показать или скрыть список воспроизведения"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr "Адрес последнего открытого файла"
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 msgid ""
 "Whether the settings has already been migrated from the previous version"
 msgstr "Перенос (миграция) пользовательских настроек из предыдущей версии"
@@ -110,7 +110,7 @@ msgstr "Возможности:"
 
 #: ../data/io.github.GnomeMpv.appdata.xml.in.h:3
 msgid "Drag and drop playlist"
-msgstr "Drag'n'Drop списка воспроизведения"
+msgstr "Поддержка Drag'n'Drop"
 
 #: ../data/io.github.GnomeMpv.appdata.xml.in.h:4
 msgid "Loading external mpv configuration files"
@@ -132,7 +132,7 @@ msgstr "Главное окно с отключённым CSD"
 msgid "The main window with playlist open"
 msgstr "Главное окно с открытым списком воспроизведения"
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -140,33 +140,35 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr "GTK+ интерфейс для MPV"
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 msgid "Add File to Playlist"
 msgstr "Добавить файл в список воспроизведения"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "Открыть файл"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "_Отмена"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "_Открыть"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 msgid "Save Playlist"
 msgstr "Сохранить список воспроизведения"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "_Сохранить"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
@@ -174,306 +176,311 @@ msgid ""
 msgstr ""
 "Чтобы изменения вступили в силу, необходимо перезапустить приложение %s."
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr "Загрузить внешние…"
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "GTK интерфейс для MPV"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
-msgstr "Максим Орлов <murmansksity at gmail.com>, 2016."
+msgstr "Maxim Orlov <murmansksity at gmail.com>, 2016."
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 msgid "Playing"
 msgstr "Воспроизводится"
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr "Ошибка"
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
 msgstr "Воспроизвести"
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
 msgstr "Остановить"
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
 msgstr "Перемотать вперёд"
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
 msgstr "Перемотать назад"
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
 msgstr "Следующая глава"
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
 msgstr "Предыдущая глава"
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
 msgstr "Переход в полноэкранный режим и обратно"
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
 msgstr "Приостановить"
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr "Ничего"
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr "Неизвестный"
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "_Файл"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "_Выйти"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "Открыть _адрес"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "_Сохранить список воспроизведения"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "_Правка"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "_Настройки"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "_Вид"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "_Показать/Скрыть список воспроизведения"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "_Полноэкранный режим"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "_Нормальный размер"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "_Двойной размер"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "_Половинный размер"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "_Справка"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "_О программе"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr "_Видео дорожка"
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr "_Загрузить внешние…"
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr "_Аудио дорожка"
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr "Дорожка с_убтитров"
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr "Воспроизведение было прекращено. Причина: %s."
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr "Не удалось применить одну или несколько опций MPV."
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "Адрес:"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "Открыть адрес"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr "_Добавить…"
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr "Повторить"
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "Список воспроизведения"
 
-#: ../src/plugins_manager.c:137
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
+msgstr "Добавить Lua скрипт"
+
+#: ../src/gmpv_plugins_manager.c:142
 msgid "Cancel"
 msgstr "Отмена"
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
 msgstr "Открыть"
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
 msgstr "Не удалось скопировать файл из '%s' в '%s'. Причина: %s"
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
-msgstr "Lua скрипт не найден"
+msgstr "Пусто"
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
 msgstr "Удалить"
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
 msgstr ""
 "Вы уверены, что хотите удалить этот скрипт? Это действие не может быть "
 "отменено."
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
 msgstr "Не удалось удалить файл '%s'. Причина: %s"
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
 msgstr "<b>Пользовательский интерфейс</b>"
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "Включить декорирование на стороне клиента"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "Использовать тёмный вариант темы"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr "Запомнить последнее расположение файла(ов)"
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>Конфигурация MPV</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "Загрузить файл конфигурации MPV"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "Файл конфигурации MPV:"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>Комбинации клавиш</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
 msgstr "Загрузить файл конфигурации ввода MPV"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
 msgstr "Файл конфигурации ввода MPV:"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
 msgstr "<b>Разное</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
 msgstr "Дополнительные опции MPV:"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
 msgstr "Общие"
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
 msgstr "Lua скрипты"
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "Настройки"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
 msgstr "Открыть файл"
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
 msgstr "Открыть адрес"
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
 msgstr "Выйти"
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
 msgstr "Показать диалог настройки"
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
 msgstr "Показать/Скрыть список воспроизведения"
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
 msgstr "Сохранить список воспроизведения"
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
 msgstr "Удалить выбранный файл из списка воспроизведения"
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
 msgstr "Перейти в полноэкранный режим"
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
 msgstr "Покинуть полноэкранный режим"
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
 msgstr "Нормальный размер"
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
 msgstr "Двойной размер"
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
 msgstr "Половинный размер"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 344ab24..547ad72 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -19,80 +19,80 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: zh-CN\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr "启用或禁用暗色主题"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr "启用或禁用客户端装饰"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr "是否让文件选择对话框记住最近访问的文件夹"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr "要传递给 mpv 的选项"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr "mpv 配置文件的路径"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr "是否载入 mpv 配置文件"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr "mpv 输入配置文件的路径"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr "是否载入 mpv 输入配置文件"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr "窗口宽度"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr "窗口高度"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr "播放器音量"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr "播放列表宽度"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr "是否显示播放列表"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr "最近访问的文件夹 URI"
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 msgid ""
 "Whether the settings has already been migrated from the previous version"
 msgstr "是否已从上一个版本迁移设置"
@@ -137,7 +137,7 @@ msgstr "关闭了 CSD 的主窗口"
 msgid "The main window with playlist open"
 msgstr "打开了播放列表的主窗口"
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -145,340 +145,347 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr "MPV 的 GTK 前端程序"
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 msgid "Add File to Playlist"
 msgstr "添加文件到播放列表"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "打开文件"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "取消(_C)"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "打开(_O)"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 msgid "Save Playlist"
 msgstr "保存播放列表"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "保存(_S)"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
 " effect."
 msgstr "启用或禁用客户端装饰需要重启 %s 生效。"
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr "载入外部配置文件…"
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "MPV 的 GTK 前端程序"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
 msgstr ""
 "Mingye Wang <arthur2e5 at aosc.xyz>, 2015, 2016.\n"
 "Jeff Bai <jeffbai at aosc.xyz>, 2015, 2016.\n"
 "Sun <warmsun0220 at gmail.com>, 2015, 2016."
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 msgid "Playing"
 msgstr "正在播放"
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr "错误"
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
 msgstr "播放"
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
 msgstr "停止"
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
 msgstr "快进"
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
 msgstr "快退"
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
 msgstr "下一章节"
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
 msgstr "上一章节"
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
 msgstr "切换全屏"
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
 msgstr "暂停"
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr "无"
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr "未知"
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "文件(_F)"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "退出(_Q)"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "打开位置(_L)"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "保存播放列表(_S)"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "编辑(_E)"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "首选项(_P)"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "视图(_V)"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "切换播放列表(_T)"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "全屏(_F)"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "正常尺寸(_N)"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "两倍尺寸(_D)"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "一半尺寸(_H)"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "帮助(_F)"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "关于(_A)"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr "视频轨道(_V)"
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr "载入外部(_L)…"
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr "音轨(_A)"
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr "字幕轨道(_U)"
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr "回放被异常终止。原因:%s。"
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr "应用一个或多个 MPV 选项失败。"
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "位置:"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "打开位置"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr "添加(_A)…"
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr "循环"
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "播放列表"
 
-#: ../src/plugins_manager.c:137
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
+msgstr ""
+
+#: ../src/gmpv_plugins_manager.c:142
 msgid "Cancel"
 msgstr ""
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
 msgstr ""
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
 msgstr ""
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
 msgstr ""
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "启用客户端装饰"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "启用暗色主题"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr "记住最后一次打开位置"
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>MPV 配置</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "加载 MPV 配置文件"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "MPV 配置文件:"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>键绑定</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
 msgstr "加载 MPV 输入配置文件"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
 msgstr "MPV 输入配置文件:"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
 msgstr "<b>杂项</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
 msgstr "额外的 MPV 选项:"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
 msgstr ""
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
 msgstr ""
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "首选项"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
 msgstr "打开文件"
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
 msgstr "打开位置"
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
 msgstr "退出"
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
 msgstr "显示首选项对话框"
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
 msgstr "切换播放列表"
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
 msgstr "保存播放列表"
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
 msgstr "移除选定的播放列表项"
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
 msgstr "切换全屏模式"
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
 msgstr "离开全屏模式"
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
 msgstr "正常大小"
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
 msgstr "双倍大小"
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
 msgstr "一般大小"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index f370f47..b1e98ce 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -20,80 +20,80 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: zh-TW\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Zanata 3.8.3\n"
+"X-Generator: Zanata 3.8.4\n"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:1
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:2
+#: ../data/org.gnome-mpv.gschema.xml.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:2
 msgid "Enable or disable dark theme"
 msgstr "啟用或禁用暗色主題"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:2
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:3
+#: ../data/org.gnome-mpv.gschema.xml.h:2
+#: ../data/io.github.GnomeMpv.gschema.xml.h:3
 msgid "Enable or disable client-side decorations"
 msgstr "啟用或禁用客戶端裝飾"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:3
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:4
+#: ../data/org.gnome-mpv.gschema.xml.h:3
+#: ../data/io.github.GnomeMpv.gschema.xml.h:4
 msgid ""
 "Whether or not to make file chooser dialog remember last folder accessed"
 msgstr "是否讓檔案選擇對話窗記住最近訪問的資料夾"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:4
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:5
+#: ../data/org.gnome-mpv.gschema.xml.h:4
+#: ../data/io.github.GnomeMpv.gschema.xml.h:5
 msgid "Options to pass to mpv"
 msgstr "要傳遞給 mpv 的選項"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:5
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:6
+#: ../data/org.gnome-mpv.gschema.xml.h:5
+#: ../data/io.github.GnomeMpv.gschema.xml.h:6
 msgid "Path to mpv configuration file"
 msgstr "mpv 配置檔的路徑"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:6
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:7
+#: ../data/org.gnome-mpv.gschema.xml.h:6
+#: ../data/io.github.GnomeMpv.gschema.xml.h:7
 msgid "Load or don't load mpv configuration file"
 msgstr "是否載入 mpv 配置檔"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:7
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:8
+#: ../data/org.gnome-mpv.gschema.xml.h:7
+#: ../data/io.github.GnomeMpv.gschema.xml.h:8
 msgid "Path to mpv input configuration file"
 msgstr "mpv 輸入配置檔的路徑"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:8
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:9
+#: ../data/org.gnome-mpv.gschema.xml.h:8
+#: ../data/io.github.GnomeMpv.gschema.xml.h:9
 msgid "Load or don't load mpv input configuration file"
 msgstr "是否載入 mpv 輸入配置檔"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:9
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:10
+#: ../data/org.gnome-mpv.gschema.xml.h:9
+#: ../data/io.github.GnomeMpv.gschema.xml.h:10
 msgid "Width of the window"
 msgstr "視窗寬度"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:10
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:11
+#: ../data/org.gnome-mpv.gschema.xml.h:10
+#: ../data/io.github.GnomeMpv.gschema.xml.h:11
 msgid "Height of the window"
 msgstr "視窗高度"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:11
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:12
+#: ../data/org.gnome-mpv.gschema.xml.h:11
+#: ../data/io.github.GnomeMpv.gschema.xml.h:12
 msgid "Volume of player"
 msgstr "播放器音量"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:12
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:13
+#: ../data/org.gnome-mpv.gschema.xml.h:12
+#: ../data/io.github.GnomeMpv.gschema.xml.h:13
 msgid "Width of the playlist"
 msgstr "播放列表寬度"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:13
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:14
+#: ../data/org.gnome-mpv.gschema.xml.h:13
+#: ../data/io.github.GnomeMpv.gschema.xml.h:14
 msgid "Show or not show the playlist"
 msgstr "是否顯示播放列表"
 
-#: ../data/org.gnome-mpv.gschema.xml.in.h:14
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:15
+#: ../data/org.gnome-mpv.gschema.xml.h:14
+#: ../data/io.github.GnomeMpv.gschema.xml.h:15
 msgid "URI of the last folder accessed"
 msgstr "最近訪問的資料夾 URI"
 
-#: ../data/io.github.GnomeMpv.gschema.xml.in.h:1
+#: ../data/io.github.GnomeMpv.gschema.xml.h:1
 msgid ""
 "Whether the settings has already been migrated from the previous version"
 msgstr ""
@@ -138,7 +138,7 @@ msgstr "關閉了 CSD 的主視窗"
 msgid "The main window with playlist open"
 msgstr "打開了播放列表的主視窗"
 
-#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/application.c:152
+#: ../data/io.github.GnomeMpv.desktop.in.h:1 ../src/gmpv_application.c:196
 msgid "GNOME MPV"
 msgstr "GNOME MPV"
 
@@ -146,339 +146,346 @@ msgstr "GNOME MPV"
 msgid "GTK+ frontend for mpv"
 msgstr "MPV 之 GTK 前端程式"
 
-#: ../src/actionctl.c:85
+#: ../src/gmpv_actionctl.c:90
 msgid "Add File to Playlist"
 msgstr "新增檔案到播放列表"
 
-#: ../src/actionctl.c:86
+#: ../src/gmpv_actionctl.c:90
 msgid "Open File"
 msgstr "開啟檔案"
 
-#: ../src/actionctl.c:89 ../src/actionctl.c:245 ../src/actionctl.c:442
-#: ../src/open_loc_dialog.c:83 ../src/pref_dialog.c:347
+#: ../src/gmpv_actionctl.c:93 ../src/gmpv_actionctl.c:255
+#: ../src/gmpv_actionctl.c:463 ../src/gmpv_open_loc_dialog.c:84
+#: ../src/gmpv_pref_dialog.c:348
 msgid "_Cancel"
 msgstr "取消(_C)"
 
-#: ../src/actionctl.c:91 ../src/actionctl.c:444 ../src/menu.c:121
-#: ../src/menu.c:390 ../src/open_loc_dialog.c:81
+#: ../src/gmpv_actionctl.c:94 ../src/gmpv_actionctl.c:464
+#: ../src/gmpv_menu.c:121 ../src/gmpv_menu.c:390
+#: ../src/gmpv_open_loc_dialog.c:82
 msgid "_Open"
 msgstr "開啟(_O)"
 
-#: ../src/actionctl.c:242
+#: ../src/gmpv_actionctl.c:252
 msgid "Save Playlist"
 msgstr "儲存播放列表"
 
-#: ../src/actionctl.c:247 ../src/pref_dialog.c:349
+#: ../src/gmpv_actionctl.c:256 ../src/gmpv_pref_dialog.c:350
 msgid "_Save"
 msgstr "儲存(_S)"
 
-#: ../src/actionctl.c:358
+#: ../src/gmpv_actionctl.c:374
 #, c-format
 msgid ""
 "Enabling or disabling client-side decorations requires restarting %s to take"
 " effect."
 msgstr "啟用或禁用客戶端裝飾需要重啟 %s 生效。"
 
-#: ../src/actionctl.c:439
+#: ../src/gmpv_actionctl.c:460
 msgid "Load External…"
 msgstr "載入外部配置檔…"
 
-#: ../src/actionctl.c:520
+#: ../src/gmpv_actionctl.c:541
 msgid "A GTK frontend for MPV"
 msgstr "MPV 的 GTK 前端程式"
 
-#: ../src/actionctl.c:530
+#: ../src/gmpv_actionctl.c:551
 msgid "translator-credits"
 msgstr ""
 "Mingye Wang\n"
 "Sun"
 
-#: ../src/application.c:563
+#: ../src/gmpv_application.c:987
 msgid "Playing"
 msgstr "正在播放"
 
-#: ../src/common.c:224
+#: ../src/gmpv_common.c:249
 msgid "Error"
 msgstr "錯誤"
 
-#: ../src/control_box.c:235 ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:235 ../src/gmpv_control_box.c:417
 msgid "Play"
 msgstr ""
 
-#: ../src/control_box.c:236
+#: ../src/gmpv_control_box.c:236
 msgid "Stop"
 msgstr ""
 
-#: ../src/control_box.c:237
+#: ../src/gmpv_control_box.c:237
 msgid "Forward"
 msgstr ""
 
-#: ../src/control_box.c:238
+#: ../src/gmpv_control_box.c:238
 msgid "Rewind"
 msgstr ""
 
-#: ../src/control_box.c:239
+#: ../src/gmpv_control_box.c:239
 msgid "Next Chapter"
 msgstr ""
 
-#: ../src/control_box.c:240
+#: ../src/gmpv_control_box.c:240
 msgid "Previous Chapter"
 msgstr ""
 
-#: ../src/control_box.c:241 ../src/main_window.c:695
+#: ../src/gmpv_control_box.c:241 ../src/gmpv_main_window.c:559
 msgid "Toggle Fullscreen"
 msgstr ""
 
-#: ../src/control_box.c:417
+#: ../src/gmpv_control_box.c:417
 msgid "Pause"
 msgstr ""
 
-#: ../src/menu.c:39
+#: ../src/gmpv_menu.c:39
 msgid "None"
 msgstr "無"
 
 #. For simplicity, also dup the default string used when the
 #. * track has no title.
-#: ../src/menu.c:54
+#: ../src/gmpv_menu.c:54
 msgid "Unknown"
 msgstr "未知"
 
-#: ../src/menu.c:119
+#: ../src/gmpv_menu.c:119
 msgid "_File"
 msgstr "檔案(_F)"
 
-#: ../src/menu.c:122 ../src/menu.c:414
+#: ../src/gmpv_menu.c:122 ../src/gmpv_menu.c:414
 msgid "_Quit"
 msgstr "退出(_Q)"
 
-#: ../src/menu.c:125 ../src/menu.c:393
+#: ../src/gmpv_menu.c:125 ../src/gmpv_menu.c:393
 msgid "Open _Location"
 msgstr "開啟位置(_L)"
 
-#: ../src/menu.c:128 ../src/menu.c:296
+#: ../src/gmpv_menu.c:128 ../src/gmpv_menu.c:296
 msgid "_Save Playlist"
 msgstr "儲存播放列表(_S)"
 
-#: ../src/menu.c:135
+#: ../src/gmpv_menu.c:135
 msgid "_Edit"
 msgstr "編輯(_E)"
 
-#: ../src/menu.c:138 ../src/menu.c:412
+#: ../src/gmpv_menu.c:138 ../src/gmpv_menu.c:412
 msgid "_Preferences"
 msgstr "偏好設定(_P)"
 
-#: ../src/menu.c:145
+#: ../src/gmpv_menu.c:145
 msgid "_View"
 msgstr "檢視(_V)"
 
-#: ../src/menu.c:148 ../src/menu.c:292
+#: ../src/gmpv_menu.c:148 ../src/gmpv_menu.c:292
 msgid "_Toggle Playlist"
 msgstr "切換播放列表(_T)"
 
-#: ../src/menu.c:151
+#: ../src/gmpv_menu.c:151
 msgid "_Fullscreen"
 msgstr "全屏(_F)"
 
-#: ../src/menu.c:154 ../src/menu.c:300
+#: ../src/gmpv_menu.c:154 ../src/gmpv_menu.c:300
 msgid "_Normal Size"
 msgstr "正常尺寸(_N)"
 
-#: ../src/menu.c:157 ../src/menu.c:304
+#: ../src/gmpv_menu.c:157 ../src/gmpv_menu.c:304
 msgid "_Double Size"
 msgstr "兩倍尺寸(_D)"
 
-#: ../src/menu.c:160 ../src/menu.c:308
+#: ../src/gmpv_menu.c:160 ../src/gmpv_menu.c:308
 msgid "_Half Size"
 msgstr "一半尺寸(_H)"
 
-#: ../src/menu.c:167
+#: ../src/gmpv_menu.c:167
 msgid "_Help"
 msgstr "幫助(_F)"
 
-#: ../src/menu.c:169 ../src/menu.c:413
+#: ../src/gmpv_menu.c:169 ../src/gmpv_menu.c:413
 msgid "_About"
 msgstr "關於(_A)"
 
-#: ../src/menu.c:179 ../src/menu.c:316
+#: ../src/gmpv_menu.c:179 ../src/gmpv_menu.c:316
 msgid "_Video Track"
 msgstr "視訊軌道(_V)"
 
-#: ../src/menu.c:196 ../src/menu.c:200 ../src/menu.c:346 ../src/menu.c:351
+#: ../src/gmpv_menu.c:196 ../src/gmpv_menu.c:200 ../src/gmpv_menu.c:346
+#: ../src/gmpv_menu.c:351
 msgid "_Load External…"
 msgstr ""
 
-#: ../src/menu.c:210 ../src/menu.c:335
+#: ../src/gmpv_menu.c:210 ../src/gmpv_menu.c:335
 msgid "_Audio Track"
 msgstr "音軌(_A)"
 
-#: ../src/menu.c:214 ../src/menu.c:339
+#: ../src/gmpv_menu.c:214 ../src/gmpv_menu.c:339
 msgid "S_ubtitle Track"
 msgstr "字幕軌道(_U)"
 
-#: ../src/mpv_obj.c:247
+#: ../src/gmpv_mpv_obj.c:197
 #, c-format
 msgid "Playback was terminated abnormally. Reason: %s."
 msgstr "回放被異常終止。原因:%s。"
 
-#: ../src/mpv_obj.c:1014
+#: ../src/gmpv_mpv_obj.c:983
 msgid "Failed to apply one or more MPV options."
 msgstr "套用一個或多個 MPV 選項失敗。"
 
-#: ../src/open_loc_dialog.c:77
+#: ../src/gmpv_open_loc_dialog.c:78
 msgid "Location:"
 msgstr "位置:"
 
-#: ../src/open_loc_dialog.c:93
+#: ../src/gmpv_open_loc_dialog.c:94
 msgid "Open Location"
 msgstr "開啟位置"
 
-#: ../src/playlist_widget.c:116
+#: ../src/gmpv_playlist_widget.c:406
 msgid "_Add…"
 msgstr "新增(_A)…"
 
-#: ../src/playlist_widget.c:117
+#: ../src/gmpv_playlist_widget.c:407
 msgid "Loop"
 msgstr "迴圈"
 
-#: ../src/playlist_widget.c:160
+#: ../src/gmpv_playlist_widget.c:504
 msgid "Playlist"
 msgstr "播放列表"
 
-#: ../src/plugins_manager.c:137
+#: ../src/gmpv_plugins_manager.c:139 ../src/gmpv_plugins_manager.c:364
+msgid "Add Lua Script"
+msgstr ""
+
+#: ../src/gmpv_plugins_manager.c:142
 msgid "Cancel"
 msgstr ""
 
-#: ../src/plugins_manager.c:139
+#: ../src/gmpv_plugins_manager.c:144
 msgid "Open"
 msgstr ""
 
-#: ../src/plugins_manager.c:176
+#: ../src/gmpv_plugins_manager.c:291
 #, c-format
 msgid "Failed to copy file from '%s' to '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/plugins_manager.c:295
+#: ../src/gmpv_plugins_manager.c:340
 msgid "No Lua script found"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:65
+#: ../src/gmpv_plugins_manager_item.c:65
 msgid "Remove"
 msgstr ""
 
-#: ../src/plugins_manager_item.c:158
+#: ../src/gmpv_plugins_manager_item.c:159
 msgid ""
 "Are you sure you want to remove this script? This action cannot be undone."
 msgstr ""
 
-#: ../src/plugins_manager_item.c:179
+#: ../src/gmpv_plugins_manager_item.c:180
 #, c-format
 msgid "Failed to delete file '%s'. Reason: %s"
 msgstr ""
 
-#: ../src/pref_dialog.c:274
+#: ../src/gmpv_pref_dialog.c:275
 msgid "<b>User Interface</b>"
 msgstr ""
 
-#: ../src/pref_dialog.c:277
+#: ../src/gmpv_pref_dialog.c:278
 msgid "Enable client-side decorations"
 msgstr "啟用客戶端裝飾"
 
-#: ../src/pref_dialog.c:280
+#: ../src/gmpv_pref_dialog.c:281
 msgid "Enable dark theme"
 msgstr "啟用暗色主題"
 
-#: ../src/pref_dialog.c:283
+#: ../src/gmpv_pref_dialog.c:284
 msgid "Remember last file's location"
 msgstr "記住最後一次開啟位置"
 
-#: ../src/pref_dialog.c:286
+#: ../src/gmpv_pref_dialog.c:287
 msgid "<b>MPV Configuration</b>"
 msgstr "<b>MPV 配置</b>"
 
-#: ../src/pref_dialog.c:289
+#: ../src/gmpv_pref_dialog.c:290
 msgid "Load MPV configuration file"
 msgstr "載入 MPV 配置檔"
 
-#: ../src/pref_dialog.c:292
+#: ../src/gmpv_pref_dialog.c:293
 msgid "MPV configuration file:"
 msgstr "MPV 配置檔:"
 
-#: ../src/pref_dialog.c:295
+#: ../src/gmpv_pref_dialog.c:296
 msgid "<b>Keybindings</b>"
 msgstr "<b>鍵繫結</b>"
 
-#: ../src/pref_dialog.c:298
+#: ../src/gmpv_pref_dialog.c:299
 msgid "Load MPV input configuration file"
 msgstr "載入 MPV 輸入配置檔"
 
-#: ../src/pref_dialog.c:301
+#: ../src/gmpv_pref_dialog.c:302
 msgid "MPV input configuration file:"
 msgstr "MPV 輸入配置檔:"
 
-#: ../src/pref_dialog.c:304
+#: ../src/gmpv_pref_dialog.c:305
 msgid "<b>Miscellaneous</b>"
 msgstr "<b>雜項</b>"
 
-#: ../src/pref_dialog.c:307
+#: ../src/gmpv_pref_dialog.c:308
 msgid "Extra MPV options:"
 msgstr "額外的 MPV 選項:"
 
-#: ../src/pref_dialog.c:340
+#: ../src/gmpv_pref_dialog.c:341
 msgid "General"
 msgstr ""
 
-#: ../src/pref_dialog.c:344
+#: ../src/gmpv_pref_dialog.c:345
 msgid "Lua Scripts"
 msgstr ""
 
-#: ../src/pref_dialog.c:366
+#: ../src/gmpv_pref_dialog.c:367
 msgid "Preferences"
 msgstr "偏好設定"
 
-#: ../src/shortcuts_window.c:43
+#: ../src/gmpv_shortcuts_window.c:43
 msgid "Open file"
 msgstr ""
 
-#: ../src/shortcuts_window.c:44
+#: ../src/gmpv_shortcuts_window.c:44
 msgid "Open location"
 msgstr ""
 
-#: ../src/shortcuts_window.c:45
+#: ../src/gmpv_shortcuts_window.c:45
 msgid "Quit"
 msgstr ""
 
-#: ../src/shortcuts_window.c:46
+#: ../src/gmpv_shortcuts_window.c:46
 msgid "Show preferences dialog"
 msgstr ""
 
-#: ../src/shortcuts_window.c:47
+#: ../src/gmpv_shortcuts_window.c:47
 msgid "Toggle playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:48
+#: ../src/gmpv_shortcuts_window.c:48
 msgid "Save playlist"
 msgstr ""
 
-#: ../src/shortcuts_window.c:49
+#: ../src/gmpv_shortcuts_window.c:49
 msgid "Remove selected playlist item"
 msgstr ""
 
-#: ../src/shortcuts_window.c:50
+#: ../src/gmpv_shortcuts_window.c:50
 msgid "Toggle fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:51
+#: ../src/gmpv_shortcuts_window.c:51
 msgid "Leave fullscreen mode"
 msgstr ""
 
-#: ../src/shortcuts_window.c:52
+#: ../src/gmpv_shortcuts_window.c:52
 msgid "Normal size"
 msgstr ""
 
-#: ../src/shortcuts_window.c:53
+#: ../src/gmpv_shortcuts_window.c:53
 msgid "Double size"
 msgstr ""
 
-#: ../src/shortcuts_window.c:54
+#: ../src/gmpv_shortcuts_window.c:54
 msgid "Half size"
 msgstr ""
diff --git a/src/Makefile.am b/src/Makefile.am
index 0f1bde4..5218126 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,56 +2,62 @@ AUTOMAKE_OPTIONS = foreign
 
 bin_PROGRAMS = gnome-mpv
 
-mpris_generated = mpris/mpris_gdbus.c mpris/mpris_gdbus.h
-mpris_files =	mpris/mpris.c mpris/mpris.h mpris/mpris_base.c \
-		mpris/mpris_base.h mpris/mpris_player.c mpris/mpris_player.h \
+mpris_generated = mpris/gmpv_mpris_gdbus.c mpris/gmpv_mpris_gdbus.h
+mpris_files =	mpris/gmpv_mpris.c mpris/gmpv_mpris.h \
+		mpris/gmpv_mpris_base.c mpris/gmpv_mpris_base.h \
+		mpris/gmpv_mpris_player.c mpris/gmpv_mpris_player.h \
 		$(mpris_generated)
-$(mpris_generated): $(top_srcdir)/data/mpris_gdbus.xml
-	$(GDBUS_CODEGEN) --c-namespace mpris --generate-c-code mpris/mpris_gdbus $< && \
-	sed -i '1i#pragma GCC diagnostic ignored \"-Wconversion\"' mpris/mpris_gdbus.c
+$(mpris_generated): $(top_srcdir)/data/gmpv_mpris_gdbus.xml
+	$(GDBUS_CODEGEN) --c-namespace gmpv_mpris --generate-c-code mpris/gmpv_mpris_gdbus $< && \
+	sed -i '1i#pragma GCC diagnostic ignored \"-Wconversion\"' mpris/gmpv_mpris_gdbus.c
 
-marshal_generated = marshal.c marshal.h
+marshal_generated = gmpv_marshal.c gmpv_marshal.h
 marshal_files = $(marshal_generated)
-marshal.h: $(top_srcdir)/data/marshal.lst
+gmpv_marshal.h: $(top_srcdir)/data/gmpv_marshal.lst
 	$(GLIB_GENMARSHAL) --prefix="g_cclosure_gen_marshal" --header $< > $@
-marshal.c: $(top_srcdir)/data/marshal.lst
+gmpv_marshal.c: $(top_srcdir)/data/gmpv_marshal.lst
 	$(GLIB_GENMARSHAL) --prefix="g_cclosure_gen_marshal" --body $< > $@
 	sed -i '1i#pragma GCC diagnostic ignored \"-Wmissing-prototypes\"' $@
 
-authors_generated = authors.h
+authors_generated = gmpv_authors.h
 authors_files = $(authors_generated)
-authors.h: $(top_srcdir)/AUTHORS
+gmpv_authors.h: $(top_srcdir)/AUTHORS
 	awk	'BEGIN{print	"#ifndef AUTHORS_H\n" \
 				"#define AUTHORS_H\n\n" \
 				"#define AUTHORS {\\"} \
 		/^[^#].+/{print "\"" $$0 "\",\\"} \
 		END{print "NULL}\n\n#endif"}' $< > $@
 
-media_key_files = media_keys/media_keys.c media_keys/media_keys.h
+media_key_files = media_keys/gmpv_media_keys.c media_keys/gmpv_media_keys.h
 
 BUILT_SOURCES = $(mpris_generated) $(marshal_generated) $(authors_generated)
 
-gnome_mpv_SOURCES =	main.c def.h \
-			actionctl.c actionctl.h \
-			application.c application.h \
-			common.c common.h \
-			control_box.c control_box.h \
-			main_window.c main_window.h \
-			menu.c menu.h \
-			mpv_obj.c mpv_obj.h \
-			mpv_opt.c mpv_opt.h \
-			open_loc_dialog.c open_loc_dialog.h \
-			playbackctl.c playbackctl.h \
-			playlist.c playlist.h \
-			playlist_widget.c playlist_widget.h \
-			plugins_manager.c plugins_manager.h \
-			plugins_manager_item.c plugins_manager_item.h \
-			pref_dialog.c pref_dialog.h \
-			shortcuts_window.c shortcuts_window.h \
-			track.c track.h \
+gnome_mpv_SOURCES =	gmpv_main.c gmpv_def.h \
+			gmpv_actionctl.c gmpv_actionctl.h \
+			gmpv_application.c gmpv_application.h \
+			gmpv_common.c gmpv_common.h \
+			gmpv_control_box.c gmpv_control_box.h \
+			gmpv_main_window.c gmpv_main_window.h \
+			gmpv_menu.c gmpv_menu.h \
+			gmpv_mpv_obj.c gmpv_mpv_obj.h \
+			gmpv_mpv_obj_private.h \
+			gmpv_mpv_opt.c gmpv_mpv_opt.h \
+			gmpv_open_loc_dialog.c gmpv_open_loc_dialog.h \
+			gmpv_playbackctl.c gmpv_playbackctl.h \
+			gmpv_playlist.c gmpv_playlist.h \
+			gmpv_playlist_widget.c gmpv_playlist_widget.h \
+			gmpv_plugins_manager.c gmpv_plugins_manager.h \
+			gmpv_plugins_manager_item.c gmpv_plugins_manager_item.h \
+			gmpv_pref_dialog.c gmpv_pref_dialog.h \
+			gmpv_track.c gmpv_track.h \
+			gmpv_video_area.c gmpv_video_area.h \
 			$(mpris_files) $(marshal_files) $(media_key_files) \
 			$(authors_files)
 
+if NEW_GTK
+gnome_mpv_SOURCES += gmpv_shortcuts_window.c gmpv_shortcuts_window.h
+endif
+
 gnome_mpv_CFLAGS =	$(DEPS_CFLAGS) \
 			-DG_SETTINGS_ENABLE_BACKEND \
 			-DPACKAGE_LOCALEDIR=\""$(localedir)"\"
diff --git a/src/application.h b/src/application.h
deleted file mode 100644
index ea29075..0000000
--- a/src/application.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2016 gnome-mpv
- *
- * This file is part of GNOME MPV.
- *
- * GNOME MPV 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 3 of the License, or
- * (at your option) any later version.
- *
- * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef APPLICATION_H
-#define APPLICATION_H
-
-#include <gtk/gtk.h>
-#include <mpv/client.h>
-#include <mpv/opengl_cb.h>
-
-#include "main_window.h"
-#include "playlist.h"
-#include "mpv_obj.h"
-
-G_BEGIN_DECLS
-
-#define APPLICATION_TYPE (application_get_type())
-
-#define	APPLICATION(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST((obj), APPLICATION_TYPE, Application))
-
-#define	APPLICATION_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST((klass), APPLICATION_TYPE, ApplicationClass))
-
-#define	IS_APPLICATION(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), APPLICATION_TYPE))
-
-#define	IS_APPLICATION_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), APPLICATION_TYPE))
-
-struct _Application
-{
-	GtkApplication parent;
-	MpvObj *mpv;
-	gchar **files;
-	guint inhibit_cookie;
-	gint64 target_playlist_pos;
-	GSettings *config;
-	MainWindow *gui;
-	GtkWidget *fs_control;
-	Playlist *playlist_store;
-};
-
-struct _ApplicationClass
-{
-	GtkApplicationClass parent_class;
-};
-
-typedef struct _Application Application;
-typedef struct _ApplicationClass ApplicationClass;
-
-GType application_get_type(void);
-Application *application_new(gchar *id, GApplicationFlags flags);
-
-G_END_DECLS
-
-#endif
diff --git a/src/control_box.h b/src/control_box.h
deleted file mode 100644
index df28bd9..0000000
--- a/src/control_box.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2014-2016 gnome-mpv
- *
- * This file is part of GNOME MPV.
- *
- * GNOME MPV 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 3 of the License, or
- * (at your option) any later version.
- *
- * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef CONTROL_BOX_H
-#define CONTROL_BOX_H
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define CONTROL_BOX_TYPE (control_box_get_type())
-
-#define	CONTROL_BOX(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST((obj), CONTROL_BOX_TYPE, ControlBox))
-
-#define	CONTROL_BOX_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST((klass), CONTROL_BOX_TYPE, ControlBoxClass))
-
-#define	IS_CONTROL_BOX(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), CONTROL_BOX_TYPE))
-
-#define	IS_CONTROL_BOX_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), CONTROL_BOX_TYPE))
-
-typedef struct _ControlBox ControlBox;
-typedef struct _ControlBoxClass ControlBoxClass;
-
-GtkWidget *control_box_new(void);
-GType control_box_get_type(void);
-void control_box_set_enabled(ControlBox *box, gboolean enabled);
-void control_box_set_chapter_enabled(ControlBox *box, gboolean enabled);
-void control_box_set_volume_enabled(ControlBox *box, gboolean enabled);
-void control_box_set_seek_bar_pos(ControlBox *box, gdouble pos);
-void control_box_set_seek_bar_length(ControlBox *box, gint length);
-void control_box_set_volume(ControlBox *box, gdouble volume);
-gdouble control_box_get_volume(ControlBox *box);
-gboolean control_box_get_volume_popup_visible(ControlBox *box);
-void control_box_set_playing_state(ControlBox *box, gboolean playing);
-void control_box_set_fullscreen_state(ControlBox *box, gboolean fullscreen);
-void control_box_set_fullscreen_btn_visible(ControlBox *box, gboolean value);
-void control_box_reset(ControlBox *box);
-
-G_END_DECLS
-
-#endif
-
diff --git a/src/actionctl.c b/src/gmpv_actionctl.c
similarity index 66%
rename from src/actionctl.c
rename to src/gmpv_actionctl.c
index b061717..ee1ea7b 100644
--- a/src/actionctl.c
+++ b/src/gmpv_actionctl.c
@@ -19,16 +19,19 @@
 
 #include <glib/gi18n.h>
 
-#include "actionctl.h"
-#include "playlist_widget.h"
-#include "def.h"
-#include "mpv_obj.h"
-#include "playlist.h"
-#include "open_loc_dialog.h"
-#include "pref_dialog.h"
-#include "shortcuts_window.h"
-#include "common.h"
-#include "authors.h"
+#include "gmpv_actionctl.h"
+#include "gmpv_playlist_widget.h"
+#include "gmpv_def.h"
+#include "gmpv_mpv_obj.h"
+#include "gmpv_playlist.h"
+#include "gmpv_open_loc_dialog.h"
+#include "gmpv_pref_dialog.h"
+#include "gmpv_common.h"
+#include "gmpv_authors.h"
+
+#if (GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 20)
+#include "gmpv_shortcuts_window.h"
+#endif
 
 static void open_handler(	GSimpleAction *action,
 				GVariant *param,
@@ -71,42 +74,37 @@ static void open_handler(	GSimpleAction *action,
 				GVariant *param,
 				gpointer data )
 {
-	Application *app = data;
-	GSettings *config = NULL;
-	GtkFileChooser *file_chooser;
-	GtkWidget *open_dialog;
-	gboolean last_folder_enable;
-	gboolean append;
+	GmpvApplication *app = data;
+	GmpvMainWindow *wnd = NULL;
+	GSettings *main_config = NULL;
+	GSettings *win_config = NULL;
+	GtkFileChooser *file_chooser = NULL;
+	GtkWidget *open_dialog = NULL;
+	gboolean last_folder_enable = FALSE;
+	gboolean append = FALSE;
 
 	g_variant_get(param, "b", &append);
 
-	open_dialog
-		= gtk_file_chooser_dialog_new(	append?
-						_("Add File to Playlist"):
-						_("Open File"),
-						GTK_WINDOW(app->gui),
-						GTK_FILE_CHOOSER_ACTION_OPEN,
-						_("_Cancel"),
-						GTK_RESPONSE_CANCEL,
-						_("_Open"),
-						GTK_RESPONSE_ACCEPT,
-						NULL );
-
+	wnd = gmpv_application_get_main_window(app);
+	open_dialog =	gtk_file_chooser_dialog_new
+			(	append?_("Add File to Playlist"):_("Open File"),
+				GTK_WINDOW(wnd),
+				GTK_FILE_CHOOSER_ACTION_OPEN,
+				_("_Cancel"), GTK_RESPONSE_CANCEL,
+				_("_Open"), GTK_RESPONSE_ACCEPT,
+				NULL );
+	main_config = g_settings_new(CONFIG_ROOT);
 	file_chooser = GTK_FILE_CHOOSER(open_dialog);
-
-	last_folder_enable
-		= g_settings_get_boolean( 	app->config,
-						"last-folder-enable" );
+	last_folder_enable =	g_settings_get_boolean
+				(main_config, "last-folder-enable");
 
 	if(last_folder_enable)
 	{
 		gchar *last_folder_uri;
 
-		config = g_settings_new(CONFIG_WIN_STATE);
-
-		last_folder_uri = g_settings_get_string
-					(config, "last-folder-uri");
-
+		win_config = g_settings_new(CONFIG_WIN_STATE);
+		last_folder_uri =	g_settings_get_string
+					(win_config, "last-folder-uri");
 
 		if(last_folder_uri && strlen(last_folder_uri) > 0)
 		{
@@ -138,7 +136,9 @@ static void open_handler(	GSimpleAction *action,
 
 		if(uri_slist)
 		{
-			mpv_obj_load_list(app->mpv, uri_list, append, TRUE);
+			GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(app);
+
+			gmpv_mpv_obj_load_list(mpv, uri_list, append, TRUE);
 		}
 
 		if(last_folder_enable)
@@ -147,8 +147,9 @@ static void open_handler(	GSimpleAction *action,
 				= gtk_file_chooser_get_current_folder_uri
 					(file_chooser);
 
-			g_settings_set_string
-				(config, "last-folder-uri", last_folder_uri ?: "" );
+			g_settings_set_string(	win_config,
+						"last-folder-uri",
+						last_folder_uri?:"" );
 
 			g_free(last_folder_uri);
 		}
@@ -158,42 +159,44 @@ static void open_handler(	GSimpleAction *action,
 	}
 
 	gtk_widget_destroy(open_dialog);
-	g_clear_object(&config);
+	g_clear_object(&main_config);
+	g_clear_object(&win_config);
 }
 
 static void open_loc_handler(	GSimpleAction *action,
 				GVariant *param,
 				gpointer data )
 {
-	Application *app = (Application*)data;
-	OpenLocDialog *open_loc_dialog;
-
-	open_loc_dialog
-		= OPEN_LOC_DIALOG(open_loc_dialog_new(GTK_WINDOW(app->gui)));
+	GmpvApplication *app = data;
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(app);
+	GtkWidget *dlg = gmpv_open_loc_dialog_new(GTK_WINDOW(wnd));
 
-	if(gtk_dialog_run(GTK_DIALOG(open_loc_dialog)) == GTK_RESPONSE_ACCEPT)
+	if(gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT)
 	{
 		const gchar *loc_str;
+		GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(app);
 
-		loc_str = open_loc_dialog_get_string(open_loc_dialog);
+		loc_str =	gmpv_open_loc_dialog_get_string
+				(GMPV_OPEN_LOC_DIALOG(dlg));
 
-		mpv_obj_set_property_flag(app->mpv, "pause", FALSE);
-		mpv_obj_load(app->mpv, loc_str, FALSE, TRUE);
+		gmpv_mpv_obj_set_property_flag(mpv, "pause", FALSE);
+		gmpv_mpv_obj_load(mpv, loc_str, FALSE, TRUE);
 	}
 
-	gtk_widget_destroy(GTK_WIDGET(open_loc_dialog));
+	gtk_widget_destroy(dlg);
 }
 
 static void loop_handler(	GSimpleAction *action,
 				GVariant *value,
 				gpointer data )
 {
-	Application *app = data;
+	GmpvApplication *app = data;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(app);
 	gboolean loop = g_variant_get_boolean(value);
 
 	g_simple_action_set_state(action, value);
 
-	mpv_check_error(mpv_obj_set_property_string(	app->mpv,
+	mpv_check_error(gmpv_mpv_obj_set_property_string(	mpv,
 							"loop",
 							loop?"inf":"no" ));
 }
@@ -202,28 +205,35 @@ static void show_shortcuts_handler(	GSimpleAction *action,
 					GVariant *param,
 					gpointer data )
 {
-	Application *app = data;
-	GtkWidget *wnd = shortcuts_window_new(GTK_WINDOW(app->gui));
+#if (GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 20)
+	GmpvApplication *app = data;
+	GmpvMainWindow *mwnd = gmpv_application_get_main_window(app);
+	GtkWidget *wnd = gmpv_shortcuts_window_new(GTK_WINDOW(mwnd));
 
 	gtk_widget_show_all(wnd);
+#endif
 }
 
 static void playlist_toggle_handler(	GSimpleAction *action,
 					GVariant *param,
 					gpointer data )
 {
-	Application *app = data;
-	gboolean visible = gtk_widget_get_visible(app->gui->playlist);
+	GmpvApplication *app = data;
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(app);
+	gboolean visible = gmpv_main_window_get_playlist_visible(wnd);
 
-	main_window_set_playlist_visible(app->gui, !visible);
+	gmpv_main_window_set_playlist_visible(wnd, !visible);
 }
 
 static void playlist_save_handler(	GSimpleAction *action,
 					GVariant *param,
 					gpointer data )
 {
-	Application *app = data;
-	GtkTreeModel *playlist;
+	GmpvApplication *app = data;
+	GmpvMpvObj *mpv;
+	GmpvMainWindow *wnd;
+	GmpvPlaylist *playlist;
+	GtkTreeModel *model;
 	GFile *dest_file;
 	GOutputStream *dest_stream;
 	GtkFileChooser *file_chooser;
@@ -232,24 +242,23 @@ static void playlist_save_handler(	GSimpleAction *action,
 	GtkTreeIter iter;
 	gboolean rc;
 
-	playlist = GTK_TREE_MODEL(playlist_get_store(app->mpv->playlist));
+	mpv = gmpv_application_get_mpv_obj(app);
+	wnd = gmpv_application_get_main_window(app);
+	playlist = gmpv_mpv_obj_get_playlist(mpv);
+	model = GTK_TREE_MODEL(gmpv_playlist_get_store(playlist));
 	dest_file = NULL;
 	dest_stream = NULL;
+	save_dialog =	gtk_file_chooser_dialog_new
+			(	_("Save Playlist"),
+				GTK_WINDOW(wnd),
+				GTK_FILE_CHOOSER_ACTION_SAVE,
+				_("_Cancel"), GTK_RESPONSE_CANCEL,
+				_("_Save"), GTK_RESPONSE_ACCEPT,
+				NULL );
+	file_chooser = GTK_FILE_CHOOSER(save_dialog);
 	error = NULL;
 	rc = FALSE;
 
-	save_dialog
-		= gtk_file_chooser_dialog_new(	_("Save Playlist"),
-						GTK_WINDOW(app->gui),
-						GTK_FILE_CHOOSER_ACTION_SAVE,
-						_("_Cancel"),
-						GTK_RESPONSE_CANCEL,
-						_("_Save"),
-						GTK_RESPONSE_ACCEPT,
-						NULL );
-
-	file_chooser = GTK_FILE_CHOOSER(save_dialog);
-
 	gtk_file_chooser_set_do_overwrite_confirmation(file_chooser, TRUE);
 	gtk_file_chooser_set_current_name(file_chooser, "playlist.m3u");
 
@@ -273,7 +282,7 @@ static void playlist_save_handler(	GSimpleAction *action,
 							&error );
 
 		dest_stream = G_OUTPUT_STREAM(dest_file_stream);
-		rc = gtk_tree_model_get_iter_first(playlist, &iter);
+		rc = gtk_tree_model_get_iter_first(model, &iter);
 		rc &= !!dest_stream;
 	}
 
@@ -283,7 +292,7 @@ static void playlist_save_handler(	GSimpleAction *action,
 		gsize written;
 
 		gtk_tree_model_get
-			(playlist, &iter, PLAYLIST_URI_COLUMN, &uri, -1);
+			(model, &iter, PLAYLIST_URI_COLUMN, &uri, -1);
 
 		rc &= g_output_stream_printf(	dest_stream,
 						&written,
@@ -291,7 +300,7 @@ static void playlist_save_handler(	GSimpleAction *action,
 						&error,
 						"%s\n",
 						uri );
-		rc &= gtk_tree_model_iter_next(playlist, &iter);
+		rc &= gtk_tree_model_iter_next(model, &iter);
 	}
 
 	if(dest_stream)
@@ -316,11 +325,16 @@ static void playlist_remove_selected(	GSimpleAction *action,
 					GVariant *param,
 					gpointer data )
 {
-	MainWindow *wnd = APPLICATION(data)->gui;
+	GmpvMainWindow *wnd =	gmpv_application_get_main_window
+				(GMPV_APPLICATION(data));
 
-	if(main_window_get_playlist_visible(wnd))
+	if(gmpv_main_window_get_playlist_visible(wnd))
 	{
-		playlist_widget_remove_selected(PLAYLIST_WIDGET(wnd->playlist));
+		GmpvPlaylistWidget *playlist;
+
+		playlist = gmpv_main_window_get_playlist(wnd);
+
+		gmpv_playlist_widget_remove_selected(playlist);
 	}
 }
 
@@ -328,30 +342,32 @@ static void pref_handler(	GSimpleAction *action,
 				GVariant *param,
 				gpointer data )
 {
-	Application *app = data;
+	GmpvApplication *app = data;
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(app);
 	GSettings *settings = g_settings_new(CONFIG_ROOT);
-	PrefDialog *pref_dialog;
+	GmpvPrefDialog *pref_dialog;
 	gboolean csd_enable_old;
 
 	csd_enable_old = g_settings_get_boolean(settings, "csd-enable");
-	pref_dialog = PREF_DIALOG(pref_dialog_new(GTK_WINDOW(app->gui)));
+	pref_dialog = GMPV_PREF_DIALOG(gmpv_pref_dialog_new(GTK_WINDOW(wnd)));
 
 	if(gtk_dialog_run(GTK_DIALOG(pref_dialog)) == GTK_RESPONSE_ACCEPT)
 	{
+		GmpvMpvObj *mpv;
 		gboolean csd_enable;
 		gboolean dark_theme_enable;
 
-		csd_enable = g_settings_get_boolean
-				(settings, "csd-enable");
-
-		dark_theme_enable = g_settings_get_boolean
+		mpv = gmpv_application_get_mpv_obj(app);
+		csd_enable = g_settings_get_boolean(settings, "csd-enable");
+		dark_theme_enable =	g_settings_get_boolean
 					(settings, "dark-theme-enable");
 
 		if(csd_enable_old != csd_enable)
 		{
-			GtkWidget *dialog
-				= gtk_message_dialog_new
-					(	GTK_WINDOW(app->gui),
+			GtkWidget *dialog;
+
+			dialog =	gtk_message_dialog_new
+					(	GTK_WINDOW(wnd),
 						GTK_DIALOG_DESTROY_WITH_PARENT,
 						GTK_MESSAGE_INFO,
 						GTK_BUTTONS_OK,
@@ -365,13 +381,13 @@ static void pref_handler(	GSimpleAction *action,
 			gtk_widget_destroy(dialog);
 		}
 
-		g_object_set(	app->gui->settings,
+		g_object_set(	gtk_settings_get_default(),
 				"gtk-application-prefer-dark-theme",
 				dark_theme_enable,
 				NULL );
 
-		mpv_obj_reset(app->mpv);
-		gtk_widget_queue_draw(GTK_WIDGET(app->gui));
+		gmpv_mpv_obj_reset(mpv);
+		gtk_widget_queue_draw(GTK_WIDGET(wnd));
 	}
 
 	gtk_widget_destroy(GTK_WIDGET(pref_dialog));
@@ -388,7 +404,8 @@ static void track_select_handler(	GSimpleAction *action,
 					GVariant *value,
 					gpointer data )
 {
-	Application *app = data;
+	GmpvApplication *app = data;
+	GmpvMpvObj *mpv;
 	gint64 id;
 	gchar *name;
 	const gchar *mpv_prop;
@@ -414,13 +431,15 @@ static void track_select_handler(	GSimpleAction *action,
 		g_assert_not_reached();
 	}
 
-	if(id >= 0)
+	mpv = gmpv_application_get_mpv_obj(app);
+
+	if(id > 0)
 	{
-		mpv_obj_set_property(app->mpv, mpv_prop, MPV_FORMAT_INT64, &id);
+		gmpv_mpv_obj_set_property(mpv, mpv_prop, MPV_FORMAT_INT64, &id);
 	}
 	else
 	{
-		mpv_obj_set_property_string(app->mpv, mpv_prop, "no");
+		gmpv_mpv_obj_set_property_string(mpv, mpv_prop, "no");
 	}
 }
 
@@ -428,23 +447,22 @@ static void load_track_handler(	GSimpleAction *action,
 				GVariant *param,
 				gpointer data )
 {
-	Application *app = (Application*)data;
+	GmpvApplication *app = data;
+	GmpvMainWindow *wnd;
 	GtkFileChooser *file_chooser;
 	GtkWidget *open_dialog;
 	const gchar *cmd_name;
 
 	g_variant_get(param, "s", &cmd_name);
 
-	open_dialog
-		= gtk_file_chooser_dialog_new(	_("Load External…"),
-						GTK_WINDOW(app->gui),
-						GTK_FILE_CHOOSER_ACTION_OPEN,
-						_("_Cancel"),
-						GTK_RESPONSE_CANCEL,
-						_("_Open"),
-						GTK_RESPONSE_ACCEPT,
-						NULL );
-
+	wnd = gmpv_application_get_main_window(app);
+	open_dialog =	gtk_file_chooser_dialog_new
+			(	_("Load External…"),
+				GTK_WINDOW(wnd),
+				GTK_FILE_CHOOSER_ACTION_OPEN,
+				_("_Cancel"), GTK_RESPONSE_CANCEL,
+				_("_Open"), GTK_RESPONSE_ACCEPT,
+				NULL );
 	file_chooser = GTK_FILE_CHOOSER(open_dialog);
 
 	gtk_file_chooser_set_select_multiple(file_chooser, TRUE);
@@ -452,6 +470,7 @@ static void load_track_handler(	GSimpleAction *action,
 	if(gtk_dialog_run(GTK_DIALOG(open_dialog)) == GTK_RESPONSE_ACCEPT)
 	{
 		const gchar *cmd[] = {cmd_name, NULL, NULL};
+		GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(app);
 		GSList *uri_list = gtk_file_chooser_get_filenames(file_chooser);
 		GSList *uri = uri_list;
 
@@ -459,7 +478,7 @@ static void load_track_handler(	GSimpleAction *action,
 		{
 			cmd[1] = uri->data;
 
-			mpv_obj_command(app->mpv, cmd);
+			gmpv_mpv_obj_command(mpv, cmd);
 
 			uri = g_slist_next(uri);
 		}
@@ -474,22 +493,23 @@ static void fullscreen_handler(	GSimpleAction *action,
 				GVariant *param,
 				gpointer data )
 {
-	MainWindow *wnd = APPLICATION(data)->gui;
+	GmpvMainWindow *wnd =	gmpv_application_get_main_window
+				(GMPV_APPLICATION(data));
 	gchar *name;
 
 	g_object_get(action, "name", &name, NULL);
 
 	if(g_strcmp0(name, "fullscreen_toggle") == 0)
 	{
-		main_window_toggle_fullscreen(wnd);
+		gmpv_main_window_toggle_fullscreen(wnd);
 	}
 	else if(g_strcmp0(name, "fullscreen_enter") == 0)
 	{
-		main_window_set_fullscreen(wnd, TRUE);
+		gmpv_main_window_set_fullscreen(wnd, TRUE);
 	}
 	else if(g_strcmp0(name, "fullscreen_leave") == 0)
 	{
-		main_window_set_fullscreen(wnd, FALSE);
+		gmpv_main_window_set_fullscreen(wnd, FALSE);
 	}
 
 	g_free(name);
@@ -501,17 +521,18 @@ static void video_size_handler(	GSimpleAction *action,
 {
 	gdouble value = g_variant_get_double (param);
 
-	resize_window_to_fit((Application *)data, value);
+	resize_window_to_fit((GmpvApplication *)data, value);
 }
 
 static void about_handler(	GSimpleAction *action,
 				GVariant *param,
 				gpointer data )
 {
-	Application *app = (Application*)data;
+	GmpvApplication *app = data;
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(app);
 	const gchar *authors[] = AUTHORS;
 
-	gtk_show_about_dialog(	GTK_WINDOW(app->gui),
+	gtk_show_about_dialog(	GTK_WINDOW(wnd),
 				"logo-icon-name",
 				ICON_NAME,
 				"version",
@@ -531,7 +552,7 @@ static void about_handler(	GSimpleAction *action,
 				NULL );
 }
 
-void actionctl_map_actions(Application *app)
+void gmpv_actionctl_map_actions(GmpvApplication *app)
 {
 	const GActionEntry entries[]
 	= {	{.name = "open",
diff --git a/src/actionctl.h b/src/gmpv_actionctl.h
similarity index 87%
rename from src/actionctl.h
rename to src/gmpv_actionctl.h
index 1acfae8..61998ff 100644
--- a/src/actionctl.h
+++ b/src/gmpv_actionctl.h
@@ -20,8 +20,12 @@
 #ifndef ACTIONCTL_H
 #define ACTIONCTL_H
 
-#include "common.h"
+#include "gmpv_common.h"
 
-void actionctl_map_actions(Application *app);
+G_BEGIN_DECLS
+
+void gmpv_actionctl_map_actions(GmpvApplication *app);
+
+G_END_DECLS
 
 #endif
diff --git a/src/application.c b/src/gmpv_application.c
similarity index 56%
rename from src/application.c
rename to src/gmpv_application.c
index 19da414..3e81cc1 100644
--- a/src/application.c
+++ b/src/gmpv_application.c
@@ -35,18 +35,38 @@
 #include <epoxy/wgl.h>
 #endif
 
-#include "application.h"
-#include "control_box.h"
-#include "actionctl.h"
-#include "playbackctl.h"
-#include "playlist_widget.h"
-#include "track.h"
-#include "menu.h"
-#include "mpv_obj.h"
-#include "def.h"
-#include "mpris/mpris.h"
-#include "media_keys/media_keys.h"
+#include "gmpv_application.h"
+#include "gmpv_control_box.h"
+#include "gmpv_actionctl.h"
+#include "gmpv_playbackctl.h"
+#include "gmpv_playlist_widget.h"
+#include "gmpv_track.h"
+#include "gmpv_menu.h"
+#include "gmpv_mpv_obj.h"
+#include "gmpv_video_area.h"
+#include "gmpv_def.h"
+#include "mpris/gmpv_mpris.h"
+#include "media_keys/gmpv_media_keys.h"
+
+struct _GmpvApplication
+{
+	GtkApplication parent;
+	GmpvMpvObj *mpv;
+	gchar **files;
+	guint inhibit_cookie;
+	gint64 target_playlist_pos;
+	GSettings *config;
+	GmpvMainWindow *gui;
+	GtkWidget *fs_control;
+	GmpvPlaylist *playlist_store;
+};
+
+struct _GmpvApplicationClass
+{
+	GtkApplicationClass parent_class;
+};
 
+static void *get_proc_address(void *fn_ctx, const gchar *name);
 static gboolean vid_area_render_handler(	GtkGLArea *area,
 						GdkGLContext *context,
 						gpointer data );
@@ -61,22 +81,21 @@ static gboolean draw_handler(GtkWidget *widget, cairo_t *cr, gpointer data);
 static gboolean delete_handler(	GtkWidget *widget,
 				GdkEvent *event,
 				gpointer data );
-static void playlist_row_activated_handler(	GtkTreeView *tree_view,
-						GtkTreePath *path,
-						GtkTreeViewColumn *column,
+static void playlist_row_activated_handler(	GmpvPlaylistWidget *playlist,
+						gint64 pos,
 						gpointer data );
-static void playlist_row_deleted_handler(	Playlist *pl,
+static void playlist_row_deleted_handler(	GmpvPlaylistWidget *playlist,
 						gint pos,
 						gpointer data );
-static void playlist_row_reodered_handler(	Playlist *pl,
+static void playlist_row_reodered_handler(	GmpvPlaylistWidget *playlist,
 						gint src,
 						gint dest,
 						gpointer data );
-static Track *parse_track_list(mpv_node_list *node);
-static void update_track_list(Application *app, mpv_node* track_list);
+static GmpvTrack *parse_track_list(mpv_node_list *node);
+static void update_track_list(GmpvApplication *app, mpv_node* track_list);
 static void mpv_prop_change_handler(mpv_event_property *prop, gpointer data);
 static void mpv_event_handler(mpv_event *event, gpointer data);
-static void mpv_error_handler(MpvObj *mpv, const gchar *err, gpointer data);
+static void mpv_error_handler(GmpvMpvObj *mpv, const gchar *err, gpointer data);
 static void drag_data_handler(	GtkWidget *widget,
 				GdkDragContext *context,
 				gint x,
@@ -95,27 +114,51 @@ static gboolean key_release_handler(	GtkWidget *widget,
 static gboolean mouse_press_handler(	GtkWidget *widget,
 					GdkEvent *event,
 					gpointer data );
+static gboolean queue_render(GtkGLArea *area);
 static void opengl_cb_update_callback(void *cb_ctx);
-static gboolean get_use_opengl(void);
-static gint64 get_xid(GtkWidget *widget);
-static gboolean load_files(Application* app, const gchar **files);
-static void connect_signals(Application *app);
+static void set_playlist_pos(GmpvApplication *app, gint64 pos);
+static void set_inhibit_idle(GmpvApplication *app, gboolean inhibit);
+static gboolean load_files(GmpvApplication* app, const gchar **files);
+static void connect_signals(GmpvApplication *app);
 static inline void add_accelerator(	GtkApplication *app,
 					const char *accel,
 					const char *action );
-static void setup_accelerators(Application *app);
-static void application_class_init(ApplicationClass *klass);
-static void application_init(Application *app);
+static void setup_accelerators(GmpvApplication *app);
+static void gmpv_application_class_init(GmpvApplicationClass *klass);
+static void gmpv_application_init(GmpvApplication *app);
 
-G_DEFINE_TYPE(Application, application, GTK_TYPE_APPLICATION)
+G_DEFINE_TYPE(GmpvApplication, gmpv_application, GTK_TYPE_APPLICATION)
+
+static void *get_proc_address(void *fn_ctx, const gchar *name)
+{
+	GdkDisplay *display = gdk_display_get_default();
+
+#ifdef GDK_WINDOWING_WAYLAND
+	if (GDK_IS_WAYLAND_DISPLAY(display))
+		return eglGetProcAddress(name);
+#endif
+#ifdef GDK_WINDOWING_X11
+	if (GDK_IS_X11_DISPLAY(display))
+		return	(void *)(intptr_t)
+			glXGetProcAddressARB((const GLubyte *)name);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+	if (GDK_IS_WIN32_DISPLAY(display))
+		return wglGetProcAddress(name);
+#endif
+	g_assert_not_reached();
+}
 
 static gboolean vid_area_render_handler(	GtkGLArea *area,
 						GdkGLContext *context,
 						gpointer data )
 {
-	Application *app = data;
+	GmpvApplication *app = data;
+	mpv_opengl_cb_context *opengl_ctx;
+
+	opengl_ctx = gmpv_mpv_obj_get_opengl_cb_context(app->mpv);
 
-	if(app->mpv->opengl_ctx)
+	if(opengl_ctx)
 	{
 		int width;
 		int height;
@@ -126,7 +169,7 @@ static gboolean vid_area_render_handler(	GtkGLArea *area,
 		fbo = -1;
 
 		glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
-		mpv_opengl_cb_draw(app->mpv->opengl_ctx, fbo, width, height);
+		mpv_opengl_cb_draw(opengl_ctx, fbo, width, height);
 	}
 
 	while(gtk_events_pending())
@@ -139,13 +182,14 @@ static gboolean vid_area_render_handler(	GtkGLArea *area,
 
 static void startup_handler(GApplication *gapp, gpointer data)
 {
-	Application *app = data;
+	GmpvApplication *app = data;
+	GmpvControlBox *control_box;
 	const gchar *vid_area_style = ".gmpv-vid-area{background-color: black}";
 	GtkCssProvider *style_provider;
 	gboolean css_loaded;
-	gboolean use_opengl;
 	gboolean csd_enable;
 	gboolean dark_theme_enable;
+	gint64 wid;
 	gchar *mpvinput;
 
 	setlocale(LC_NUMERIC, "C");
@@ -156,18 +200,17 @@ static void startup_handler(GApplication *gapp, gpointer data)
 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
 	textdomain(GETTEXT_PACKAGE);
 
-	use_opengl = get_use_opengl();
-
 	app->files = NULL;
 	app->inhibit_cookie = 0;
 	app->target_playlist_pos = -1;
 	app->config = g_settings_new(CONFIG_ROOT);
-	app->playlist_store = playlist_new();
-	app->gui = MAIN_WINDOW(main_window_new(app, app->playlist_store, use_opengl));
+	app->playlist_store = gmpv_playlist_new();
+	app->gui = GMPV_MAIN_WINDOW(gmpv_main_window_new(app, app->playlist_store));
 	app->fs_control = NULL;
 
 	migrate_config(app);
 
+	control_box = gmpv_main_window_get_control_box(app->gui);
 	style_provider = gtk_css_provider_new();
 	css_loaded = gtk_css_provider_load_from_data
 			(style_provider, vid_area_style, -1, NULL);
@@ -195,17 +238,17 @@ static void startup_handler(GApplication *gapp, gpointer data)
 	{
 		GMenu *app_menu = g_menu_new();
 
-		menu_build_app_menu(app_menu);
+		gmpv_menu_build_app_menu(app_menu);
 		gtk_application_set_app_menu
 			(GTK_APPLICATION(app), G_MENU_MODEL(app_menu));
 
-		main_window_enable_csd(app->gui);
+		gmpv_main_window_enable_csd(app->gui);
 	}
 	else
 	{
 		GMenu *full_menu = g_menu_new();
 
-		menu_build_full(full_menu, NULL, NULL, NULL);
+		gmpv_menu_build_full(full_menu, NULL, NULL, NULL);
 		gtk_application_set_app_menu(GTK_APPLICATION(app), NULL);
 
 		gtk_application_set_menubar
@@ -213,41 +256,34 @@ static void startup_handler(GApplication *gapp, gpointer data)
 	}
 
 	setup_accelerators(app);
-	actionctl_map_actions(app);
-	main_window_load_state(app->gui);
+	gmpv_actionctl_map_actions(app);
+	gmpv_main_window_load_state(app->gui);
 	gtk_widget_show_all(GTK_WIDGET(app->gui));
 
 	if(csd_enable)
 	{
-		control_box_set_fullscreen_btn_visible
-			(CONTROL_BOX(app->gui->control_box), FALSE);
+		gmpv_control_box_set_fullscreen_btn_visible
+			(control_box, FALSE);
 	}
 
-	control_box_set_chapter_enabled
-		(CONTROL_BOX(app->gui->control_box), FALSE);
+	gmpv_control_box_set_chapter_enabled(control_box, FALSE);
 
-	/* Due to a GTK bug, get_xid() must not be called when opengl-cb is
-	 * enabled or the GtkGLArea will break.
-	 */
-	app->mpv = mpv_obj_new(	app->playlist_store,
-				use_opengl,
-				use_opengl?-1:get_xid(app->gui->vid_area),
-				use_opengl?GTK_GL_AREA(app->gui->vid_area):NULL );
+	wid = gmpv_video_area_get_xid(gmpv_main_window_get_video_area(app->gui));
+	app->mpv = gmpv_mpv_obj_new(app->playlist_store, wid);
 
 	if(csd_enable)
 	{
-		control_box_set_fullscreen_btn_visible
-			(CONTROL_BOX(app->gui->control_box), FALSE);
+		gmpv_control_box_set_fullscreen_btn_visible
+			(control_box, FALSE);
 	}
 
-	control_box_set_chapter_enabled
-		(CONTROL_BOX(app->gui->control_box), FALSE);
+	gmpv_control_box_set_chapter_enabled(control_box, FALSE);
 
 	connect_signals(app);
-	mpris_init(app);
-	media_keys_init(app);
+	gmpv_mpris_init(app);
+	gmpv_media_keys_init(app);
 
-	g_object_set(	app->gui->settings,
+	g_object_set(	gtk_settings_get_default(),
 			"gtk-application-prefer-dark-theme",
 			dark_theme_enable,
 			NULL );
@@ -261,14 +297,48 @@ static void startup_handler(GApplication *gapp, gpointer data)
 
 static void activate_handler(GApplication *gapp, gpointer data)
 {
-	gtk_window_present(GTK_WINDOW(APPLICATION(data)->gui));
+	gtk_window_present(GTK_WINDOW(GMPV_APPLICATION(data)->gui));
 }
 
-static void mpv_init_handler(MpvObj *mpv, gpointer data)
+static void mpv_init_handler(GmpvMpvObj *mpv, gpointer data)
 {
-	Application *app = data;
+	GmpvApplication *app = data;
+	gchar *current_vo = gmpv_mpv_obj_get_property_string(mpv, "current-vo");
+	GmpvVideoArea *vid_area = gmpv_main_window_get_video_area(app->gui);
+
+	gmpv_video_area_set_use_opengl(vid_area, !current_vo);
+
+	/* current_vo should be NULL if the selected vo is opengl-cb */
+	if(!current_vo)
+	{
+		GtkGLArea *gl_area;
+		mpv_opengl_cb_context *opengl_ctx;
+		gint rc;
 
-	g_signal_handlers_disconnect_by_func(mpv, mpv_init_handler, data);
+		gl_area = gmpv_video_area_get_gl_area(vid_area);
+		g_signal_connect(	gl_area,
+					"render",
+					G_CALLBACK(vid_area_render_handler),
+					app );
+
+		gtk_gl_area_make_current(gl_area);
+		opengl_ctx = gmpv_mpv_obj_get_opengl_cb_context(mpv);
+		rc = mpv_opengl_cb_init_gl(	opengl_ctx,
+						NULL,
+						get_proc_address,
+						NULL );
+
+		if(rc >= 0)
+		{
+			g_debug("Initialized opengl-cb");
+		}
+		else
+		{
+			g_critical("Failed to initialize opengl-cb");
+		}
+	}
+
+	mpv_free(current_vo);
 	load_files(app, (const gchar **)app->files);
 }
 
@@ -278,12 +348,12 @@ static void open_handler(	GApplication *gapp,
 				gchar *hint,
 				gpointer data )
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 	gint i;
 
 	if(n_files > 0)
 	{
-		MpvObjState state;
+		GmpvMpvObjState state;
 
 		app->files = g_malloc(sizeof(GFile *)*(gsize)(n_files+1));
 
@@ -294,19 +364,12 @@ static void open_handler(	GApplication *gapp,
 
 		app->files[i] = NULL;
 
-		mpv_obj_get_state(app->mpv, &state);
+		gmpv_mpv_obj_get_state(app->mpv, &state);
 
 		if(state.ready)
 		{
 			load_files(app, (const gchar **)app->files);
 		}
-		else
-		{
-			g_signal_connect(	app->mpv,
-						"mpv-init",
-						G_CALLBACK(mpv_init_handler),
-						app );
-		}
 	}
 
 	gdk_notify_startup_complete();
@@ -314,8 +377,8 @@ static void open_handler(	GApplication *gapp,
 
 static gboolean draw_handler(GtkWidget *widget, cairo_t *cr, gpointer data)
 {
-	Application *app = data;
-	guint signal_id = g_signal_lookup("draw", MAIN_WINDOW_TYPE);
+	GmpvApplication *app = data;
+	guint signal_id = g_signal_lookup("draw", GMPV_TYPE_MAIN_WINDOW);
 
 	g_signal_handlers_disconnect_matched(	widget,
 						G_SIGNAL_MATCH_ID
@@ -326,16 +389,19 @@ static gboolean draw_handler(GtkWidget *widget, cairo_t *cr, gpointer data)
 						NULL,
 						app );
 
-	app->mpv->mpv_event_handler = mpv_event_handler;
-
-	mpv_obj_initialize(app->mpv);
-	mpv_obj_set_opengl_cb_callback(app->mpv, opengl_cb_update_callback, app);
-	mpv_obj_set_wakup_callback(app->mpv, mpv_obj_wakeup_callback, app);
+	gmpv_mpv_obj_initialize(app->mpv);
+	gmpv_mpv_obj_set_opengl_cb_callback
+		(app->mpv, opengl_cb_update_callback, app);
+	gmpv_mpv_obj_set_event_callback
+		(app->mpv, mpv_event_handler, app);
 
 	if(!app->files)
 	{
-		control_box_set_enabled
-			(CONTROL_BOX(app->gui->control_box), FALSE);
+		GmpvControlBox *control_box;
+
+		control_box = gmpv_main_window_get_control_box(app->gui);
+
+		gmpv_control_box_set_enabled(control_box, FALSE);
 	}
 
 	return FALSE;
@@ -350,71 +416,47 @@ static gboolean delete_handler(	GtkWidget *widget,
 	return TRUE;
 }
 
-static void playlist_row_activated_handler(	GtkTreeView *tree_view,
-						GtkTreePath *path,
-						GtkTreeViewColumn *column,
+static void playlist_row_activated_handler(	GmpvPlaylistWidget *playlist,
+						gint64 pos,
 						gpointer data )
 {
-	Application *app = data;
-	gint *indices = gtk_tree_path_get_indices(path);
-	gint64 index = indices[0];
-	gint64 pos;
-	gint rc;
-
-	rc = mpv_obj_get_property(	app->mpv,
-					"playlist-pos",
-					MPV_FORMAT_INT64,
-					&pos );
-
-	mpv_obj_set_property_flag(app->mpv, "pause", FALSE);
-
-	if(indices && indices[0] != pos)
-	{
-		if(rc >= 0)
-		{
-			mpv_obj_set_property(	app->mpv,
-						"playlist-pos",
-						MPV_FORMAT_INT64,
-						&index );
-		}
-		else
-		{
-			app->target_playlist_pos = index;
-		}
-	}
+	set_playlist_pos(data, pos);
 }
 
-static void playlist_row_deleted_handler(	Playlist *pl,
+static void playlist_row_deleted_handler(	GmpvPlaylistWidget *playlist,
 						gint pos,
 						gpointer data )
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 
-	if(mpv_obj_is_loaded(app->mpv))
+	if(gmpv_mpv_obj_is_loaded(app->mpv))
 	{
 		const gchar *cmd[] = {"playlist_remove", NULL, NULL};
 		gchar *index_str = g_strdup_printf("%d", pos);
 
 		cmd[1] = index_str;
 
-		mpv_check_error(mpv_obj_command(app->mpv, cmd));
+		mpv_check_error(gmpv_mpv_obj_command(app->mpv, cmd));
 
 		g_free(index_str);
 	}
 
-	if(playlist_empty(app->playlist_store))
+	if(gmpv_playlist_empty(app->playlist_store))
 	{
-		control_box_set_enabled
-			(CONTROL_BOX(app->gui->control_box), FALSE);
+		GmpvControlBox *control_box;
+
+		control_box = gmpv_main_window_get_control_box(app->gui);
+
+		gmpv_control_box_set_enabled(control_box, FALSE);
 	}
 }
 
-static void playlist_row_reodered_handler(	Playlist *pl,
+static void playlist_row_reodered_handler(	GmpvPlaylistWidget *playlist,
 						gint src,
 						gint dest,
 						gpointer data )
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 	const gchar *cmd[] = {"playlist_move", NULL, NULL, NULL};
 	gchar *src_str = g_strdup_printf("%d", (src > dest)?--src:src);
 	gchar *dest_str = g_strdup_printf("%d", dest);
@@ -422,15 +464,15 @@ static void playlist_row_reodered_handler(	Playlist *pl,
 	cmd[1] = src_str;
 	cmd[2] = dest_str;
 
-	mpv_obj_command(app->mpv, cmd);
+	gmpv_mpv_obj_command(app->mpv, cmd);
 
 	g_free(src_str);
 	g_free(dest_str);
 }
 
-static Track *parse_track_list(mpv_node_list *node)
+static GmpvTrack *parse_track_list(mpv_node_list *node)
 {
-	Track *entry = track_new();
+	GmpvTrack *entry = gmpv_track_new();
 
 	for(gint i = 0; i < node->num; i++)
 	{
@@ -468,44 +510,47 @@ static Track *parse_track_list(mpv_node_list *node)
 	return entry;
 }
 
-static void update_track_list(Application *app, mpv_node* track_list)
+static void update_track_list(GmpvApplication *app, mpv_node* track_list)
 {
-	MpvObj *mpv = app->mpv;
+	const struct
+	{
+		const gchar *prop_name;
+		const gchar *action_name;
+	}
+	track_map[] = {	{"aid", "audio_select"},
+			{"vid", "video_select"},
+			{"sid", "sub_select"},
+			{NULL, NULL} };
+
+	GmpvMpvObj *mpv = app->mpv;
 	mpv_node_list *org_list = track_list->u.list;
 	GSList *audio_list = NULL;
 	GSList *video_list = NULL;
 	GSList *sub_list = NULL;
-	GAction *action = NULL;
-	gint64 aid = -1;
-	gint64 sid = -1;
-
-	mpv_get_property(	mpv->mpv_ctx,
-				"aid",
-				MPV_FORMAT_INT64,
-				&aid );
-	mpv_get_property(	mpv->mpv_ctx,
-				"sid",
-				MPV_FORMAT_INT64,
-				&sid );
-
-	action = g_action_map_lookup_action
-			(G_ACTION_MAP(app), "audio_select");
-	g_simple_action_set_state
-		(G_SIMPLE_ACTION(action), g_variant_new_int64(aid));
-
-	action = g_action_map_lookup_action
-			(G_ACTION_MAP(app), "sub_select");
-	g_simple_action_set_state
-		(G_SIMPLE_ACTION(action), g_variant_new_int64(sid));
+
+	for(gint i = 0; track_map[i].prop_name; i++)
+	{
+		GAction *action;
+		gchar *buf;
+		gint64 val;
+
+		action =	g_action_map_lookup_action
+				(G_ACTION_MAP(app), track_map[i].action_name);
+		buf =	gmpv_mpv_obj_get_property_string
+			(mpv, track_map[i].prop_name);
+		val = g_ascii_strtoll(buf, NULL, 10);
+
+		g_simple_action_set_state
+			(G_SIMPLE_ACTION(action), g_variant_new_int64(val));
+
+		mpv_free(buf);
+	}
 
 	for(gint i = 0; i < org_list->num; i++)
 	{
-		Track *entry;
+		GmpvTrack *entry = parse_track_list(org_list->values[i].u.list);
 		GSList **list;
 
-		entry = parse_track_list
-			(org_list->values[i].u.list);
-
 		if(entry->type == TRACK_TYPE_AUDIO)
 		{
 			list = &audio_list;
@@ -520,7 +565,7 @@ static void update_track_list(Application *app, mpv_node* track_list)
 		}
 		else
 		{
-			g_assert(FALSE);
+			g_assert_not_reached();
 		}
 
 		*list = g_slist_prepend(*list, entry);
@@ -530,43 +575,37 @@ static void update_track_list(Application *app, mpv_node* track_list)
 	video_list = g_slist_reverse(video_list);
 	sub_list = g_slist_reverse(sub_list);
 
-	main_window_update_track_list
+	gmpv_main_window_update_track_list
 		(app->gui, audio_list, video_list, sub_list);
 
-	g_slist_free_full(audio_list, (GDestroyNotify)track_free);
-	g_slist_free_full(video_list, (GDestroyNotify)track_free);
-	g_slist_free_full(sub_list, (GDestroyNotify)track_free);
+	g_slist_free_full(audio_list, (GDestroyNotify)gmpv_track_free);
+	g_slist_free_full(video_list, (GDestroyNotify)gmpv_track_free);
+	g_slist_free_full(sub_list, (GDestroyNotify)gmpv_track_free);
 }
 
 static void mpv_prop_change_handler(mpv_event_property *prop, gpointer data)
 {
-	Application *app = data;
-	MpvObj *mpv = app->mpv;
-	ControlBox *control_box = CONTROL_BOX(app->gui->control_box);
-	MpvObjState state;
+	GmpvApplication *app = data;
+	GmpvMpvObj *mpv;
+	GmpvControlBox *control_box;
+	GmpvMpvObjState state;
 
-	mpv_obj_get_state(mpv, &state);
+	mpv = app->mpv;
+	control_box = gmpv_main_window_get_control_box(app->gui);
+
+	gmpv_mpv_obj_get_state(mpv, &state);
 
 	if(g_strcmp0(prop->name, "pause") == 0)
 	{
 		gboolean paused = prop->data?*((gboolean *)prop->data):TRUE;
 
-		control_box_set_playing_state(control_box, !paused);
+		gmpv_control_box_set_playing_state(control_box, !paused);
+	}
+	else if(g_strcmp0(prop->name, "core-idle") == 0)
+	{
+		gboolean idle = prop->data?*((gboolean *)prop->data):TRUE;
 
-		if(!paused)
-		{
-			app->inhibit_cookie
-				= gtk_application_inhibit
-					(	GTK_APPLICATION(app),
-						GTK_WINDOW(app->gui),
-						GTK_APPLICATION_INHIBIT_IDLE,
-						_("Playing") );
-		}
-		else if(app->inhibit_cookie != 0)
-		{
-			gtk_application_uninhibit
-				(GTK_APPLICATION(app), app->inhibit_cookie);
-		}
+		set_inhibit_idle(app, !idle);
 	}
 	else if(g_strcmp0(prop->name, "track-list") == 0 && prop->data)
 	{
@@ -577,18 +616,18 @@ static void mpv_prop_change_handler(mpv_event_property *prop, gpointer data)
 	{
 		gdouble volume = prop->data?*((double *)prop->data)/100.0:0;
 
-		control_box_set_volume(control_box, volume);
+		gmpv_control_box_set_volume(control_box, volume);
 	}
 	else if(g_strcmp0(prop->name, "aid") == 0)
 	{
 		/* prop->data == NULL iff there is no audio track */
-		control_box_set_volume_enabled(control_box, !!prop->data);
+		gmpv_control_box_set_volume_enabled(control_box, !!prop->data);
 	}
 	else if(g_strcmp0(prop->name, "length") == 0 && prop->data)
 	{
 		gdouble length = *((gdouble *) prop->data);
 
-		control_box_set_seek_bar_length(control_box, (gint)length);
+		gmpv_control_box_set_seek_bar_length(control_box, (gint)length);
 	}
 	else if(g_strcmp0(prop->name, "media-title") == 0 && prop->data)
 	{
@@ -598,31 +637,34 @@ static void mpv_prop_change_handler(mpv_event_property *prop, gpointer data)
 	}
 	else if(g_strcmp0(prop->name, "playlist-pos") == 0 && prop->data)
 	{
+		GmpvPlaylist *playlist = gmpv_mpv_obj_get_playlist(mpv);
 		gint64 pos = *((gint64 *)prop->data);
 
-		playlist_set_indicator_pos(mpv->playlist, (gint)pos);
+		gmpv_playlist_set_indicator_pos(playlist, (gint)pos);
 	}
 	else if(g_strcmp0(prop->name, "chapters") == 0 && prop->data)
 	{
 		gint64 count = *((gint64 *) prop->data);
 
-		control_box_set_chapter_enabled(control_box, (count > 1));
+		gmpv_control_box_set_chapter_enabled(control_box, (count > 1));
 	}
 }
 
 static void mpv_event_handler(mpv_event *event, gpointer data)
 {
-	Application *app = data;
-	MpvObj *mpv = app->mpv;
-	MpvObjState state;
+	GmpvApplication *app = data;
+	GmpvMpvObj *mpv = app->mpv;
+	GmpvMpvObjState state;
 
-	mpv_obj_get_state(mpv, &state);
+	gmpv_mpv_obj_get_state(mpv, &state);
 
 	if(event->event_id == MPV_EVENT_VIDEO_RECONFIG)
 	{
-		if(state.new_file && app->mpv->autofit_ratio > 0)
+		gdouble autofit_ratio = gmpv_mpv_obj_get_autofit_ratio(app->mpv);
+
+		if(state.new_file && autofit_ratio > 0)
 		{
-			resize_window_to_fit(app, mpv->autofit_ratio);
+			resize_window_to_fit(app, autofit_ratio);
 		}
 	}
 	else if(event->event_id == MPV_EVENT_PROPERTY_CHANGE)
@@ -634,38 +676,46 @@ static void mpv_event_handler(mpv_event *event, gpointer data)
 	}
 	else if(event->event_id == MPV_EVENT_FILE_LOADED)
 	{
-		ControlBox *control_box = CONTROL_BOX(app->gui->control_box);
-		gint64 aid = -1;
+		GmpvControlBox *control_box;
+		GmpvPlaylist *playlist;
+		gchar *title;
+		gchar *aid_str;
+		gint64 aid;
 		gint64 pos = -1;
 		gdouble length = 0;
-		gchar *title = NULL;
+
+		control_box = gmpv_main_window_get_control_box(app->gui);
+		playlist = gmpv_mpv_obj_get_playlist(mpv);
 
 		if(app->target_playlist_pos != -1)
 		{
-			mpv_obj_set_property(	app->mpv,
-						"playlist-pos",
-						MPV_FORMAT_INT64,
-						&app->target_playlist_pos );
+			gmpv_mpv_obj_set_property
+				(	mpv,
+					"playlist-pos",
+					MPV_FORMAT_INT64,
+					&app->target_playlist_pos );
 
 			app->target_playlist_pos = -1;
 		}
 
-		mpv_obj_get_property
-			(mpv, "aid", MPV_FORMAT_INT64, &aid);
-		mpv_obj_get_property
+		gmpv_mpv_obj_get_property
 			(mpv, "playlist-pos", MPV_FORMAT_INT64, &pos);
-		mpv_obj_get_property
+		gmpv_mpv_obj_get_property
 			(mpv, "length", MPV_FORMAT_DOUBLE, &length);
 
-		title = mpv_obj_get_property_string(mpv, "media-title");
+		aid_str = gmpv_mpv_obj_get_property_string(mpv, "aid");
+		aid = g_ascii_strtoll(aid_str, NULL, 10);
 
-		control_box_set_enabled(control_box, TRUE);
-		control_box_set_volume_enabled(control_box, (aid != -1));
-		control_box_set_playing_state(control_box, !state.paused);
-		playlist_set_indicator_pos(mpv->playlist, (gint)pos);
-		control_box_set_seek_bar_length(control_box, (gint)length);
+		title = gmpv_mpv_obj_get_property_string(mpv, "media-title");
+
+		gmpv_control_box_set_enabled(control_box, TRUE);
+		gmpv_control_box_set_volume_enabled(control_box, (aid > 0));
+		gmpv_control_box_set_playing_state(control_box, !state.paused);
+		gmpv_playlist_set_indicator_pos(playlist, (gint)pos);
+		gmpv_control_box_set_seek_bar_length(control_box, (gint)length);
 		gtk_window_set_title(GTK_WINDOW(app->gui), title);
 
+		mpv_free(aid_str);
 		mpv_free(title);
 	}
 	else if(event->event_id == MPV_EVENT_CLIENT_MESSAGE)
@@ -700,7 +750,8 @@ static void mpv_event_handler(mpv_event *event, gpointer data)
 	{
 		if(!state.init_load && !state.loaded)
 		{
-			main_window_reset(app->gui);
+			gmpv_main_window_reset(app->gui);
+			set_inhibit_idle(app, FALSE);
 		}
 	}
 	else if(event->event_id == MPV_EVENT_SHUTDOWN)
@@ -709,11 +760,11 @@ static void mpv_event_handler(mpv_event *event, gpointer data)
 	}
 }
 
-static void mpv_error_handler(MpvObj *mpv, const gchar *err, gpointer data)
+static void mpv_error_handler(GmpvMpvObj *mpv, const gchar *err, gpointer data)
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 
-	main_window_reset(app->gui);
+	gmpv_main_window_reset(app->gui);
 	show_error_dialog(app, NULL, err);
 }
 
@@ -726,31 +777,42 @@ static void drag_data_handler(	GtkWidget *widget,
 				guint time,
 				gpointer data)
 {
-	Application *app = data;
-	PlaylistWidget *playlist = PLAYLIST_WIDGET(app->gui->playlist);
-	gchar **uri_list = NULL;
-	gboolean append = (widget == GTK_WIDGET(playlist));
+	GmpvApplication *app = data;
+	gchar *type = gdk_atom_name(gtk_selection_data_get_target(sel_data));
+	const guchar *raw_data = gtk_selection_data_get_data(sel_data);
+	gchar **uri_list = gtk_selection_data_get_uris(sel_data);
+	gboolean append = GMPV_IS_PLAYLIST_WIDGET(widget);
 
-	if(sel_data && gtk_selection_data_get_length(sel_data) > 0)
+	if(g_strcmp0(type, "PLAYLIST_PATH") == 0)
 	{
-		uri_list = gtk_selection_data_get_uris(sel_data);
-	}
+		GtkTreePath *path =	gtk_tree_path_new_from_string
+					((const gchar *)raw_data);
 
-	if(uri_list)
-	{
-		mpv_obj_load_list(	app->mpv,
-					(const gchar **)uri_list,
-					append,
-					TRUE );
+		g_assert(path);
+		set_playlist_pos(app, gtk_tree_path_get_indices(path)[0]);
 
-		g_strfreev(uri_list);
+		gtk_tree_path_free(path);
 	}
 	else
 	{
-		const guchar *raw_data = gtk_selection_data_get_data(sel_data);
-
-		mpv_obj_load(app->mpv, (const gchar *)raw_data, append, TRUE);
+		if(uri_list)
+		{
+			gmpv_mpv_obj_load_list(	app->mpv,
+						(const gchar **)uri_list,
+						append,
+						TRUE );
+		}
+		else
+		{
+			gmpv_mpv_obj_load(	app->mpv,
+						(const gchar *)raw_data,
+						append,
+						TRUE );
+		}
 	}
+
+	g_strfreev(uri_list);
+	g_free(type);
 }
 
 static gchar *get_full_keystr(guint keyval, guint state)
@@ -805,7 +867,7 @@ static gboolean key_press_handler(	GtkWidget *widget,
 					gpointer data )
 {
 	const gchar *cmd[] = {"keydown", NULL, NULL};
-	Application *app = data;
+	GmpvApplication *app = data;
 	guint keyval = ((GdkEventKey*)event)->keyval;
 	guint state = ((GdkEventKey*)event)->state;
 	gchar *keystr = NULL;
@@ -815,7 +877,7 @@ static gboolean key_press_handler(	GtkWidget *widget,
 	if(keystr)
 	{
 		g_debug("Sent '%s' key down to mpv", keystr);
-		mpv_obj_command(app->mpv, cmd);
+		gmpv_mpv_obj_command(app->mpv, cmd);
 
 		g_free(keystr);
 	}
@@ -827,7 +889,7 @@ static gboolean key_release_handler(	GtkWidget *widget,
 					GdkEvent *event,
 					gpointer data )
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 	guint keyval = ((GdkEventKey*)event)->keyval;
 	guint state = ((GdkEventKey*)event)->state;
 	gchar *keystr = NULL;
@@ -838,7 +900,7 @@ static gboolean key_release_handler(	GtkWidget *widget,
 	if(keystr)
 	{
 		g_debug("Sent '%s' key up to mpv", keystr);
-		mpv_obj_command(app->mpv, cmd);
+		gmpv_mpv_obj_command(app->mpv, cmd);
 
 		g_free(keystr);
 	}
@@ -850,7 +912,7 @@ static gboolean mouse_press_handler(	GtkWidget *widget,
 					GdkEvent *event,
 					gpointer data )
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 	GdkEventButton *btn_event = (GdkEventButton *)event;
 	gchar *x_str = g_strdup_printf("%d", (gint)btn_event->x);
 	gchar *y_str = g_strdup_printf("%d", (gint)btn_event->y);
@@ -863,7 +925,7 @@ static gboolean mouse_press_handler(	GtkWidget *widget,
 	g_debug(	"Sent %s button %s click at %sx%s to mpv",
 			type_str, btn_str, x_str, y_str );
 
-	mpv_obj_command(app->mpv, cmd);
+	gmpv_mpv_obj_command(app->mpv, cmd);
 
 	g_free(x_str);
 	g_free(y_str);
@@ -872,78 +934,114 @@ static gboolean mouse_press_handler(	GtkWidget *widget,
 	return TRUE;
 }
 
+static gboolean queue_render(GtkGLArea *area)
+{
+	gtk_gl_area_queue_render(area);
+
+	return FALSE;
+}
+
 static void opengl_cb_update_callback(void *cb_ctx)
 {
-	Application *app = cb_ctx;
+	GmpvApplication *app = cb_ctx;
+	GtkGLArea *area =	gmpv_video_area_get_gl_area
+				(gmpv_main_window_get_video_area(app->gui));
+
+	g_idle_add_full(	G_PRIORITY_HIGH,
+				(GSourceFunc)queue_render,
+				area,
+				NULL );
+}
+
+static void set_playlist_pos(GmpvApplication *app, gint64 pos)
+{
+	gint64 mpv_pos;
+	gint rc;
+
+	rc = gmpv_mpv_obj_get_property(	app->mpv,
+					"playlist-pos",
+					MPV_FORMAT_INT64,
+					&mpv_pos );
 
-	if(app->mpv->opengl_ctx)
+	gmpv_mpv_obj_set_property_flag(app->mpv, "pause", FALSE);
+
+	if(pos != mpv_pos)
 	{
-		gtk_gl_area_queue_render(GTK_GL_AREA(app->gui->vid_area));
+		if(rc >= 0)
+		{
+			gmpv_mpv_obj_set_property(	app->mpv,
+							"playlist-pos",
+							MPV_FORMAT_INT64,
+							&pos );
+		}
+		else
+		{
+			app->target_playlist_pos = pos;
+		}
 	}
 }
 
-static gboolean get_use_opengl(void)
+static void set_inhibit_idle(GmpvApplication *app, gboolean inhibit)
 {
-	/* TODO: Add option to use opengl on X11 */
-	return	g_getenv("FORCE_OPENGL_CB") ||
-		!GDK_IS_X11_DISPLAY(gdk_display_get_default()) ;
-}
+	if(inhibit && app->inhibit_cookie == 0)
+	{
+		app->inhibit_cookie
+			= gtk_application_inhibit
+				(	GTK_APPLICATION(app),
+					GTK_WINDOW(app->gui),
+					GTK_APPLICATION_INHIBIT_IDLE,
+					_("Playing") );
+	}
+	else if(!inhibit && app->inhibit_cookie != 0)
+	{
+		gtk_application_uninhibit
+			(GTK_APPLICATION(app), app->inhibit_cookie);
 
-static gint64 get_xid(GtkWidget *widget)
-{
-#ifdef GDK_WINDOWING_X11
-	return (gint64)gdk_x11_window_get_xid(gtk_widget_get_window(widget));
-#else
-	return -1;
-#endif
+		app->inhibit_cookie = 0;
+	}
 }
 
-static gboolean load_files(Application *app, const gchar **files)
+static gboolean load_files(GmpvApplication *app, const gchar **files)
 {
-	MpvObjState state;
+	GmpvMpvObjState state;
 
-	mpv_obj_get_state(app->mpv, &state);
+	gmpv_mpv_obj_get_state(app->mpv, &state);
 
 	if(files)
 	{
-		mpv_obj_load_list(app->mpv, files, FALSE, TRUE);
+		gmpv_mpv_obj_load_list(app->mpv, files, FALSE, TRUE);
 
 		g_strfreev(app->files);
+
+		app->files = NULL;
 	}
 
 	return FALSE;
 }
 
-static void connect_signals(Application *app)
+static void connect_signals(GmpvApplication *app)
 {
-	PlaylistWidget *playlist = PLAYLIST_WIDGET(app->gui->playlist);
+	GmpvPlaylistWidget *playlist;
+	GmpvVideoArea *video_area;
 
-	playbackctl_connect_signals(app);
+	playlist = gmpv_main_window_get_playlist(app->gui);
+	video_area = gmpv_main_window_get_video_area(app->gui);
 
-	if(main_window_get_use_opengl(app->gui))
-	{
-		g_signal_connect(	app->gui->vid_area,
-					"render",
-					G_CALLBACK(vid_area_render_handler),
-					app );
-		g_signal_connect(	app->gui,
-					"draw",
-					G_CALLBACK(draw_handler),
-					app );
-	}
-	else
-	{
-		g_signal_connect_after(	app->gui,
-					"draw",
-					G_CALLBACK(draw_handler),
-					app );
-	}
+	gmpv_playbackctl_connect_signals(app);
 
-	g_signal_connect(	app->gui->vid_area,
+	g_signal_connect_after(	app->gui,
+				"draw",
+				G_CALLBACK(draw_handler),
+				app );
+	g_signal_connect(	app->mpv,
+				"mpv-init",
+				G_CALLBACK(mpv_init_handler),
+				app );
+	g_signal_connect(	video_area,
 				"drag-data-received",
 				G_CALLBACK(drag_data_handler),
 				app );
-	g_signal_connect(	app->gui->playlist,
+	g_signal_connect(	playlist,
 				"drag-data-received",
 				G_CALLBACK(drag_data_handler),
 				app );
@@ -959,19 +1057,19 @@ static void connect_signals(Application *app)
 				"key-release-event",
 				G_CALLBACK(key_release_handler),
 				app );
-	g_signal_connect(	app->gui->vid_area,
+	g_signal_connect(	video_area,
 				"button-press-event",
 				G_CALLBACK(mouse_press_handler),
 				app );
-	g_signal_connect(	playlist->tree_view,
+	g_signal_connect(	playlist,
 				"row-activated",
 				G_CALLBACK(playlist_row_activated_handler),
 				app );
-	g_signal_connect(	playlist->store,
+	g_signal_connect(	playlist,
 				"row-deleted",
 				G_CALLBACK(playlist_row_deleted_handler),
 				app );
-	g_signal_connect(	playlist->store,
+	g_signal_connect(	playlist,
 				"row-reordered",
 				G_CALLBACK(playlist_row_reodered_handler),
 				app );
@@ -990,7 +1088,7 @@ static inline void add_accelerator(	GtkApplication *app,
 	gtk_application_set_accels_for_action(app, action, accels);
 }
 
-static void setup_accelerators(Application *app)
+static void setup_accelerators(GmpvApplication *app)
 {
 	GtkApplication *gtk_app = GTK_APPLICATION(app);
 
@@ -1008,20 +1106,30 @@ static void setup_accelerators(Application *app)
 }
 
 
-static void application_class_init(ApplicationClass *klass)
+static void gmpv_application_class_init(GmpvApplicationClass *klass)
 {
 }
 
-static void application_init(Application *app)
+static void gmpv_application_init(GmpvApplication *app)
 {
 	g_signal_connect(app, "startup", G_CALLBACK(startup_handler), app);
 	g_signal_connect(app, "activate", G_CALLBACK(activate_handler), app);
 	g_signal_connect(app, "open", G_CALLBACK(open_handler), app);
 }
 
-Application *application_new(gchar *id, GApplicationFlags flags)
+GmpvMainWindow *gmpv_application_get_main_window(GmpvApplication *app)
+{
+	return app->gui;
+}
+
+GmpvMpvObj *gmpv_application_get_mpv_obj(GmpvApplication *app)
+{
+	return app->mpv;
+}
+
+GmpvApplication *gmpv_application_new(gchar *id, GApplicationFlags flags)
 {
-	return APPLICATION(g_object_new(	application_get_type(),
+	return GMPV_APPLICATION(g_object_new(	gmpv_application_get_type(),
 						"application-id", id,
 						"flags", flags,
 						NULL ));
diff --git a/src/mpv_opt.h b/src/gmpv_application.h
similarity index 57%
copy from src/mpv_opt.h
copy to src/gmpv_application.h
index 93e6920..75c1fa3 100644
--- a/src/mpv_opt.h
+++ b/src/gmpv_application.h
@@ -17,22 +17,27 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef MPV_OPT_H
-#define MPV_OPT_H
+#ifndef APPLICATION_H
+#define APPLICATION_H
 
+#include <gtk/gtk.h>
 #include <mpv/client.h>
+#include <mpv/opengl_cb.h>
 
-#include "mpv_obj.h"
+#include "gmpv_main_window.h"
+#include "gmpv_playlist.h"
+#include "gmpv_mpv_obj.h"
 
-typedef struct module_log_level module_log_level;
+G_BEGIN_DECLS
 
-struct module_log_level
-{
-	gchar *prefix;
-	mpv_log_level level;
-};
+#define GMPV_TYPE_APPLICATION (gmpv_application_get_type())
 
-void mpv_opt_handle_autofit(MpvObj *mpv);
-void mpv_opt_handle_msg_level(MpvObj *mpv);
+G_DECLARE_FINAL_TYPE(GmpvApplication, gmpv_application, GMPV, APPLICATION, GtkApplication)
+
+GmpvApplication *gmpv_application_new(gchar *id, GApplicationFlags flags);
+GmpvMainWindow *gmpv_application_get_main_window(GmpvApplication *app);
+GmpvMpvObj *gmpv_application_get_mpv_obj(GmpvApplication *app);
+
+G_END_DECLS
 
 #endif
diff --git a/src/common.c b/src/gmpv_common.c
similarity index 66%
rename from src/common.c
rename to src/gmpv_common.c
index 3f93862..733e73c 100644
--- a/src/common.c
+++ b/src/gmpv_common.c
@@ -21,12 +21,13 @@
 #include <glib/gi18n.h>
 #include <string.h>
 
-#include "common.h"
-#include "def.h"
-#include "mpv_obj.h"
-#include "main_window.h"
-#include "control_box.h"
-#include "playlist_widget.h"
+#include "gmpv_common.h"
+#include "gmpv_def.h"
+#include "gmpv_mpv_obj.h"
+#include "gmpv_main_window.h"
+#include "gmpv_video_area.h"
+#include "gmpv_control_box.h"
+#include "gmpv_playlist_widget.h"
 
 gchar *get_config_dir_path(void)
 {
@@ -73,19 +74,30 @@ gchar *get_name_from_path(const gchar *path)
 gboolean quit(gpointer data)
 {
 	const gchar *cmd[] = {"quit", NULL};
-	Application *app = data;
+	GmpvApplication *app = data;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(app);
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(app);
 
-	if(app->mpv->mpv_ctx)
+	if(gmpv_mpv_obj_get_mpv_handle(mpv))
 	{
-		mpv_obj_command(app->mpv, cmd);
-		mpv_obj_quit(app->mpv);
+		GmpvVideoArea *vid_area = gmpv_main_window_get_video_area(wnd);
+		GtkGLArea *gl_area = gmpv_video_area_get_gl_area(vid_area);
 
-		app->mpv->mpv_ctx = NULL;
+		if(gtk_widget_get_realized(GTK_WIDGET(gl_area)))
+		{
+			/* Needed by gmpv_mpv_obj_quit() to uninitialize
+			 * opengl-cb
+			 */
+			gtk_gl_area_make_current(GTK_GL_AREA(gl_area));
+		}
+
+		gmpv_mpv_obj_command(mpv, cmd);
+		gmpv_mpv_obj_quit(mpv);
 	}
 
-	if(!app->gui->fullscreen)
+	if(!gmpv_main_window_get_fullscreen(wnd))
 	{
-		main_window_save_state(app->gui);
+		gmpv_main_window_save_state(wnd);
 	}
 
 	g_application_quit(G_APPLICATION(app));
@@ -93,7 +105,7 @@ gboolean quit(gpointer data)
 	return FALSE;
 }
 
-void activate_action_string(Application *app, const gchar *str)
+void activate_action_string(GmpvApplication *app, const gchar *str)
 {
 	GActionMap *map = G_ACTION_MAP(app);
 	GAction *action = NULL;
@@ -127,7 +139,7 @@ void activate_action_string(Application *app, const gchar *str)
 	}
 }
 
-void migrate_config(Application *app)
+void migrate_config(GmpvApplication *app)
 {
 	const gchar *keys[] = {	"dark-theme-enable",
 				"csd-enable",
@@ -167,34 +179,45 @@ void migrate_config(Application *app)
 
 gboolean update_seek_bar(gpointer data)
 {
-	Application *app = data;
+	GmpvApplication *app = data;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(app);
+	mpv_handle *mpv_ctx = gmpv_mpv_obj_get_mpv_handle(mpv);
+	GmpvMpvObjState state;
 	gdouble time_pos = -1;
 	gint rc = -1;
 
-	if(app->mpv->mpv_ctx)
+	gmpv_mpv_obj_get_state(mpv, &state);
+
+	if(state.loaded)
 	{
-		rc = mpv_get_property(	app->mpv->mpv_ctx,
-					"time-pos",
-					MPV_FORMAT_DOUBLE,
-					&time_pos );
+		rc = gmpv_mpv_obj_get_property(	mpv,
+						"time-pos",
+						MPV_FORMAT_DOUBLE,
+						&time_pos );
 	}
 
 	if(rc >= 0)
 	{
-		control_box_set_seek_bar_pos
-			(CONTROL_BOX(app->gui->control_box), time_pos);
+		GmpvMainWindow *wnd;
+		GmpvControlBox *control_box;
+
+		wnd = gmpv_application_get_main_window(app);
+		control_box = gmpv_main_window_get_control_box(wnd);
+
+		gmpv_control_box_set_seek_bar_pos(control_box, time_pos);
 	}
 
-	return !!app->mpv->mpv_ctx;
+	return !!mpv_ctx;
 }
 
-void seek(Application *app, gdouble time)
+void seek(GmpvApplication *app, gdouble time)
 {
 	const gchar *cmd[] = {"seek", NULL, "absolute", NULL};
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(app);
 
-	if(!mpv_obj_is_loaded(app->mpv))
+	if(!gmpv_mpv_obj_is_loaded(mpv))
 	{
-		mpv_obj_load(app->mpv, NULL, FALSE, TRUE);
+		gmpv_mpv_obj_load(mpv, NULL, FALSE, TRUE);
 	}
 	else
 	{
@@ -202,7 +225,7 @@ void seek(Application *app, gdouble time)
 
 		cmd[1] = value_str;
 
-		mpv_obj_command(app->mpv, cmd);
+		gmpv_mpv_obj_command(mpv, cmd);
 		update_seek_bar(app);
 
 		g_free(value_str);
@@ -210,22 +233,22 @@ void seek(Application *app, gdouble time)
 
 }
 
-void show_error_dialog(Application *app, const gchar *prefix, const gchar *msg)
+void show_error_dialog(GmpvApplication *app, const gchar *prefix, const gchar *msg)
 {
+	GmpvMainWindow *wnd;
 	GtkWidget *dialog;
 	GtkWidget *msg_area;
 	GList *iter;
 
-	dialog = gtk_message_dialog_new
-			(	GTK_WINDOW(app->gui),
+	wnd = gmpv_application_get_main_window(app);
+	dialog =	gtk_message_dialog_new
+			(	GTK_WINDOW(wnd),
 				GTK_DIALOG_DESTROY_WITH_PARENT,
 				GTK_MESSAGE_ERROR,
 				GTK_BUTTONS_OK,
 				_("Error") );
-
-	msg_area = gtk_message_dialog_get_message_area
+	msg_area =	gtk_message_dialog_get_message_area
 			(GTK_MESSAGE_DIALOG(dialog));
-
 	iter = gtk_container_get_children(GTK_CONTAINER(msg_area));
 
 	while(iter)
@@ -267,38 +290,40 @@ void show_error_dialog(Application *app, const gchar *prefix, const gchar *msg)
 	gtk_widget_destroy(dialog);
 }
 
-void resize_window_to_fit(Application *app, gdouble multiplier)
+void resize_window_to_fit(GmpvApplication *app, gdouble multiplier)
 {
-	gchar *video = mpv_get_property_string(app->mpv->mpv_ctx, "video");
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(app);
+	gchar *video = gmpv_mpv_obj_get_property_string(mpv, "video");
 	gint64 width;
 	gint64 height;
 	gint mpv_width_rc;
 	gint mpv_height_rc;
 
-	mpv_width_rc = mpv_get_property(	app->mpv->mpv_ctx,
-						"dwidth",
-						MPV_FORMAT_INT64,
-						&width );
-
-	mpv_height_rc = mpv_get_property(	app->mpv->mpv_ctx,
-						"dheight",
-						MPV_FORMAT_INT64,
-						&height );
+	mpv_width_rc = gmpv_mpv_obj_get_property(	mpv,
+							"dwidth",
+							MPV_FORMAT_INT64,
+							&width );
+	mpv_height_rc = gmpv_mpv_obj_get_property(	mpv,
+							"dheight",
+							MPV_FORMAT_INT64,
+							&height );
 
 	if(video
 	&& strncmp(video, "no", 3) != 0
 	&& mpv_width_rc >= 0
 	&& mpv_height_rc >= 0)
 	{
+		GmpvMainWindow *wnd;
 		gint new_width;
 		gint new_height;
 
+		wnd = gmpv_application_get_main_window(app);
 		new_width = (gint)(multiplier*(gdouble)width);
 		new_height = (gint)(multiplier*(gdouble)height);
 
 		g_debug("Resizing window to %dx%d", new_width, new_height);
 
-		main_window_resize_video_area(app->gui, new_width, new_height);
+		gmpv_main_window_resize_video_area(wnd, new_width, new_height);
 	}
 
 	mpv_free(video);
diff --git a/src/common.h b/src/gmpv_common.h
similarity index 71%
rename from src/common.h
rename to src/gmpv_common.h
index 026a3e7..8e56a93 100644
--- a/src/common.h
+++ b/src/gmpv_common.h
@@ -23,8 +23,10 @@
 #include <mpv/client.h>
 #include <mpv/opengl_cb.h>
 
-#include "playlist.h"
-#include "application.h"
+#include "gmpv_playlist.h"
+#include "gmpv_application.h"
+
+G_BEGIN_DECLS
 
 gchar *get_config_dir_path(void);
 gchar *get_scripts_dir_path(void);
@@ -32,13 +34,15 @@ gchar *get_path_from_uri(const gchar *uri);
 gchar *get_name_from_path(const gchar *path);
 gboolean quit(gpointer data);
 gboolean update_seek_bar(gpointer data);
-void activate_action_string(Application *app, const gchar *str);
-void migrate_config(Application *app);
-void seek(Application *app, gdouble time);
-void show_error_dialog(Application *app, const gchar *prefix, const gchar *msg);
-void resize_window_to_fit(Application *app, gdouble multiplier);
-void load_keybind(	Application *app,
+void activate_action_string(GmpvApplication *app, const gchar *str);
+void migrate_config(GmpvApplication *app);
+void seek(GmpvApplication *app, gdouble time);
+void show_error_dialog(GmpvApplication *app, const gchar *prefix, const gchar *msg);
+void resize_window_to_fit(GmpvApplication *app, gdouble multiplier);
+void load_keybind(	GmpvApplication *app,
 			const gchar *config_path,
 			gboolean notify_ignore );
 
+G_END_DECLS
+
 #endif
diff --git a/src/control_box.c b/src/gmpv_control_box.c
similarity index 87%
rename from src/control_box.c
rename to src/gmpv_control_box.c
index a532551..de82f62 100644
--- a/src/control_box.c
+++ b/src/gmpv_control_box.c
@@ -19,9 +19,9 @@
 
 #include <glib/gi18n.h>
 
-#include "control_box.h"
+#include "gmpv_control_box.h"
 
-struct _ControlBox
+struct _GmpvControlBox
 {
 	GtkBox parent_instance;
 	gint seek_bar_length;
@@ -36,7 +36,7 @@ struct _ControlBox
 	GtkWidget *seek_bar;
 };
 
-struct _ControlBoxClass
+struct _GmpvControlBoxClass
 {
 	GtkBoxClass parent_class;
 };
@@ -53,14 +53,14 @@ static void volume_changed_handler(	GtkVolumeButton *button,
 					gpointer data );
 static void simple_signal_handler(GtkWidget *widget, gpointer data);
 
-G_DEFINE_TYPE(ControlBox, control_box, GTK_TYPE_BOX)
+G_DEFINE_TYPE(GmpvControlBox, gmpv_control_box, GTK_TYPE_BOX)
 
 static gchar *seek_bar_format_handler(	GtkScale *scale,
 					gdouble value,
 					gpointer data )
 {
 	gint sec = (gint)value;
-	gint length = CONTROL_BOX(data)->seek_bar_length;
+	gint length = GMPV_CONTROL_BOX(data)->seek_bar_length;
 	char *output = NULL;
 
 	/* Longer than one hour */
@@ -109,7 +109,7 @@ static void volume_changed_handler(	GtkVolumeButton *button,
 
 static void simple_signal_handler(GtkWidget *widget, gpointer data)
 {
-	ControlBox *box = data;
+	GmpvControlBox *box = data;
 	gint i;
 
 	const struct
@@ -135,7 +135,7 @@ static void simple_signal_handler(GtkWidget *widget, gpointer data)
 	}
 }
 
-static void control_box_class_init(ControlBoxClass *klass)
+static void gmpv_control_box_class_init(GmpvControlBoxClass *klass)
 {
 	/* Names of signals that have no parameter and return nothing */
 	const gchar *simple_signals[] = {	"play-button-clicked",
@@ -183,7 +183,7 @@ static void control_box_class_init(ControlBoxClass *klass)
 			G_TYPE_DOUBLE );
 }
 
-static void control_box_init(ControlBox *box)
+static void gmpv_control_box_init(GmpvControlBox *box)
 {
 	GtkWidget *play_icon;
 	GtkWidget *stop_icon;
@@ -336,12 +336,12 @@ static void control_box_init(ControlBox *box)
 				box );
 }
 
-GtkWidget *control_box_new(void)
+GtkWidget *gmpv_control_box_new(void)
 {
-	return GTK_WIDGET(g_object_new(control_box_get_type(), NULL));
+	return GTK_WIDGET(g_object_new(gmpv_control_box_get_type(), NULL));
 }
 
-void control_box_set_enabled(ControlBox *box, gboolean enabled)
+void gmpv_control_box_set_enabled(GmpvControlBox *box, gboolean enabled)
 {
 	gtk_widget_set_sensitive(box->previous_button, enabled);
 	gtk_widget_set_sensitive(box->rewind_button, enabled);
@@ -351,7 +351,7 @@ void control_box_set_enabled(ControlBox *box, gboolean enabled)
 	gtk_widget_set_sensitive(box->next_button, enabled);
 }
 
-void control_box_set_chapter_enabled(ControlBox *box, gboolean enabled)
+void gmpv_control_box_set_chapter_enabled(GmpvControlBox *box, gboolean enabled)
 {
 	if(enabled)
 	{
@@ -365,24 +365,24 @@ void control_box_set_chapter_enabled(ControlBox *box, gboolean enabled)
 	}
 }
 
-void control_box_set_volume_enabled(ControlBox *box, gboolean enabled)
+void gmpv_control_box_set_volume_enabled(GmpvControlBox *box, gboolean enabled)
 {
 	gtk_widget_set_sensitive(box->volume_button, enabled);
 }
 
-void control_box_set_seek_bar_pos(ControlBox *box, gdouble pos)
+void gmpv_control_box_set_seek_bar_pos(GmpvControlBox *box, gdouble pos)
 {
 	gtk_range_set_value(GTK_RANGE(box->seek_bar), pos);
 }
 
-void control_box_set_seek_bar_length(ControlBox *box, gint length)
+void gmpv_control_box_set_seek_bar_length(GmpvControlBox *box, gint length)
 {
 	box->seek_bar_length = length;
 
 	gtk_range_set_range(GTK_RANGE(box->seek_bar), 0, length);
 }
 
-void control_box_set_volume(ControlBox *box, gdouble volume)
+void gmpv_control_box_set_volume(GmpvControlBox *box, gdouble volume)
 {
 	g_signal_handlers_block_by_func(box, volume_changed_handler, box);
 
@@ -392,19 +392,19 @@ void control_box_set_volume(ControlBox *box, gdouble volume)
 	g_signal_handlers_unblock_by_func(box, volume_changed_handler, box);
 }
 
-gdouble control_box_get_volume(ControlBox *box)
+gdouble gmpv_control_box_get_volume(GmpvControlBox *box)
 {
 	return gtk_scale_button_get_value(GTK_SCALE_BUTTON(box->volume_button));
 }
 
-gboolean control_box_get_volume_popup_visible(ControlBox *box)
+gboolean gmpv_control_box_get_volume_popup_visible(GmpvControlBox *box)
 {
 	GtkScaleButton *volume_button = GTK_SCALE_BUTTON(box->volume_button);
 
 	return gtk_widget_is_visible(gtk_scale_button_get_popup(volume_button));
 }
 
-void control_box_set_playing_state(ControlBox *box, gboolean playing)
+void gmpv_control_box_set_playing_state(GmpvControlBox *box, gboolean playing)
 {
 	GtkWidget *play_icon;
 	const gchar *tooltip;
@@ -420,7 +420,8 @@ void control_box_set_playing_state(ControlBox *box, gboolean playing)
 	gtk_widget_set_tooltip_text(box->play_button, tooltip);
 }
 
-void control_box_set_fullscreen_state(ControlBox *box, gboolean fullscreen)
+void gmpv_control_box_set_fullscreen_state(	GmpvControlBox *box,
+						gboolean fullscreen )
 {
 	GtkWidget *fullscreen_icon;
 
@@ -434,16 +435,17 @@ void control_box_set_fullscreen_state(ControlBox *box, gboolean fullscreen)
 				fullscreen_icon );
 }
 
-void control_box_set_fullscreen_btn_visible(ControlBox *box, gboolean value)
+void gmpv_control_box_set_fullscreen_btn_visible(	GmpvControlBox *box,
+							gboolean value )
 {
 	gtk_widget_set_visible(box->fullscreen_button, value);
 }
 
-void control_box_reset(ControlBox *box)
+void gmpv_control_box_reset(GmpvControlBox *box)
 {
-	control_box_set_seek_bar_length(box, 0);
-	control_box_set_playing_state(box, FALSE);
-	control_box_set_chapter_enabled(box, FALSE);
-	control_box_set_fullscreen_state(box, FALSE);
-	control_box_set_volume_enabled(box, FALSE);
+	gmpv_control_box_set_seek_bar_length(box, 0);
+	gmpv_control_box_set_playing_state(box, FALSE);
+	gmpv_control_box_set_chapter_enabled(box, FALSE);
+	gmpv_control_box_set_fullscreen_state(box, FALSE);
+	gmpv_control_box_set_volume_enabled(box, FALSE);
 }
diff --git a/src/gmpv_control_box.h b/src/gmpv_control_box.h
new file mode 100644
index 0000000..8222797
--- /dev/null
+++ b/src/gmpv_control_box.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014-2016 gnome-mpv
+ *
+ * This file is part of GNOME MPV.
+ *
+ * GNOME MPV 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CONTROL_BOX_H
+#define CONTROL_BOX_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GMPV_TYPE_CONTROL_BOX (gmpv_control_box_get_type())
+
+G_DECLARE_FINAL_TYPE(GmpvControlBox, gmpv_control_box, GMPV, CONTROL_BOX, GtkBox)
+
+GtkWidget *gmpv_control_box_new(void);
+void gmpv_control_box_set_enabled(GmpvControlBox *box, gboolean enabled);
+void gmpv_control_box_set_chapter_enabled(GmpvControlBox *box, gboolean enabled);
+void gmpv_control_box_set_volume_enabled(GmpvControlBox *box, gboolean enabled);
+void gmpv_control_box_set_seek_bar_pos(GmpvControlBox *box, gdouble pos);
+void gmpv_control_box_set_seek_bar_length(GmpvControlBox *box, gint length);
+void gmpv_control_box_set_volume(GmpvControlBox *box, gdouble volume);
+gdouble gmpv_control_box_get_volume(GmpvControlBox *box);
+gboolean gmpv_control_box_get_volume_popup_visible(GmpvControlBox *box);
+void gmpv_control_box_set_playing_state(GmpvControlBox *box, gboolean playing);
+void gmpv_control_box_set_fullscreen_state(	GmpvControlBox *box,
+						gboolean fullscreen );
+void gmpv_control_box_set_fullscreen_btn_visible(	GmpvControlBox *box,
+							gboolean value );
+void gmpv_control_box_reset(GmpvControlBox *box);
+
+G_END_DECLS
+
+#endif
+
diff --git a/src/def.h b/src/gmpv_def.h
similarity index 90%
rename from src/def.h
rename to src/gmpv_def.h
index f5f66ab..66535e7 100644
--- a/src/def.h
+++ b/src/gmpv_def.h
@@ -26,7 +26,7 @@
 #define CONFIG_ROOT APP_ID
 #define CONFIG_WIN_STATE APP_ID".window-state"
 #define DEFAULT_LOG_LEVEL MPV_LOG_LEVEL_ERROR
-#define MPRIS_TRACK_ID_PREFIX "/org/gnome_mpv/Track/"
+#define MPRIS_TRACK_ID_PREFIX "/org/gnome_mpv/GmpvTrack/"
 #define MPRIS_BUS_NAME "org.mpris.MediaPlayer2.gnome-mpv"
 #define MPRIS_OBJ_ROOT_PATH "/org/mpris/MediaPlayer2"
 #define PLAYLIST_DEFAULT_WIDTH 200
@@ -40,7 +40,10 @@
 #define FS_CONTROL_HIDE_DELAY 1
 #define KEYSTRING_MAX_LEN 16
 
-#define DND_TARGETS	{	{.target = "text/uri-list",\
+#define DND_TARGETS	{	{.target = "PLAYLIST_PATH",\
+				.flags = GTK_TARGET_SAME_APP,\
+				.info = 0},\
+				{.target = "text/uri-list",\
 				.flags = 0,\
 				.info = 0},\
 				{.target = "text/plain",\
@@ -173,15 +176,15 @@
 					"rar",\
 					NULL }
 
-#define SUPPORTED_MIME_TYPES	{	"application/ogg",\
-					"application/x-ogg",\
-					"application/sdp",\
-					"application/smil",\
-					"application/x-smil",\
-					"application/streamingmedia",\
-					"application/x-streamingmedia",\
-					"application/vnd.rn-realmedia",\
-					"application/vnd.rn-realmedia-vbr",\
+#define SUPPORTED_MIME_TYPES	{	"gmpv_application/ogg",\
+					"gmpv_application/x-ogg",\
+					"gmpv_application/sdp",\
+					"gmpv_application/smil",\
+					"gmpv_application/x-smil",\
+					"gmpv_application/streamingmedia",\
+					"gmpv_application/x-streamingmedia",\
+					"gmpv_application/vnd.rn-realmedia",\
+					"gmpv_application/vnd.rn-realmedia-vbr",\
 					"audio/aac",\
 					"audio/x-aac",\
 					"audio/m4a",\
diff --git a/src/main.c b/src/gmpv_main.c
similarity index 86%
copy from src/main.c
copy to src/gmpv_main.c
index 0d34db3..9198a9b 100644
--- a/src/main.c
+++ b/src/gmpv_main.c
@@ -20,15 +20,15 @@
 #include <glib/gi18n.h>
 #include <gdk/gdk.h>
 
-#include "application.h"
-#include "def.h"
+#include "gmpv_application.h"
+#include "gmpv_def.h"
 
 int main(int argc, char **argv)
 {
-	Application *app;
+	GmpvApplication *app;
 	gint status;
 
-	app = application_new(APP_ID, G_APPLICATION_HANDLES_OPEN);
+	app = gmpv_application_new(APP_ID, G_APPLICATION_HANDLES_OPEN);
 	status = g_application_run(G_APPLICATION(app), argc, argv);
 
 	g_object_unref(app);
diff --git a/src/main_window.c b/src/gmpv_main_window.c
similarity index 53%
rename from src/main_window.c
rename to src/gmpv_main_window.c
index c947873..1851936 100644
--- a/src/main_window.c
+++ b/src/gmpv_main_window.c
@@ -24,112 +24,116 @@
 #include <gdk/gdkwayland.h>
 #endif
 
-#include "def.h"
-#include "menu.h"
-#include "application.h"
-#include "playlist_widget.h"
-#include "main_window.h"
-#include "control_box.h"
+#include "gmpv_def.h"
+#include "gmpv_menu.h"
+#include "gmpv_application.h"
+#include "gmpv_playlist_widget.h"
+#include "gmpv_main_window.h"
+#include "gmpv_control_box.h"
+#include "gmpv_video_area.h"
 
 enum
 {
 	PROP_0,
 	PROP_PLAYLIST,
-	PROP_USE_OPENGL,
 	N_PROPERTIES
 };
 
-struct _MainWindowPrivate
+struct _GmpvMainWindow
 {
-	Playlist *playlist;
-	gboolean playlist_first_toggle;
-	gboolean use_opengl;
+	GtkApplicationWindow parent_instance;
+	GmpvPlaylist *playlist_store;
 	gint width_offset;
 	gint height_offset;
 	gint resize_target[2];
+	gboolean fullscreen;
+	gboolean playlist_visible;
+	gboolean playlist_first_toggle;
+	gboolean pre_fs_playlist_visible;
+	gint playlist_width;
+	guint timeout_tag;
+	GtkWidget *header_bar;
+	GtkWidget *open_hdr_btn;
+	GtkWidget *fullscreen_hdr_btn;
+	GtkWidget *menu_hdr_btn;
+	GtkWidget *main_box;
+	GtkWidget *vid_area_paned;
+	GtkWidget *vid_area;
+	GtkWidget *control_box;
+	GtkWidget *playlist;
+};
+
+struct _GmpvMainWindowClass
+{
+	GtkApplicationWindowClass parent_class;
 };
 
-static void main_window_set_property(	GObject *object,
-					guint property_id,
-					const GValue *value,
-					GParamSpec *pspec );
-static void main_window_get_property(	GObject *object,
-					guint property_id,
-					GValue *value,
-					GParamSpec *pspec );
-static gboolean fs_control_enter_handler(	GtkWidget *widget,
-						GdkEvent *event,
-						gpointer data );
-static gboolean fs_control_leave_handler(	GtkWidget *widget,
-						GdkEvent *event,
-						gpointer data );
-static gboolean motion_notify_handler(GtkWidget *widget, GdkEventMotion *event);
+static void gmpv_main_window_constructed(GObject *object);
+static void gmpv_main_window_set_property(	GObject *object,
+						guint property_id,
+						const GValue *value,
+						GParamSpec *pspec );
+static void gmpv_main_window_get_property(	GObject *object,
+						guint property_id,
+						GValue *value,
+						GParamSpec *pspec );
 static void size_allocate_handler(	GtkWidget *widget,
 					GdkRectangle *allocation,
 					gpointer data );
-static void vid_area_init(MainWindow *wnd, gboolean use_opengl);
-static GtkWidget *vid_area_new(gboolean use_opengl);
-static gboolean timeout_handler(gpointer data);
 static gboolean resize_to_target(gpointer data);
 
-G_DEFINE_TYPE_WITH_PRIVATE(MainWindow, main_window, GTK_TYPE_APPLICATION_WINDOW)
+G_DEFINE_TYPE(GmpvMainWindow, gmpv_main_window, GTK_TYPE_APPLICATION_WINDOW)
 
-static void main_window_constructed(GObject *object)
+static void gmpv_main_window_constructed(GObject *object)
 {
-	MainWindow *self = MAIN_WINDOW(object);
+	GmpvMainWindow *self = GMPV_MAIN_WINDOW(object);
 
-	self->playlist = playlist_widget_new(self->priv->playlist);
+	self->playlist = gmpv_playlist_widget_new(self->playlist_store);
 
 	gtk_widget_show_all(self->playlist);
 	gtk_widget_hide(self->playlist);
 	gtk_widget_set_no_show_all(self->playlist, TRUE);
 
+	gtk_paned_pack1(	GTK_PANED(self->vid_area_paned),
+				self->vid_area,
+				TRUE,
+				TRUE );
 	gtk_paned_pack2(	GTK_PANED(self->vid_area_paned),
 				self->playlist,
 				FALSE,
 				FALSE );
 
-	vid_area_init(self, self->priv->use_opengl);
-
-	G_OBJECT_CLASS(main_window_parent_class)->constructed(object);
+	G_OBJECT_CLASS(gmpv_main_window_parent_class)->constructed(object);
 }
 
-static void main_window_set_property(	GObject *object,
-					guint property_id,
-					const GValue *value,
-					GParamSpec *pspec )
+static void gmpv_main_window_set_property(	GObject *object,
+						guint property_id,
+						const GValue *value,
+						GParamSpec *pspec )
 {
-	MainWindow *self = MAIN_WINDOW(object);
+	GmpvMainWindow *self = GMPV_MAIN_WINDOW(object);
 
 	if(property_id == PROP_PLAYLIST)
 	{
-		self->priv->playlist = g_value_get_pointer(value);
+		self->playlist_store = g_value_get_pointer(value);
 
 	}
-	else if(property_id == PROP_USE_OPENGL)
-	{
-		self->priv->use_opengl = g_value_get_boolean(value);
-	}
 	else
 	{
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
 	}
 }
 
-static void main_window_get_property(	GObject *object,
-					guint property_id,
-					GValue *value,
-					GParamSpec *pspec )
+static void gmpv_main_window_get_property(	GObject *object,
+						guint property_id,
+						GValue *value,
+						GParamSpec *pspec )
 {
-	MainWindow *self = MAIN_WINDOW(object);
+	GmpvMainWindow *self = GMPV_MAIN_WINDOW(object);
 
 	if(property_id == PROP_PLAYLIST)
 	{
-		g_value_set_pointer(value, self->priv->playlist);
-	}
-	else if(property_id == PROP_USE_OPENGL)
-	{
-		g_value_set_boolean(value, self->priv->use_opengl);
+		g_value_set_pointer(value, self->playlist_store);
 	}
 	else
 	{
@@ -137,64 +141,18 @@ static void main_window_get_property(	GObject *object,
 	}
 }
 
-static gboolean fs_control_enter_handler(	GtkWidget *widget,
-						GdkEvent *event,
-						gpointer data )
-{
-	MAIN_WINDOW(data)->fs_control_hover = TRUE;
-
-	return FALSE;
-}
-
-static gboolean fs_control_leave_handler(	GtkWidget *widget,
-						GdkEvent *event,
-						gpointer data )
-{
-	MAIN_WINDOW(data)->fs_control_hover = FALSE;
-
-	return FALSE;
-}
-
-static gboolean motion_notify_handler(GtkWidget *widget, GdkEventMotion *event)
-{
-	MainWindow *wnd = MAIN_WINDOW(widget);
-	GdkCursor *cursor;
-
-	cursor = gdk_cursor_new_from_name(gdk_display_get_default(), "default");
-	gdk_window_set_cursor
-		(gtk_widget_get_window(GTK_WIDGET(wnd->vid_area)), cursor);
-
-	if(wnd->fullscreen)
-	{
-		gtk_revealer_set_reveal_child
-			(GTK_REVEALER(wnd->fs_revealer), TRUE);
-	}
-
-	if(wnd->timeout_tag > 0)
-	{
-		g_source_remove(wnd->timeout_tag);
-	}
-
-	wnd->timeout_tag = g_timeout_add_seconds(	FS_CONTROL_HIDE_DELAY,
-							timeout_handler,
-							wnd );
-
-	return	GTK_WIDGET_CLASS(main_window_parent_class)
-		->motion_notify_event(widget, event);
-}
-
 static void size_allocate_handler(	GtkWidget *widget,
 					GdkRectangle *allocation,
 					gpointer data )
 {
-	MainWindow *wnd = data;
+	GmpvMainWindow *wnd = data;
 	GdkScreen *screen = gdk_screen_get_default();
 	gint screen_width = gdk_screen_get_width(screen);
 	gint screen_height = gdk_screen_get_height(screen);
 	gint width = allocation->width;
 	gint height = allocation->height;
-	gint target_width = wnd->priv->resize_target[0];
-	gint target_height = wnd->priv->resize_target[1];
+	gint target_width = wnd->resize_target[0];
+	gint target_height = wnd->resize_target[1];
 
 	g_signal_handlers_disconnect_by_func
 		(widget, size_allocate_handler, data);
@@ -205,106 +163,34 @@ static void size_allocate_handler(	GtkWidget *widget,
 	&& !gtk_window_is_maximized(GTK_WINDOW(wnd))
 	&& !wnd->fullscreen)
 	{
-		wnd->priv->width_offset += target_width-width;
-		wnd->priv->height_offset += target_height-height;
+		wnd->width_offset += target_width-width;
+		wnd->height_offset += target_height-height;
 
 		g_idle_add(resize_to_target, wnd);
 	}
 }
 
-static void vid_area_init(MainWindow *wnd, gboolean use_opengl)
-{
-	/* vid_area cannot be initialized more than once */
-	if(!wnd->vid_area)
-	{
-		GtkTargetEntry targets[] = DND_TARGETS;
-		GtkStyleContext *style_context;
-
-		wnd->vid_area =	vid_area_new(use_opengl);
-		style_context = gtk_widget_get_style_context(wnd->vid_area);
-
-		gtk_style_context_add_class(style_context, "gmpv-vid-area");
-
-		gtk_drag_dest_set(	wnd->vid_area,
-					GTK_DEST_DEFAULT_ALL,
-					targets,
-					G_N_ELEMENTS(targets),
-					GDK_ACTION_LINK );
-		gtk_drag_dest_add_uri_targets(wnd->vid_area);
-
-		/* GDK_BUTTON_RELEASE_MASK is needed so that GtkMenuButtons can
-		 * hide their menus when vid_area is clicked.
-		 */
-		gtk_widget_add_events(	wnd->vid_area,
-					GDK_BUTTON_PRESS_MASK|
-					GDK_BUTTON_RELEASE_MASK );
-
-		gtk_container_add(	GTK_CONTAINER(wnd->vid_area_overlay),
-					wnd->vid_area );
-		gtk_paned_pack1(	GTK_PANED(wnd->vid_area_paned),
-					wnd->vid_area_overlay,
-					TRUE,
-					TRUE );
-	}
-}
-
-static GtkWidget *vid_area_new(gboolean use_opengl)
-{
-	return use_opengl?gtk_gl_area_new():gtk_drawing_area_new();
-}
-
-static gboolean timeout_handler(gpointer data)
-{
-	MainWindow *wnd;
-	ControlBox *control_box;
-
-	wnd = data;
-	control_box = CONTROL_BOX(wnd->control_box);
-
-	if(wnd->fullscreen
-	&& !wnd->fs_control_hover
-	&& !control_box_get_volume_popup_visible(control_box))
-	{
-		GdkWindow *window;
-		GdkCursor *cursor;
-
-		window = gtk_widget_get_window(GTK_WIDGET(wnd->vid_area));
-		cursor = gdk_cursor_new_for_display
-				(gdk_display_get_default(), GDK_BLANK_CURSOR);
-
-		gdk_window_set_cursor(window, cursor);
-		gtk_revealer_set_reveal_child
-			(GTK_REVEALER(wnd->fs_revealer), FALSE);
-	}
-
-	wnd->timeout_tag = 0;
-
-	return FALSE;
-}
-
 static gboolean resize_to_target(gpointer data)
 {
-	MainWindow *wnd = data;
-	gint target_width = wnd->priv->resize_target[0];
-	gint target_height = wnd->priv->resize_target[1];
+	GmpvMainWindow *wnd = data;
+	gint target_width = wnd->resize_target[0];
+	gint target_height = wnd->resize_target[1];
 
 	gtk_window_resize(	GTK_WINDOW(wnd),
-				target_width+wnd->priv->width_offset,
-				target_height+wnd->priv->height_offset );
+				target_width+wnd->width_offset,
+				target_height+wnd->height_offset );
 
 	return FALSE;
 }
 
-static void main_window_class_init(MainWindowClass *klass)
+static void gmpv_main_window_class_init(GmpvMainWindowClass *klass)
 {
 	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-	GtkWidgetClass *wgt_class = GTK_WIDGET_CLASS(klass);
 	GParamSpec *pspec = NULL;
 
-	obj_class->constructed = main_window_constructed;
-	obj_class->set_property = main_window_set_property;
-	obj_class->get_property = main_window_get_property;
-	wgt_class->motion_notify_event = motion_notify_handler;
+	obj_class->constructed = gmpv_main_window_constructed;
+	obj_class->set_property = gmpv_main_window_set_property;
+	obj_class->get_property = gmpv_main_window_get_property;
 
 	pspec = g_param_spec_pointer
 		(	"playlist",
@@ -313,43 +199,29 @@ static void main_window_class_init(MainWindowClass *klass)
 			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
 
 	g_object_class_install_property(obj_class, PROP_PLAYLIST, pspec);
-
-	pspec = g_param_spec_boolean
-		(	"use-opengl",
-			"Use OpenGL",
-			"Whether or not to set up video area for opengl-cb",
-			FALSE,
-			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
-
-	g_object_class_install_property(obj_class, PROP_USE_OPENGL, pspec);
 }
 
-static void main_window_init(MainWindow *wnd)
+static void gmpv_main_window_init(GmpvMainWindow *wnd)
 {
-	/* wnd->vid_area will be initialized when use-opengl property is set */
-	wnd->priv = main_window_get_instance_private(wnd);
 	wnd->fullscreen = FALSE;
 	wnd->playlist_visible = FALSE;
-	wnd->fs_control_hover = FALSE;
 	wnd->pre_fs_playlist_visible = FALSE;
 	wnd->playlist_width = PLAYLIST_DEFAULT_WIDTH;
 	wnd->timeout_tag = 0;
-	wnd->settings = gtk_settings_get_default();
 	wnd->header_bar = gtk_header_bar_new();
 	wnd->open_hdr_btn = NULL;
 	wnd->fullscreen_hdr_btn = NULL;
 	wnd->menu_hdr_btn = NULL;
 	wnd->main_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
 	wnd->vid_area_paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
-	wnd->vid_area_overlay = gtk_overlay_new();
-	wnd->control_box = control_box_new();
-	wnd->fs_revealer = gtk_revealer_new();
+	wnd->vid_area = gmpv_video_area_new();
+	wnd->control_box = gmpv_control_box_new();
 
-	wnd->priv->playlist_first_toggle = TRUE;
-	wnd->priv->width_offset = 0;
-	wnd->priv->height_offset = 0;
+	wnd->playlist_first_toggle = TRUE;
+	wnd->width_offset = 0;
+	wnd->height_offset = 0;
 
-	gtk_widget_add_events(	wnd->vid_area_overlay,
+	gtk_widget_add_events(	wnd->vid_area,
 				GDK_ENTER_NOTIFY_MASK
 				|GDK_LEAVE_NOTIFY_MASK );
 
@@ -366,48 +238,42 @@ static void main_window_init(MainWindow *wnd)
 					MAIN_WINDOW_DEFAULT_WIDTH,
 					MAIN_WINDOW_DEFAULT_HEIGHT );
 
-	gtk_widget_set_vexpand(wnd->fs_revealer, FALSE);
-	gtk_widget_set_hexpand(wnd->fs_revealer, FALSE);
-	gtk_widget_set_halign(wnd->fs_revealer, GTK_ALIGN_CENTER);
-	gtk_widget_set_valign(wnd->fs_revealer, GTK_ALIGN_END);
-	gtk_widget_show(wnd->fs_revealer);
-	gtk_revealer_set_reveal_child(GTK_REVEALER(wnd->fs_revealer), FALSE);
-
-	gtk_overlay_add_overlay
-		(GTK_OVERLAY(wnd->vid_area_overlay), wnd->fs_revealer);
 	gtk_box_pack_start
 		(GTK_BOX(wnd->main_box), wnd->vid_area_paned, TRUE, TRUE, 0);
 	gtk_container_add(GTK_CONTAINER(wnd->main_box), wnd->control_box);
 	gtk_container_add(GTK_CONTAINER(wnd), wnd->main_box);
-
-	g_signal_connect(	wnd->vid_area_overlay,
-				"enter-notify-event",
-				G_CALLBACK(fs_control_enter_handler),
-				wnd );
-	g_signal_connect(	wnd->vid_area_overlay,
-				"leave-notify-event",
-				G_CALLBACK(fs_control_leave_handler),
-				wnd );
 }
 
-GtkWidget *main_window_new(	Application *app,
-				Playlist *playlist,
-				gboolean use_opengl )
+GtkWidget *gmpv_main_window_new(GmpvApplication *app, GmpvPlaylist *playlist)
 {
-	return GTK_WIDGET(g_object_new(	main_window_get_type(),
+	return GTK_WIDGET(g_object_new(	gmpv_main_window_get_type(),
 					"application", app,
 					"playlist", playlist,
-					"use-opengl", use_opengl,
 					NULL ));
 }
 
-void main_window_set_fullscreen(MainWindow *wnd, gboolean fullscreen)
+GmpvPlaylistWidget *gmpv_main_window_get_playlist(GmpvMainWindow *wnd)
+{
+	return GMPV_PLAYLIST_WIDGET(wnd->playlist);
+}
+
+GmpvControlBox *gmpv_main_window_get_control_box(GmpvMainWindow *wnd)
+{
+	return GMPV_CONTROL_BOX(wnd->control_box);
+}
+
+GmpvVideoArea *gmpv_main_window_get_video_area(GmpvMainWindow *wnd)
+{
+	return GMPV_VIDEO_AREA(wnd->vid_area);
+}
+
+void gmpv_main_window_set_fullscreen(GmpvMainWindow *wnd, gboolean fullscreen)
 {
 	if(fullscreen != wnd->fullscreen)
 	{
-		ControlBox *control_box = CONTROL_BOX(wnd->control_box);
+		GmpvControlBox *control_box = GMPV_CONTROL_BOX(wnd->control_box);
+		GmpvVideoArea *vid_area = GMPV_VIDEO_AREA(wnd->vid_area);
 		GtkContainer* main_box = GTK_CONTAINER(wnd->main_box);
-		GtkContainer* revealer = GTK_CONTAINER(wnd->fs_revealer);
 
 		if(fullscreen)
 		{
@@ -432,18 +298,18 @@ void main_window_set_fullscreen(MainWindow *wnd, gboolean fullscreen)
 
 			g_object_ref(wnd->control_box);
 			gtk_container_remove(main_box, wnd->control_box);
-			gtk_container_add(revealer, wnd->control_box);
+			gmpv_video_area_set_control_box
+				(vid_area, wnd->control_box);
 			g_object_unref(wnd->control_box);
 
-			control_box_set_fullscreen_state(control_box, TRUE);
+			gmpv_video_area_set_fullscreen_state(vid_area, TRUE);
 			gtk_window_fullscreen(GTK_WINDOW(wnd));
 			gtk_window_present(GTK_WINDOW(wnd));
-			gtk_widget_show(GTK_WIDGET(revealer));
 
-			if(main_window_get_csd_enabled(wnd))
+			if(gmpv_main_window_get_csd_enabled(wnd))
 			{
-				control_box_set_fullscreen_btn_visible
-					(CONTROL_BOX(wnd->control_box), TRUE);
+				gmpv_control_box_set_fullscreen_btn_visible
+					(control_box, TRUE);
 			}
 			else
 			{
@@ -456,26 +322,22 @@ void main_window_set_fullscreen(MainWindow *wnd, gboolean fullscreen)
 		}
 		else
 		{
-			GdkCursor *cursor;
-			GdkWindow *vid_area;
-
 			gtk_widget_set_halign(wnd->control_box, GTK_ALIGN_FILL);
 			gtk_widget_set_valign(wnd->control_box, GTK_ALIGN_FILL);
 			gtk_widget_set_size_request(wnd->control_box, -1, -1);
 
 			g_object_ref(wnd->control_box);
-			gtk_container_remove(revealer, wnd->control_box);
+			gmpv_video_area_set_control_box(vid_area, NULL);
 			gtk_container_add(main_box, wnd->control_box);
 			g_object_unref(wnd->control_box);
 
-			control_box_set_fullscreen_state(control_box, FALSE);
+			gmpv_video_area_set_fullscreen_state(vid_area, FALSE);
 			gtk_window_unfullscreen(GTK_WINDOW(wnd));
-			gtk_widget_hide(GTK_WIDGET(revealer));
 
-			if(main_window_get_csd_enabled(wnd))
+			if(gmpv_main_window_get_csd_enabled(wnd))
 			{
-				control_box_set_fullscreen_btn_visible
-					(CONTROL_BOX(wnd->control_box), FALSE);
+				gmpv_control_box_set_fullscreen_btn_visible
+					(control_box, FALSE);
 			}
 			else
 			{
@@ -486,34 +348,33 @@ void main_window_set_fullscreen(MainWindow *wnd, gboolean fullscreen)
 			wnd->playlist_visible = wnd->pre_fs_playlist_visible;
 			gtk_widget_set_visible
 				(wnd->playlist, wnd->pre_fs_playlist_visible);
-
-			cursor =	gdk_cursor_new_from_name
-					(gdk_display_get_default(), "default");
-			vid_area =	gtk_widget_get_window
-					(GTK_WIDGET(wnd->vid_area));
-
-			gdk_window_set_cursor(vid_area, cursor);
 		}
 
 		wnd->fullscreen = fullscreen;
-
-		timeout_handler(wnd);
 	}
 }
 
-void main_window_toggle_fullscreen(MainWindow *wnd)
+gboolean gmpv_main_window_get_fullscreen(GmpvMainWindow *wnd)
 {
-	main_window_set_fullscreen(wnd, !wnd->fullscreen);
+	return wnd->fullscreen;
 }
 
-void main_window_reset(MainWindow *wnd)
+void gmpv_main_window_toggle_fullscreen(GmpvMainWindow *wnd)
 {
+	gmpv_main_window_set_fullscreen(wnd, !wnd->fullscreen);
+}
+
+void gmpv_main_window_reset(GmpvMainWindow *wnd)
+{
+	GmpvPlaylist *store =	gmpv_playlist_widget_get_store
+				(GMPV_PLAYLIST_WIDGET(wnd->playlist));
+
 	gtk_window_set_title(GTK_WINDOW(wnd), g_get_application_name());
-	control_box_reset(CONTROL_BOX(wnd->control_box));
-	playlist_set_indicator_pos(PLAYLIST_WIDGET(wnd->playlist)->store, -1);
+	gmpv_control_box_reset(GMPV_CONTROL_BOX(wnd->control_box));
+	gmpv_playlist_set_indicator_pos(store, -1);
 }
 
-void main_window_save_state(MainWindow *wnd)
+void gmpv_main_window_save_state(GmpvMainWindow *wnd)
 {
 	GSettings *settings;
 	gint width;
@@ -523,7 +384,7 @@ void main_window_save_state(MainWindow *wnd)
 
 	settings = g_settings_new(CONFIG_WIN_STATE);
 	handle_pos = gtk_paned_get_position(GTK_PANED(wnd->vid_area_paned));
-	volume = control_box_get_volume(CONTROL_BOX(wnd->control_box));
+	volume = gmpv_control_box_get_volume(GMPV_CONTROL_BOX(wnd->control_box));
 
 	gtk_window_get_size(GTK_WINDOW(wnd), &width, &height);
 
@@ -532,7 +393,7 @@ void main_window_save_state(MainWindow *wnd)
 	g_settings_set_double(settings, "volume", volume);
 	g_settings_set_boolean(settings, "show-playlist", wnd->playlist_visible);
 
-	if(main_window_get_playlist_visible(wnd))
+	if(gmpv_main_window_get_playlist_visible(wnd))
 	{
 		g_settings_set_int(	settings,
 					"playlist-width",
@@ -548,7 +409,7 @@ void main_window_save_state(MainWindow *wnd)
 	g_clear_object(&settings);
 }
 
-void main_window_load_state(MainWindow *wnd)
+void gmpv_main_window_load_state(GmpvMainWindow *wnd)
 {
 	if(!gtk_widget_get_realized(GTK_WIDGET(wnd)))
 	{
@@ -565,31 +426,33 @@ void main_window_load_state(MainWindow *wnd)
 		volume = g_settings_get_double(settings, "volume");
 		handle_pos = width-(wnd->playlist_visible?wnd->playlist_width:0);
 
-		control_box_set_volume(CONTROL_BOX(wnd->control_box), volume);
+		gmpv_control_box_set_volume
+			(GMPV_CONTROL_BOX(wnd->control_box), volume);
 		gtk_widget_set_visible(wnd->playlist, wnd->playlist_visible);
 		gtk_window_resize(GTK_WINDOW(wnd), width, height);
-		gtk_paned_set_position(	GTK_PANED(wnd->vid_area_paned),
-					 handle_pos );
+		gtk_paned_set_position
+			(GTK_PANED(wnd->vid_area_paned), handle_pos);
 
 		g_clear_object(&settings);
 	}
 	else
 	{
-		g_critical(	"Attempted to call main_window_load_state() on "
-				"realized window" );
+		g_critical(	"Attempted to call gmpv_main_window_load_state() "
+				"on realized window" );
 	}
 }
 
-void main_window_update_track_list(	MainWindow *wnd,
+void gmpv_main_window_update_track_list(	GmpvMainWindow *wnd,
 					const GSList *audio_list,
 					const GSList *video_list,
 					const GSList *sub_list )
 {
-	if(main_window_get_csd_enabled(wnd))
+	if(gmpv_main_window_get_csd_enabled(wnd))
 	{
 		GMenu *menu = g_menu_new();
 
-		menu_build_menu_btn(menu, audio_list, video_list, sub_list);
+		gmpv_menu_build_menu_btn
+			(menu, audio_list, video_list, sub_list);
 
 		gtk_menu_button_set_menu_model
 			(	GTK_MENU_BUTTON(wnd->menu_hdr_btn),
@@ -606,12 +469,13 @@ void main_window_update_track_list(	MainWindow *wnd,
 		if(menu)
 		{
 			g_menu_remove_all(menu);
-			menu_build_full(menu, audio_list, video_list, sub_list);
+			gmpv_menu_build_full
+				(menu, audio_list, video_list, sub_list);
 		}
 	}
 }
 
-void main_window_resize_video_area(	MainWindow *wnd,
+void gmpv_main_window_resize_video_area(	GmpvMainWindow *wnd,
 					gint width,
 					gint height )
 {
@@ -620,23 +484,22 @@ void main_window_resize_video_area(	MainWindow *wnd,
 				G_CALLBACK(size_allocate_handler),
 				wnd );
 
-	wnd->priv->resize_target[0] = width;
-	wnd->priv->resize_target[1] = height;
+	wnd->resize_target[0] = width;
+	wnd->resize_target[1] = height;
 	resize_to_target(wnd);
 
 	/* The size may not change, so this is needed to ensure that
 	 * size_allocate_handler() will be called so that the event handler will
 	 * be disconnected.
 	 */
+#if (GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 20)
 	gtk_widget_queue_allocate(wnd->vid_area);
+#else
+	gtk_widget_queue_resize(wnd->vid_area);
+#endif
 }
 
-gboolean main_window_get_use_opengl(MainWindow *wnd)
-{
-	return wnd->priv->use_opengl;
-}
-
-void main_window_enable_csd(MainWindow *wnd)
+void gmpv_main_window_enable_csd(GmpvMainWindow *wnd)
 {
 	GMenu *menu_btn_menu;
 	GMenu *open_btn_menu;
@@ -659,8 +522,8 @@ void main_window_enable_csd(MainWindow *wnd)
 	wnd->fullscreen_hdr_btn = gtk_button_new();
 	wnd->menu_hdr_btn = gtk_menu_button_new();
 
-	menu_build_open_btn(open_btn_menu);
-	menu_build_menu_btn(menu_btn_menu, NULL, NULL, NULL);
+	gmpv_menu_build_open_btn(open_btn_menu);
+	gmpv_menu_build_menu_btn(menu_btn_menu, NULL, NULL, NULL);
 
 	gtk_widget_set_can_focus(wnd->open_hdr_btn, FALSE);
 	gtk_widget_set_can_focus(wnd->fullscreen_hdr_btn, FALSE);
@@ -707,14 +570,14 @@ void main_window_enable_csd(MainWindow *wnd)
 	gtk_window_set_title(GTK_WINDOW(wnd), g_get_application_name());
 }
 
-gboolean main_window_get_csd_enabled(MainWindow *wnd)
+gboolean gmpv_main_window_get_csd_enabled(GmpvMainWindow *wnd)
 {
 	return	wnd->open_hdr_btn &&
 		wnd->fullscreen_hdr_btn &&
 		wnd->menu_hdr_btn;
 }
 
-void main_window_set_playlist_visible(MainWindow *wnd, gboolean visible)
+void gmpv_main_window_set_playlist_visible(GmpvMainWindow *wnd, gboolean visible)
 {
 	if(visible != wnd->playlist_visible && !wnd->fullscreen)
 	{
@@ -729,7 +592,7 @@ void main_window_set_playlist_visible(MainWindow *wnd, gboolean visible)
 
 		gtk_window_get_size(GTK_WINDOW(wnd), &width, &height);
 
-		if(wnd->priv->playlist_first_toggle && visible)
+		if(wnd->playlist_first_toggle && visible)
 		{
 			gint new_pos = width-(maximized?wnd->playlist_width:0);
 
@@ -747,18 +610,33 @@ void main_window_set_playlist_visible(MainWindow *wnd, gboolean visible)
 
 		if(!maximized)
 		{
+#if (GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 20)
 			gtk_window_resize(	GTK_WINDOW(wnd),
 						visible?
 						width+wnd->playlist_width:
 						handle_pos,
 						height );
+#else
+			/* Workaround for window sizing bug on Wayland affecting
+			 * GTK+ < 3.20
+			 */
+			gint wnd_offset;
+
+			wnd_offset = gmpv_main_window_get_csd_enabled(wnd)?52:0;
+
+			gtk_window_resize(	GTK_WINDOW(wnd),
+						visible?
+						width+wnd->playlist_width-wnd_offset:
+						handle_pos+wnd_offset,
+						height );
+#endif
 		}
 
-		wnd->priv->playlist_first_toggle = FALSE;
+		wnd->playlist_first_toggle = FALSE;
 	}
 }
 
-gboolean main_window_get_playlist_visible(MainWindow *wnd)
+gboolean gmpv_main_window_get_playlist_visible(GmpvMainWindow *wnd)
 {
 	return gtk_widget_get_visible(GTK_WIDGET(wnd->playlist));
 }
diff --git a/src/gmpv_main_window.h b/src/gmpv_main_window.h
new file mode 100644
index 0000000..f9dd5a5
--- /dev/null
+++ b/src/gmpv_main_window.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014-2016 gnome-mpv
+ *
+ * This file is part of GNOME MPV.
+ *
+ * GNOME MPV 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAIN_WINDOW_H
+#define MAIN_WINDOW_H
+
+#include <gtk/gtk.h>
+
+#include "gmpv_playlist.h"
+#include "gmpv_playlist_widget.h"
+#include "gmpv_control_box.h"
+#include "gmpv_video_area.h"
+
+G_BEGIN_DECLS
+
+#define GMPV_TYPE_MAIN_WINDOW (gmpv_main_window_get_type ())
+
+G_DECLARE_FINAL_TYPE(GmpvMainWindow, gmpv_main_window, GMPV, MAIN_WINDOW, GtkApplicationWindow)
+
+typedef struct _GmpvApplication GmpvApplication;
+
+GtkWidget *gmpv_main_window_new(GmpvApplication *app, GmpvPlaylist *gmpv_playlist);
+GmpvPlaylistWidget *gmpv_main_window_get_playlist(GmpvMainWindow *wnd);
+GmpvControlBox *gmpv_main_window_get_control_box(GmpvMainWindow *wnd);
+GmpvVideoArea *gmpv_main_window_get_video_area(GmpvMainWindow *wnd);
+void gmpv_main_window_set_fullscreen(GmpvMainWindow *wnd, gboolean fullscreen);
+gboolean gmpv_main_window_get_fullscreen(GmpvMainWindow *wnd);
+void gmpv_main_window_toggle_fullscreen(GmpvMainWindow *wnd);
+void gmpv_main_window_reset(GmpvMainWindow *wnd);
+void gmpv_main_window_save_state(GmpvMainWindow *wnd);
+void gmpv_main_window_load_state(GmpvMainWindow *wnd);
+void gmpv_main_window_update_track_list(	GmpvMainWindow *wnd,
+					const GSList *audio_list,
+					const GSList *video_list,
+					const GSList *sub_list );
+void gmpv_main_window_resize_video_area(	GmpvMainWindow *wnd,
+					gint width,
+					gint height );
+void gmpv_main_window_enable_csd(GmpvMainWindow *wnd);
+gboolean gmpv_main_window_get_csd_enabled(GmpvMainWindow *wnd);
+void gmpv_main_window_set_playlist_visible(GmpvMainWindow *wnd, gboolean visible);
+gboolean gmpv_main_window_get_playlist_visible(GmpvMainWindow *wnd);
+
+G_END_DECLS
+
+#endif
diff --git a/src/menu.c b/src/gmpv_menu.c
similarity index 97%
rename from src/menu.c
rename to src/gmpv_menu.c
index a8e69e1..e65bb2b 100644
--- a/src/menu.c
+++ b/src/gmpv_menu.c
@@ -19,8 +19,8 @@
 
 #include <glib/gi18n.h>
 
-#include "menu.h"
-#include "track.h"
+#include "gmpv_menu.h"
+#include "gmpv_track.h"
 
 static void build_menu_from_track_list(	GMenu *menu,
 					const GSList *list,
@@ -34,14 +34,14 @@ void build_menu_from_track_list(	GMenu *menu,
 	const glong max_len = 32;
 	gchar *detailed_action;
 
-	detailed_action = g_strdup_printf("app.%s(@x -1)", action);
+	detailed_action = g_strdup_printf("app.%s(@x 0)", action);
 
 	g_menu_append(menu, _("None"), detailed_action);
 	g_free(detailed_action);
 
 	while(iter)
 	{
-		Track *entry;
+		GmpvTrack *entry;
 		glong entry_title_len;
 		gchar *entry_title;
 		gchar *title;
@@ -86,7 +86,7 @@ void build_menu_from_track_list(	GMenu *menu,
 	}
 }
 
-void menu_build_full(	GMenu *menu,
+void gmpv_menu_build_full(	GMenu *menu,
 			const GSList *audio_list,
 			const GSList *video_list,
 			const GSList *sub_list )
@@ -257,7 +257,7 @@ void menu_build_full(	GMenu *menu,
 	g_object_unref(about_menu_item);
 }
 
-void menu_build_menu_btn(	GMenu *menu,
+void gmpv_menu_build_menu_btn(	GMenu *menu,
 				const GSList *audio_list,
 				const GSList *video_list,
 				const GSList *sub_list )
@@ -381,7 +381,7 @@ void menu_build_menu_btn(	GMenu *menu,
 	g_object_unref(view_section);
 }
 
-void menu_build_open_btn(GMenu *menu)
+void gmpv_menu_build_open_btn(GMenu *menu)
 {
 	GMenuItem *open_menu_item;
 	GMenuItem *open_loc_menu_item;
@@ -399,7 +399,7 @@ void menu_build_open_btn(GMenu *menu)
 	g_object_unref(open_loc_menu_item);
 }
 
-void menu_build_app_menu(GMenu *menu)
+void gmpv_menu_build_app_menu(GMenu *menu)
 {
 	GMenu *top_section;
 	GMenu *bottom_section;
diff --git a/src/menu.h b/src/gmpv_menu.h
similarity index 78%
rename from src/menu.h
rename to src/gmpv_menu.h
index 9a721a1..206d3cb 100644
--- a/src/menu.h
+++ b/src/gmpv_menu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 gnome-mpv
+ * Copyright (c) 2015-2016 gnome-mpv
  *
  * This file is part of GNOME MPV.
  *
@@ -22,15 +22,19 @@
 
 #include <gio/gio.h>
 
-void menu_build_full(	GMenu *menu,
+G_BEGIN_DECLS
+
+void gmpv_menu_build_full(	GMenu *gmpv_menu,
 			const GSList *audio_list,
 			const GSList *video_list,
 			const GSList *sub_list );
-void menu_build_menu_btn(	GMenu *menu,
+void gmpv_menu_build_menu_btn(	GMenu *gmpv_menu,
 				const GSList *audio_list,
 				const GSList *video_list,
 				const GSList *sub_list );
-void menu_build_open_btn(GMenu *menu);
-void menu_build_app_menu(GMenu *menu);
+void gmpv_menu_build_open_btn(GMenu *gmpv_menu);
+void gmpv_menu_build_app_menu(GMenu *gmpv_menu);
+
+G_END_DECLS
 
 #endif
diff --git a/src/mpv_obj.c b/src/gmpv_mpv_obj.c
similarity index 65%
rename from src/mpv_obj.c
rename to src/gmpv_mpv_obj.c
index 477fe2f..2e7a925 100644
--- a/src/mpv_obj.c
+++ b/src/gmpv_mpv_obj.c
@@ -38,94 +38,45 @@
 #include <epoxy/wgl.h>
 #endif
 
-#include "mpv_obj.h"
-#include "mpv_opt.h"
-#include "application.h"
-#include "common.h"
-#include "def.h"
-#include "track.h"
-#include "playlist.h"
-#include "control_box.h"
-#include "playlist_widget.h"
-
-enum
-{
-	PROP_0,
-	PROP_USE_OPENGL,
-	PROP_GLAREA,
-	PROP_WID,
-	PROP_PLAYLIST,
-	N_PROPERTIES
-};
-
-struct _MpvObjPrivate
-{
-	MpvObjState state;
-	gboolean use_opengl;
-	GtkGLArea *glarea;
-	gint64 wid;
-	void *wakeup_callback_data;
-	void *opengl_cb_callback_data;
-	void (*wakeup_callback)(void *data);
-	void (*opengl_cb_callback)(void *data);
-};
-
-
-static void *get_proc_address(void *fn_ctx, const gchar *name);
-static void mpv_obj_set_inst_property(	GObject *object,
-					guint property_id,
-					const GValue *value,
-					GParamSpec *pspec );
-static void mpv_obj_get_inst_property(	GObject *object,
-					guint property_id,
-					GValue *value,
-					GParamSpec *pspec );
-static void mpv_prop_change_handler(MpvObj *mpv, mpv_event_property* prop);
+#include "gmpv_mpv_obj.h"
+#include "gmpv_mpv_obj_private.h"
+#include "gmpv_mpv_opt.h"
+#include "gmpv_application.h"
+#include "gmpv_common.h"
+#include "gmpv_def.h"
+#include "gmpv_track.h"
+#include "gmpv_playlist.h"
+#include "gmpv_control_box.h"
+#include "gmpv_playlist_widget.h"
+
+static void gmpv_mpv_obj_set_inst_property(	GObject *object,
+						guint property_id,
+						const GValue *value,
+						GParamSpec *pspec );
+static void gmpv_mpv_obj_get_inst_property(	GObject *object,
+						guint property_id,
+						GValue *value,
+						GParamSpec *pspec );
+static void wakeup_callback(void *data);
+static void mpv_prop_change_handler(GmpvMpvObj *mpv, mpv_event_property* prop);
 static gboolean mpv_event_handler(gpointer data);
-static void mpv_obj_update_playlist(MpvObj *mpv);
+static void mpv_obj_update_playlist(GmpvMpvObj *mpv);
 static gint mpv_obj_apply_args(mpv_handle *mpv_ctx, gchar *args);
-static void mpv_obj_log_handler(MpvObj *mpv, mpv_event_log_message* message);
-static void load_input_conf(MpvObj *mpv, const gchar *input_conf);
-static void uninit_opengl_cb(MpvObj *mpv);
+static void mpv_obj_log_handler(GmpvMpvObj *mpv, mpv_event_log_message* message);
+static void load_input_conf(GmpvMpvObj *mpv, const gchar *input_conf);
 
-G_DEFINE_TYPE_WITH_PRIVATE(MpvObj, mpv_obj, G_TYPE_OBJECT)
+G_DEFINE_TYPE(GmpvMpvObj, gmpv_mpv_obj, G_TYPE_OBJECT)
 
-static void *get_proc_address(void *fn_ctx, const gchar *name)
+static void gmpv_mpv_obj_set_inst_property(	GObject *object,
+						guint property_id,
+						const GValue *value,
+						GParamSpec *pspec )
 {
-	GdkDisplay *display = gdk_display_get_default();
-
-#ifdef GDK_WINDOWING_WAYLAND
-	if (GDK_IS_WAYLAND_DISPLAY(display))
-		return eglGetProcAddress(name);
-#endif
-#ifdef GDK_WINDOWING_X11
-	if (GDK_IS_X11_DISPLAY(display))
-		return (void *)(intptr_t)glXGetProcAddressARB((const GLubyte *)name);
-#endif
-#ifdef GDK_WINDOWING_WIN32
-	if (GDK_IS_WIN32_DISPLAY(display))
-		return wglGetProcAddress(name);
-#endif
-	g_assert_not_reached();
-}
-
-static void mpv_obj_set_inst_property(	GObject *object,
-					guint property_id,
-					const GValue *value,
-					GParamSpec *pspec )
-{	MpvObj *self = MPV_OBJ(object);
+	GmpvMpvObj *self = GMPV_MPV_OBJ(object);
 
-	if(property_id == PROP_USE_OPENGL)
+	if(property_id == PROP_WID)
 	{
-		self->priv->use_opengl = g_value_get_boolean(value);
-	}
-	else if(property_id == PROP_GLAREA)
-	{
-		self->priv->glarea = g_value_get_pointer(value);
-	}
-	else if(property_id == PROP_WID)
-	{
-		self->priv->wid = g_value_get_int64(value);
+		self->wid = g_value_get_int64(value);
 	}
 	else if(property_id == PROP_PLAYLIST)
 	{
@@ -137,23 +88,16 @@ static void mpv_obj_set_inst_property(	GObject *object,
 	}
 }
 
-static void mpv_obj_get_inst_property(	GObject *object,
-					guint property_id,
-					GValue *value,
-					GParamSpec *pspec )
-{	MpvObj *self = MPV_OBJ(object);
+static void gmpv_mpv_obj_get_inst_property(	GObject *object,
+						guint property_id,
+						GValue *value,
+						GParamSpec *pspec )
+{
+	GmpvMpvObj *self = GMPV_MPV_OBJ(object);
 
-	if(property_id == PROP_USE_OPENGL)
-	{
-		g_value_set_boolean(value, self->priv->use_opengl);
-	}
-	else if(property_id == PROP_GLAREA)
+	if(property_id == PROP_WID)
 	{
-		g_value_set_pointer(value, self->priv->glarea);
-	}
-	else if(property_id == PROP_WID)
-	{
-		g_value_set_int64(value, self->priv->wid);
+		g_value_set_int64(value, self->wid);
 	}
 	else if(property_id == PROP_PLAYLIST)
 	{
@@ -165,33 +109,40 @@ static void mpv_obj_get_inst_property(	GObject *object,
 	}
 }
 
-static void mpv_prop_change_handler(MpvObj *mpv, mpv_event_property* prop)
+static void wakeup_callback(void *data)
 {
+	g_idle_add((GSourceFunc)mpv_event_handler, data);
+}
+
+static void mpv_prop_change_handler(GmpvMpvObj *mpv, mpv_event_property* prop)
+{
+	g_debug("Received mpv property change event for \"%s\"", prop->name);
+
 	if(g_strcmp0(prop->name, "pause") == 0)
 	{
 		gboolean idle;
 
-		mpv->priv->state.paused = prop->data?*((int *)prop->data):TRUE;
+		mpv->state.paused = prop->data?*((int *)prop->data):TRUE;
 
 		mpv_get_property(mpv->mpv_ctx, "idle", MPV_FORMAT_FLAG, &idle);
 
-		if(idle && !mpv->priv->state.paused)
+		if(idle && !mpv->state.paused)
 		{
-			mpv_obj_load(mpv, NULL, FALSE, TRUE);
+			gmpv_mpv_obj_load(mpv, NULL, FALSE, TRUE);
 		}
 	}
 }
 
 static gboolean mpv_event_handler(gpointer data)
 {
-	Application *app = data;
-	MpvObj *mpv = app->mpv;
-	mpv_event *event = NULL;
-	gboolean done = FALSE;
+	GmpvMpvObj *mpv = data;
+	gboolean done = !mpv;
 
 	while(!done)
 	{
-		event = mpv->mpv_ctx?mpv_wait_event(mpv->mpv_ctx, 0):NULL;
+		mpv_event *event =	mpv->mpv_ctx?
+					mpv_wait_event(mpv->mpv_ctx, 0):
+					NULL;
 
 		if(!event)
 		{
@@ -209,20 +160,21 @@ static gboolean mpv_event_handler(gpointer data)
 		}
 		else if(event->event_id == MPV_EVENT_IDLE)
 		{
-			if(mpv->priv->state.loaded)
+			if(mpv->state.loaded)
 			{
-				mpv->priv->state.loaded = FALSE;
+				mpv->state.loaded = FALSE;
 
-				mpv_obj_set_property_flag(mpv, "pause", TRUE);
-				playlist_reset(mpv->playlist);
+				gmpv_mpv_obj_set_property_flag
+					(mpv, "pause", TRUE);
+				gmpv_playlist_reset(mpv->playlist);
 			}
 
-			mpv->priv->state.init_load = FALSE;
+			mpv->state.init_load = FALSE;
 		}
 		else if(event->event_id == MPV_EVENT_FILE_LOADED)
 		{
-			mpv->priv->state.loaded = TRUE;
-			mpv->priv->state.init_load = FALSE;
+			mpv->state.loaded = TRUE;
+			mpv->state.init_load = FALSE;
 
 			mpv_obj_update_playlist(mpv);
 		}
@@ -230,11 +182,11 @@ static gboolean mpv_event_handler(gpointer data)
 		{
 			mpv_event_end_file *ef_event = event->data;
 
-			mpv->priv->state.init_load = FALSE;
+			mpv->state.init_load = FALSE;
 
-			if(mpv->priv->state.loaded)
+			if(mpv->state.loaded)
 			{
-				mpv->priv->state.new_file = FALSE;
+				mpv->state.new_file = FALSE;
 			}
 
 			if(ef_event->reason == MPV_END_FILE_REASON_ERROR)
@@ -248,15 +200,16 @@ static gboolean mpv_event_handler(gpointer data)
 						"abnormally. Reason: %s."),
 						err );
 
-				mpv_obj_set_property_flag(mpv, "pause", TRUE);
+				gmpv_mpv_obj_set_property_flag
+					(mpv, "pause", TRUE);
 				g_signal_emit_by_name(mpv, "mpv-error", msg);
 			}
 		}
 		else if(event->event_id == MPV_EVENT_VIDEO_RECONFIG)
 		{
-			if(mpv->priv->state.new_file)
+			if(mpv->state.new_file)
 			{
-				mpv_opt_handle_autofit(mpv);
+				gmpv_mpv_opt_handle_autofit(mpv);
 			}
 		}
 		else if(event->event_id == MPV_EVENT_PLAYBACK_RESTART)
@@ -275,9 +228,10 @@ static gboolean mpv_event_handler(gpointer data)
 
 		if(event)
 		{
-			if(mpv->mpv_event_handler)
+			if(mpv->event_callback)
 			{
-				mpv->mpv_event_handler(event, data);
+				mpv->event_callback
+					(event, mpv->event_callback_data);
 			}
 
 			if(mpv->mpv_ctx)
@@ -295,13 +249,13 @@ static gboolean mpv_event_handler(gpointer data)
 	return FALSE;
 }
 
-static void mpv_obj_update_playlist(MpvObj *mpv)
+static void mpv_obj_update_playlist(GmpvMpvObj *mpv)
 {
 	/* The length of "playlist//filename" including null-terminator (19)
 	 * plus the number of digits in the maximum value of 64 bit int (19).
 	 */
 	const gsize filename_prop_str_size = 38;
-	GtkListStore *store = playlist_get_store(mpv->playlist);
+	GtkListStore *store = gmpv_playlist_get_store(mpv->playlist);
 	gchar *filename_prop_str = g_malloc(filename_prop_str_size);
 	gboolean iter_end = FALSE;
 	GtkTreeIter iter;
@@ -339,7 +293,7 @@ static void mpv_obj_update_playlist(MpvObj *mpv)
 				->values[3].u.string;
 		}
 
-		name = title?title:get_name_from_path(uri);
+		name = title?g_strdup(title):get_name_from_path(uri);
 
 		if(!iter_end)
 		{
@@ -373,10 +327,9 @@ static void mpv_obj_update_playlist(MpvObj *mpv)
 		 */
 		else
 		{
-			playlist_append(mpv->playlist, name, uri);
+			gmpv_playlist_append(mpv->playlist, name, uri);
 		}
 
-		mpv_free(uri);
 		g_free(name);
 	}
 
@@ -460,7 +413,7 @@ static gint mpv_obj_apply_args(mpv_handle *mpv_ctx, gchar *args)
 	return fail_count*(-1);
 }
 
-static void mpv_obj_log_handler(MpvObj *mpv, mpv_event_log_message* message)
+static void mpv_obj_log_handler(GmpvMpvObj *mpv, mpv_event_log_message* message)
 {
 	GSList *iter = mpv->log_level_list;
 	module_log_level *level = NULL;
@@ -522,7 +475,7 @@ static void mpv_obj_log_handler(MpvObj *mpv, mpv_event_log_message* message)
 	}
 }
 
-static void load_input_conf(MpvObj *mpv, const gchar *input_conf)
+static void load_input_conf(GmpvMpvObj *mpv, const gchar *input_conf)
 {
 	const gchar *default_keybinds[] = DEFAULT_KEYBINDS;
 	gchar *tmp_path;
@@ -590,36 +543,13 @@ static void load_input_conf(MpvObj *mpv, const gchar *input_conf)
 	fclose(tmp_file);
 }
 
-static void uninit_opengl_cb(MpvObj *mpv)
-{
-	gtk_gl_area_make_current(mpv->priv->glarea);
-	mpv_opengl_cb_uninit_gl(mpv->opengl_ctx);
-}
-
-static void mpv_obj_class_init(MpvObjClass* klass)
+static void gmpv_mpv_obj_class_init(GmpvMpvObjClass* klass)
 {
 	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
 	GParamSpec *pspec = NULL;
 
-	obj_class->set_property = mpv_obj_set_inst_property;
-	obj_class->get_property = mpv_obj_get_inst_property;
-
-	pspec = g_param_spec_boolean
-		(	"use-opengl",
-			"Use OpenGL",
-			"Whether or not to use opengl-cb",
-			FALSE,
-			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
-
-	g_object_class_install_property(obj_class, PROP_USE_OPENGL, pspec);
-
-	pspec = g_param_spec_pointer
-		(	"glarea",
-			"GLArea",
-			"The GtkGLArea to render onto",
-			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
-
-	g_object_class_install_property(obj_class, PROP_GLAREA, pspec);
+	obj_class->set_property = gmpv_mpv_obj_set_inst_property;
+	obj_class->get_property = gmpv_mpv_obj_get_inst_property;
 
 	pspec = g_param_spec_int64
 		(	"wid",
@@ -628,15 +558,15 @@ static void mpv_obj_class_init(MpvObjClass* klass)
 			G_MININT64,
 			G_MAXINT64,
 			-1,
-			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
+			G_PARAM_READWRITE );
 
 	g_object_class_install_property(obj_class, PROP_WID, pspec);
 
 	pspec = g_param_spec_pointer
 		(	"playlist",
 			"Playlist",
-			"Playlist object to use for storage",
-			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
+			"GmpvPlaylist to use for storage",
+			G_PARAM_READWRITE );
 
 	g_object_class_install_property(obj_class, PROP_PLAYLIST, pspec);
 
@@ -694,56 +624,52 @@ static void mpv_obj_class_init(MpvObjClass* klass)
 			G_TYPE_STRING );
 }
 
-static void mpv_obj_init(MpvObj *mpv)
+static void gmpv_mpv_obj_init(GmpvMpvObj *mpv)
 {
-	mpv->priv = mpv_obj_get_instance_private(mpv);
 	mpv->mpv_ctx = mpv_create();
 	mpv->opengl_ctx = NULL;
 	mpv->playlist = NULL;
 	mpv->tmp_input_file = NULL;
 	mpv->log_level_list = NULL;
 	mpv->autofit_ratio = -1;
-	mpv->mpv_event_handler = NULL;
-
-	mpv->priv->state.ready = FALSE;
-	mpv->priv->state.paused = TRUE;
-	mpv->priv->state.loaded = FALSE;
-	mpv->priv->state.new_file = TRUE;
-	mpv->priv->state.init_load = TRUE;
-
-	mpv->priv->use_opengl = FALSE;
-	mpv->priv->glarea = NULL;
-	mpv->priv->wid = -1;
-	mpv->priv->wakeup_callback_data = NULL;
-	mpv->priv->opengl_cb_callback_data = NULL;
-	mpv->priv->wakeup_callback = NULL;
-	mpv->priv->opengl_cb_callback = NULL;
+
+	mpv->state.ready = FALSE;
+	mpv->state.paused = TRUE;
+	mpv->state.loaded = FALSE;
+	mpv->state.new_file = TRUE;
+	mpv->state.init_load = TRUE;
+
+	mpv->force_opengl = FALSE;
+	mpv->glarea = NULL;
+	mpv->wid = -1;
+	mpv->event_callback_data = NULL;
+	mpv->opengl_cb_callback_data = NULL;
+	mpv->event_callback = NULL;
+	mpv->opengl_cb_callback = NULL;
 }
 
-MpvObj *mpv_obj_new(	Playlist *playlist,
-			gboolean use_opengl,
-			gint64 wid,
-			GtkGLArea *glarea )
+GmpvMpvObj *gmpv_mpv_obj_new(GmpvPlaylist *playlist, gint64 wid)
 {
-	return MPV_OBJ(g_object_new(	mpv_obj_get_type(),
-					"playlist", playlist,
-					"use-opengl", use_opengl,
-					"wid", wid,
-					"glarea", glarea,
-					NULL ));
+	return GMPV_MPV_OBJ(g_object_new(	gmpv_mpv_obj_get_type(),
+						"playlist", playlist,
+						"wid", wid,
+						NULL ));
 }
 
-gint mpv_obj_command(MpvObj *mpv, const gchar **cmd)
+gint gmpv_mpv_obj_command(GmpvMpvObj *mpv, const gchar **cmd)
 {
-	gint rc;
+	gint rc = MPV_ERROR_UNINITIALIZED;
 
-	rc = mpv_command(mpv->mpv_ctx, cmd);
+	if(mpv->mpv_ctx)
+	{
+		rc = mpv_command(mpv->mpv_ctx, cmd);
+	}
 
 	if(rc < 0)
 	{
 		gchar *cmd_str = g_strjoinv(" ", (gchar **)cmd);
 
-		g_warning(	"Failed to run mpv command \"%s\". Reason: %s",
+		g_warning(	"Failed to run mpv command \"%s\". Reason: %s.",
 				cmd_str,
 				mpv_error_string(rc) );
 
@@ -753,16 +679,19 @@ gint mpv_obj_command(MpvObj *mpv, const gchar **cmd)
 	return rc;
 }
 
-gint mpv_obj_command_string(MpvObj *mpv, const gchar *cmd)
+gint gmpv_mpv_obj_command_string(GmpvMpvObj *mpv, const gchar *cmd)
 {
-	gint rc;
+	gint rc = MPV_ERROR_UNINITIALIZED;
 
-	rc = mpv_command_string(mpv->mpv_ctx, cmd);
+	if(mpv->mpv_ctx)
+	{
+		rc = mpv_command_string(mpv->mpv_ctx, cmd);
+	}
 
 	if(rc < 0)
 	{
 		g_warning(	"Failed to run mpv command string \"%s\". "
-				"Reason: %s",
+				"Reason: %s.",
 				cmd,
 				mpv_error_string(rc) );
 	}
@@ -770,19 +699,22 @@ gint mpv_obj_command_string(MpvObj *mpv, const gchar *cmd)
 	return rc;
 }
 
-gint mpv_obj_get_property(	MpvObj *mpv,
+gint gmpv_mpv_obj_get_property(	GmpvMpvObj *mpv,
 				const gchar *name,
 				mpv_format format,
 				void *data )
 {
-	gint rc;
+	gint rc = MPV_ERROR_UNINITIALIZED;
 
-	rc = mpv_get_property(mpv->mpv_ctx, name, format, data);
+	if(mpv->mpv_ctx)
+	{
+		rc = mpv_get_property(mpv->mpv_ctx, name, format, data);
+	}
 
 	if(rc < 0)
 	{
 		g_info(	"Failed to retrieve property \"%s\" "
-			"using mpv format %d. Reason %s",
+			"using mpv format %d. Reason: %s.",
 			name,
 			format,
 			mpv_error_string(rc) );
@@ -791,9 +723,14 @@ gint mpv_obj_get_property(	MpvObj *mpv,
 	return rc;
 }
 
-gchar *mpv_obj_get_property_string(MpvObj *mpv, const gchar *name)
+gchar *gmpv_mpv_obj_get_property_string(GmpvMpvObj *mpv, const gchar *name)
 {
-	gchar *value = mpv_get_property_string(mpv->mpv_ctx, name);
+	gchar *value = NULL;
+
+	if(mpv->mpv_ctx)
+	{
+		value = mpv_get_property_string(mpv->mpv_ctx, name);
+	}
 
 	if(!value)
 	{
@@ -803,17 +740,21 @@ gchar *mpv_obj_get_property_string(MpvObj *mpv, const gchar *name)
 	return value;
 }
 
-gboolean mpv_obj_get_property_flag(MpvObj *mpv, const gchar *name)
+gboolean gmpv_mpv_obj_get_property_flag(GmpvMpvObj *mpv, const gchar *name)
 {
 	gboolean value = FALSE;
-	gint rc;
+	gint rc = MPV_ERROR_UNINITIALIZED;
 
-	rc = mpv_get_property(mpv->mpv_ctx, name, MPV_FORMAT_FLAG, &value);
+	if(mpv->mpv_ctx)
+	{
+		rc =	mpv_get_property
+			(mpv->mpv_ctx, name, MPV_FORMAT_FLAG, &value);
+	}
 
 	if(rc < 0)
 	{
 		g_info(	"Failed to retrieve property \"%s\" as flag. "
-			"Reason: %s",
+			"Reason: %s.",
 			name,
 			mpv_error_string(rc) );
 	}
@@ -821,19 +762,22 @@ gboolean mpv_obj_get_property_flag(MpvObj *mpv, const gchar *name)
 	return value;
 }
 
-gint mpv_obj_set_property(	MpvObj *mpv,
+gint gmpv_mpv_obj_set_property(	GmpvMpvObj *mpv,
 				const gchar *name,
 				mpv_format format,
 				void *data )
 {
-	gint rc;
+	gint rc = MPV_ERROR_UNINITIALIZED;
 
-	rc = mpv_set_property(mpv->mpv_ctx, name, format, data);
+	if(mpv->mpv_ctx)
+	{
+		rc = mpv_set_property(mpv->mpv_ctx, name, format, data);
+	}
 
 	if(rc < 0)
 	{
 		g_info(	"Failed to set property \"%s\" using mpv format %d. "
-			"Reason: %s",
+			"Reason: %s.",
 			name,
 			format,
 			mpv_error_string(rc) );
@@ -842,17 +786,20 @@ gint mpv_obj_set_property(	MpvObj *mpv,
 	return rc;
 }
 
-gint mpv_obj_set_property_string(	MpvObj *mpv,
+gint gmpv_mpv_obj_set_property_string(	GmpvMpvObj *mpv,
 					const gchar *name,
 					const char *data )
 {
-	gint rc;
+	gint rc = MPV_ERROR_UNINITIALIZED;
 
-	rc = mpv_set_property_string(mpv->mpv_ctx, name, data);
+	if(mpv->mpv_ctx)
+	{
+		rc = mpv_set_property_string(mpv->mpv_ctx, name, data);
+	}
 
 	if(rc < 0)
 	{
-		g_info(	"Failed to set property \"%s\" as string. Reason: %s",
+		g_info(	"Failed to set property \"%s\" as string. Reason: %s.",
 			name,
 			mpv_error_string(rc) );
 	}
@@ -860,17 +807,21 @@ gint mpv_obj_set_property_string(	MpvObj *mpv,
 	return rc;
 }
 
-gint mpv_obj_set_property_flag(	MpvObj *mpv,
-				const gchar *name,
-				gboolean value )
+gint gmpv_mpv_obj_set_property_flag(	GmpvMpvObj *mpv,
+					const gchar *name,
+					gboolean value )
 {
-	gint rc;
+	gint rc = MPV_ERROR_UNINITIALIZED;
 
-	rc = mpv_set_property(mpv->mpv_ctx, name, MPV_FORMAT_FLAG, &value);
+	if(mpv->mpv_ctx)
+	{
+		rc =	mpv_set_property
+			(mpv->mpv_ctx, name, MPV_FORMAT_FLAG, &value);
+	}
 
 	if(rc < 0)
 	{
-		g_info(	"Failed to set property \"%s\" as flag. Reason: %s",
+		g_info(	"Failed to set property \"%s\" as flag. Reason: %s.",
 			name,
 			mpv_error_string(rc) );
 	}
@@ -878,29 +829,25 @@ gint mpv_obj_set_property_flag(	MpvObj *mpv,
 	return rc;
 }
 
-void mpv_obj_set_wakup_callback(	MpvObj *mpv,
-					void (*func)(void *),
+void gmpv_mpv_obj_set_event_callback(	GmpvMpvObj *mpv,
+					void (*func)(mpv_event *, void *),
 					void *data )
 {
-	mpv->priv->wakeup_callback = func;
-	mpv->priv->wakeup_callback_data = data;
-
-	mpv_set_wakeup_callback(mpv->mpv_ctx, func, data);
+	mpv->event_callback = func;
+	mpv->event_callback_data = data;
 }
 
-void mpv_obj_set_opengl_cb_callback(	MpvObj *mpv,
-					mpv_opengl_cb_update_fn func,
-					void *data )
+void gmpv_mpv_obj_set_opengl_cb_callback(	GmpvMpvObj *mpv,
+						mpv_opengl_cb_update_fn func,
+						void *data )
 {
-	mpv->priv->opengl_cb_callback = func;
-	mpv->priv->opengl_cb_callback_data = data;
+	mpv->opengl_cb_callback = func;
+	mpv->opengl_cb_callback_data = data;
 
-	mpv_opengl_cb_set_update_callback(mpv->opengl_ctx, func, data);
-}
-
-void mpv_obj_wakeup_callback(void *data)
-{
-	g_idle_add((GSourceFunc)mpv_event_handler, data);
+	if(mpv->opengl_ctx)
+	{
+		mpv_opengl_cb_set_update_callback(mpv->opengl_ctx, func, data);
+	}
 }
 
 void mpv_check_error(int status)
@@ -920,23 +867,44 @@ void mpv_check_error(int status)
 	}
 }
 
-inline gboolean mpv_obj_is_loaded(MpvObj *mpv)
+inline gboolean gmpv_mpv_obj_is_loaded(GmpvMpvObj *mpv)
+{
+	return mpv->state.loaded;
+}
+
+inline void gmpv_mpv_obj_get_state(GmpvMpvObj *mpv, GmpvMpvObjState *state)
+{
+	memcpy(state, &mpv->state, sizeof(GmpvMpvObjState));
+}
+
+inline gdouble gmpv_mpv_obj_get_autofit_ratio(GmpvMpvObj *mpv)
+{
+	return mpv->autofit_ratio;
+}
+
+inline GmpvPlaylist *gmpv_mpv_obj_get_playlist(GmpvMpvObj *mpv)
 {
-	return mpv->priv->state.loaded;
+	return mpv->playlist;
 }
 
-inline void mpv_obj_get_state(MpvObj *mpv, MpvObjState *state)
+inline mpv_handle *gmpv_mpv_obj_get_mpv_handle(GmpvMpvObj *mpv)
 {
-	memcpy(state, &mpv->priv->state, sizeof(MpvObjState));
+	return mpv->mpv_ctx;
 }
 
-void mpv_obj_initialize(MpvObj *mpv)
+inline mpv_opengl_cb_context *gmpv_mpv_obj_get_opengl_cb_context(GmpvMpvObj *mpv)
+{
+	return mpv->opengl_ctx;
+}
+
+void gmpv_mpv_obj_initialize(GmpvMpvObj *mpv)
 {
 	GSettings *main_settings = g_settings_new(CONFIG_ROOT);
 	GSettings *win_settings = g_settings_new(CONFIG_WIN_STATE);
 	gdouble volume = g_settings_get_double(win_settings, "volume")*100;
 	gchar *config_dir = get_config_dir_path();
 	gchar *mpvopt = NULL;
+	gchar *current_vo = NULL;
 
 	const struct
 	{
@@ -961,6 +929,8 @@ void mpv_obj_initialize(MpvObj *mpv)
 			{"config-dir", config_dir},
 			{NULL, NULL} };
 
+	g_assert(mpv->mpv_ctx);
+
 	for(gint i = 0; options[i].name; i++)
 	{
 		g_debug(	"Applying default option --%s=%s",
@@ -1016,50 +986,62 @@ void mpv_obj_initialize(MpvObj *mpv)
 		g_signal_emit_by_name(mpv, "mpv-error", g_strdup(msg));
 	}
 
-	if(mpv->priv->use_opengl)
+	if(mpv->force_opengl)
 	{
-		g_info("opengl-cb is enabled; forcing --vo=opengl-cb");
+		g_info("Forcing --vo=opengl-cb");
 		mpv_set_option_string(mpv->mpv_ctx, "vo", "opengl-cb");
 
 	}
 	else
 	{
 		g_debug(	"Attaching mpv window to wid %#x",
-				(guint)mpv->priv->wid );
+				(guint)mpv->wid );
 
-		mpv_set_option(	mpv->mpv_ctx,
-				"wid",
-				MPV_FORMAT_INT64,
-				&mpv->priv->wid );
+		mpv_set_option(mpv->mpv_ctx, "wid", MPV_FORMAT_INT64, &mpv->wid);
 	}
 
 	mpv_observe_property(mpv->mpv_ctx, 0, "aid", MPV_FORMAT_INT64);
 	mpv_observe_property(mpv->mpv_ctx, 0, "chapters", MPV_FORMAT_INT64);
+	mpv_observe_property(mpv->mpv_ctx, 0, "core-idle", MPV_FORMAT_FLAG);
 	mpv_observe_property(mpv->mpv_ctx, 0, "pause", MPV_FORMAT_FLAG);
 	mpv_observe_property(mpv->mpv_ctx, 0, "length", MPV_FORMAT_DOUBLE);
 	mpv_observe_property(mpv->mpv_ctx, 0, "media-title", MPV_FORMAT_STRING);
 	mpv_observe_property(mpv->mpv_ctx, 0, "playlist-pos", MPV_FORMAT_INT64);
 	mpv_observe_property(mpv->mpv_ctx, 0, "track-list", MPV_FORMAT_NODE);
 	mpv_observe_property(mpv->mpv_ctx, 0, "volume", MPV_FORMAT_DOUBLE);
+	mpv_set_wakeup_callback(mpv->mpv_ctx, wakeup_callback, mpv);
 	mpv_check_error(mpv_initialize(mpv->mpv_ctx));
 
-	mpv->opengl_ctx = mpv_get_sub_api(mpv->mpv_ctx, MPV_SUB_API_OPENGL_CB);
+	current_vo = gmpv_mpv_obj_get_property_string(mpv, "current-vo");
 
-	if(mpv->priv->use_opengl)
+	if(current_vo && !GDK_IS_X11_DISPLAY(gdk_display_get_default()))
 	{
-		gtk_gl_area_make_current(mpv->priv->glarea);
+		g_info(	"The chosen vo is %s but the display is not X11; "
+			"forcing --vo=opengl-cb and resetting",
+			current_vo );
 
-		mpv_check_error(mpv_opengl_cb_init_gl
-					(	mpv->opengl_ctx,
-						NULL,
-						get_proc_address,
-						NULL ));
+		mpv->force_opengl = TRUE;
+		mpv->state.paused = FALSE;
+
+		mpv_free(current_vo);
+		gmpv_mpv_obj_reset(mpv);
 	}
+	else
+	{
+		/* The vo should be opengl-cb if current_vo is NULL*/
+		if(!current_vo)
+		{
+			mpv->opengl_ctx =	mpv_get_sub_api
+						(	mpv->mpv_ctx,
+							MPV_SUB_API_OPENGL_CB );
+		}
 
-	mpv_opt_handle_msg_level(mpv);
+		gmpv_mpv_opt_handle_msg_level(mpv);
 
-	mpv->priv->state.ready = TRUE;
-	g_signal_emit_by_name(mpv, "mpv-init");
+		mpv->force_opengl = FALSE;
+		mpv->state.ready = TRUE;
+		g_signal_emit_by_name(mpv, "mpv-init");
+	}
 
 	g_clear_object(&main_settings);
 	g_clear_object(&win_settings);
@@ -1067,7 +1049,7 @@ void mpv_obj_initialize(MpvObj *mpv)
 	g_free(mpvopt);
 }
 
-void mpv_obj_reset(MpvObj *mpv)
+void gmpv_mpv_obj_reset(GmpvMpvObj *mpv)
 {
 	const gchar *quit_cmd[] = {"quit_watch_later", NULL};
 	gchar *loop_str;
@@ -1075,9 +1057,9 @@ void mpv_obj_reset(MpvObj *mpv)
 	gint64 playlist_pos;
 	gint playlist_pos_rc;
 
-	mpv_check_error(mpv_obj_set_property_string(mpv, "pause", "yes"));
+	g_assert(mpv->mpv_ctx);
 
-	loop_str = mpv_obj_get_property_string(mpv, "loop");
+	loop_str = gmpv_mpv_obj_get_property_string(mpv, "loop");
 	loop = (g_strcmp0(loop_str, "inf") == 0);
 
 	mpv_free(loop_str);
@@ -1088,31 +1070,28 @@ void mpv_obj_reset(MpvObj *mpv)
 						&playlist_pos );
 
 	/* Reset mpv->mpv_ctx */
-	mpv->priv->state.ready = FALSE;
+	mpv->state.ready = FALSE;
 
-	mpv_check_error(mpv_obj_command(mpv, quit_cmd));
-	mpv_obj_quit(mpv);
+	mpv_check_error(gmpv_mpv_obj_command(mpv, quit_cmd));
+	gmpv_mpv_obj_quit(mpv);
 
 	mpv->mpv_ctx = mpv_create();
-	mpv_obj_initialize(mpv);
+	gmpv_mpv_obj_initialize(mpv);
 
-	mpv_obj_set_wakup_callback
+	gmpv_mpv_obj_set_event_callback
 		(	mpv,
-			mpv->priv->wakeup_callback,
-			mpv->priv->wakeup_callback_data );
-
-	mpv_obj_set_opengl_cb_callback
+			mpv->event_callback,
+			mpv->event_callback_data );
+	gmpv_mpv_obj_set_opengl_cb_callback
 		(	mpv,
-			mpv->priv->opengl_cb_callback,
-			mpv->priv->opengl_cb_callback_data );
+			mpv->opengl_cb_callback,
+			mpv->opengl_cb_callback_data );
 
-	mpv_obj_set_property_string(	mpv,
-					"loop",
-					loop?"inf":"no" );
+	gmpv_mpv_obj_set_property_string(mpv, "loop", loop?"inf":"no");
 
 	if(mpv->playlist)
 	{
-		if(mpv->priv->state.loaded)
+		if(mpv->state.loaded)
 		{
 			gint rc;
 
@@ -1120,7 +1099,7 @@ void mpv_obj_reset(MpvObj *mpv)
 				(mpv->mpv_ctx, MPV_EVENT_FILE_LOADED, 0);
 			mpv_check_error(rc);
 
-			mpv_obj_load(mpv, NULL, FALSE, TRUE);
+			gmpv_mpv_obj_load(mpv, NULL, FALSE, TRUE);
 
 			rc =	mpv_request_event
 				(mpv->mpv_ctx, MPV_EVENT_FILE_LOADED, 1);
@@ -1129,20 +1108,20 @@ void mpv_obj_reset(MpvObj *mpv)
 
 		if(playlist_pos_rc >= 0 && playlist_pos > 0)
 		{
-			mpv_obj_set_property(	mpv,
-						"playlist-pos",
-						MPV_FORMAT_INT64,
-						&playlist_pos );
+			gmpv_mpv_obj_set_property(	mpv,
+							"playlist-pos",
+							MPV_FORMAT_INT64,
+							&playlist_pos );
 		}
 
-		mpv_obj_set_property(	mpv,
-					"pause",
-					MPV_FORMAT_FLAG,
-					&mpv->priv->state.paused );
+		gmpv_mpv_obj_set_property(	mpv,
+						"pause",
+						MPV_FORMAT_FLAG,
+						&mpv->state.paused );
 	}
 }
 
-void mpv_obj_quit(MpvObj *mpv)
+void gmpv_mpv_obj_quit(GmpvMpvObj *mpv)
 {
 	g_info("Terminating mpv");
 
@@ -1151,26 +1130,27 @@ void mpv_obj_quit(MpvObj *mpv)
 		g_unlink(mpv->tmp_input_file);
 	}
 
-	if(mpv->priv->use_opengl)
+	if(mpv->opengl_ctx)
 	{
 		g_debug("Uninitializing opengl-cb");
-		uninit_opengl_cb(mpv);
+		mpv_opengl_cb_uninit_gl(mpv->opengl_ctx);
 
 		mpv->opengl_ctx = NULL;
 	}
 
+	g_assert(mpv->mpv_ctx);
 	mpv_terminate_destroy(mpv->mpv_ctx);
 
 	mpv->mpv_ctx = NULL;
 }
 
-void mpv_obj_load(	MpvObj *mpv,
+void gmpv_mpv_obj_load(	GmpvMpvObj *mpv,
 			const gchar *uri,
 			gboolean append,
 			gboolean update )
 {
 	const gchar *load_cmd[] = {"loadfile", NULL, NULL, NULL};
-	GtkListStore *playlist_store = playlist_get_store(mpv->playlist);
+	GtkListStore *playlist_store = gmpv_playlist_get_store(mpv->playlist);
 	GtkTreeIter iter;
 	gboolean empty;
 
@@ -1186,10 +1166,10 @@ void mpv_obj_load(	MpvObj *mpv,
 
 	if(!append && uri && update)
 	{
-		playlist_clear(mpv->playlist);
+		gmpv_playlist_clear(mpv->playlist);
 
-		mpv->priv->state.new_file = TRUE;
-		mpv->priv->state.loaded = FALSE;
+		mpv->state.new_file = TRUE;
+		mpv->state.loaded = FALSE;
 	}
 
 	if(!uri)
@@ -1197,9 +1177,9 @@ void mpv_obj_load(	MpvObj *mpv,
 		gboolean append = FALSE;
 		gboolean rc;
 
-		if(!mpv->priv->state.init_load)
+		if(!mpv->state.init_load)
 		{
-			mpv_obj_set_property_flag(mpv, "pause", FALSE);
+			gmpv_mpv_obj_set_property_flag(mpv, "pause", FALSE);
 		}
 
 		rc = gtk_tree_model_get_iter_first
@@ -1216,7 +1196,7 @@ void mpv_obj_load(	MpvObj *mpv,
 						-1 );
 
 			/* append = FALSE only on first iteration */
-			mpv_obj_load(mpv, uri, append, FALSE);
+			gmpv_mpv_obj_load(mpv, uri, append, FALSE);
 
 			append = TRUE;
 
@@ -1235,11 +1215,12 @@ void mpv_obj_load(	MpvObj *mpv,
 
 		if(!append)
 		{
-			mpv->priv->state.loaded = FALSE;
+			mpv->state.loaded = FALSE;
 
-			if(!mpv->priv->state.init_load)
+			if(!mpv->state.init_load)
 			{
-				mpv_obj_set_property_flag(mpv, "pause", FALSE);
+				gmpv_mpv_obj_set_property_flag
+					(mpv, "pause", FALSE);
 			}
 		}
 
@@ -1247,11 +1228,13 @@ void mpv_obj_load(	MpvObj *mpv,
 		{
 			gchar *name = get_name_from_path(path);
 
-			playlist_append(mpv->playlist, name, uri);
+			gmpv_playlist_append(mpv->playlist, name, uri);
 
 			g_free(name);
 		}
 
+		g_assert(mpv->mpv_ctx);
+
 		mpv_check_error(mpv_request_event(	mpv->mpv_ctx,
 							MPV_EVENT_END_FILE,
 							0 ));
@@ -1266,10 +1249,10 @@ void mpv_obj_load(	MpvObj *mpv,
 	}
 }
 
-void mpv_obj_load_list(	MpvObj *mpv,
-			const gchar **uri_list,
-			gboolean append,
-			gboolean update )
+void gmpv_mpv_obj_load_list(	GmpvMpvObj *mpv,
+				const gchar **uri_list,
+				gboolean append,
+				gboolean update )
 {
 	static const char *const sub_exts[]
 		= {	"utf", "utf8", "utf-8", "idx", "sub", "srt", "smi",
@@ -1296,7 +1279,7 @@ void mpv_obj_load_list(	MpvObj *mpv,
 		 * already is a file loaded. Try to load the file as a
 		 * media file otherwise.
 		 */
-		if(ext && sub_exts[j] && mpv_obj_is_loaded(mpv))
+		if(ext && sub_exts[j] && gmpv_mpv_obj_is_loaded(mpv))
 		{
 			const gchar *cmd[] = {"sub-add", NULL, NULL};
 			gchar *path;
@@ -1309,18 +1292,18 @@ void mpv_obj_load_list(	MpvObj *mpv,
 
 			cmd[1] = path?:uri_list[i];
 
-			mpv_obj_command(mpv, cmd);
+			gmpv_mpv_obj_command(mpv, cmd);
 
 			g_free(path);
 		}
 		else
 		{
-			gboolean empty = playlist_empty(mpv->playlist);
+			gboolean empty = gmpv_playlist_empty(mpv->playlist);
 
-			mpv_obj_load(	mpv,
-					uri_list[i],
-					((append && !empty) || i != 0),
-					TRUE );
+			gmpv_mpv_obj_load(	mpv,
+						uri_list[i],
+						((append && !empty) || i != 0),
+						TRUE );
 		}
 	}
 }
diff --git a/src/gmpv_mpv_obj.h b/src/gmpv_mpv_obj.h
new file mode 100644
index 0000000..767e624
--- /dev/null
+++ b/src/gmpv_mpv_obj.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014, 2016 gnome-mpv
+ *
+ * This file is part of GNOME MPV.
+ *
+ * GNOME MPV 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MPV_OBJ_H
+#define MPV_OBJ_H
+
+#include <gtk/gtk.h>
+#include <mpv/client.h>
+#include <mpv/opengl_cb.h>
+
+#include "gmpv_playlist.h"
+
+G_BEGIN_DECLS
+
+#define GMPV_TYPE_MPV_OBJ (gmpv_mpv_obj_get_type())
+
+G_DECLARE_FINAL_TYPE(GmpvMpvObj, gmpv_mpv_obj, GMPV, MPV_OBJ, GObject)
+
+typedef struct _GmpvMpvObjState GmpvMpvObjState;
+
+struct _GmpvMpvObjState
+{
+	gboolean ready;
+	gboolean paused;
+	gboolean loaded;
+	gboolean new_file;
+	gboolean init_load;
+};
+
+GmpvMpvObj *gmpv_mpv_obj_new(GmpvPlaylist *playlist, gint64 wid);
+gint gmpv_mpv_obj_command(GmpvMpvObj *mpv, const gchar **cmd);
+gint gmpv_mpv_obj_command_string(GmpvMpvObj *mpv, const gchar *cmd);
+gint gmpv_mpv_obj_get_property(	GmpvMpvObj *mpv,
+				const gchar *name,
+				mpv_format format,
+				void *data );
+gchar *gmpv_mpv_obj_get_property_string(GmpvMpvObj *mpv, const gchar *name);
+gboolean gmpv_mpv_obj_get_property_flag(GmpvMpvObj *mpv, const gchar *name);
+gint gmpv_mpv_obj_set_property(	GmpvMpvObj *mpv,
+				const gchar *name,
+				mpv_format format,
+				void *data );
+gint gmpv_mpv_obj_set_property_flag(	GmpvMpvObj *mpv,
+					const gchar *name,
+					gboolean value);
+gint gmpv_mpv_obj_set_property_string(	GmpvMpvObj *mpv,
+					const gchar *name,
+					const char *data );
+void gmpv_mpv_obj_set_event_callback(	GmpvMpvObj *mpv,
+					void (*func)(mpv_event *, void *),
+					void *data );
+void gmpv_mpv_obj_set_opengl_cb_callback(	GmpvMpvObj *mpv,
+						mpv_opengl_cb_update_fn func,
+						void *data );
+void mpv_check_error(int status);
+gboolean gmpv_mpv_obj_is_loaded(GmpvMpvObj *mpv);
+void gmpv_mpv_obj_get_state(GmpvMpvObj *mpv, GmpvMpvObjState *state);
+gdouble gmpv_mpv_obj_get_autofit_ratio(GmpvMpvObj *mpv);
+GmpvPlaylist *gmpv_mpv_obj_get_playlist(GmpvMpvObj *mpv);
+mpv_handle *gmpv_mpv_obj_get_mpv_handle(GmpvMpvObj *mpv);
+mpv_opengl_cb_context *gmpv_mpv_obj_get_opengl_cb_context(GmpvMpvObj *mpv);
+void gmpv_mpv_obj_initialize(GmpvMpvObj *mpv);
+void gmpv_mpv_obj_reset(GmpvMpvObj *mpv);
+void gmpv_mpv_obj_quit(GmpvMpvObj *mpv);
+void gmpv_mpv_obj_load(	GmpvMpvObj *mpv,
+			const gchar *uri,
+			gboolean append,
+			gboolean update );
+void gmpv_mpv_obj_load_list(	GmpvMpvObj *mpv,
+			const gchar **uri_list,
+			gboolean append,
+			gboolean update );
+
+G_END_DECLS
+
+#endif
diff --git a/src/mpv_opt.h b/src/gmpv_mpv_obj_private.h
similarity index 54%
copy from src/mpv_opt.h
copy to src/gmpv_mpv_obj_private.h
index 93e6920..ce68302 100644
--- a/src/mpv_opt.h
+++ b/src/gmpv_mpv_obj_private.h
@@ -17,22 +17,43 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef MPV_OPT_H
-#define MPV_OPT_H
+#ifndef MPV_OBJ_PRIVATE_H
+#define MPV_OBJ_PRIVATE_H
 
-#include <mpv/client.h>
+G_BEGIN_DECLS
 
-#include "mpv_obj.h"
+enum
+{
+	PROP_0,
+	PROP_WID,
+	PROP_PLAYLIST,
+	N_PROPERTIES
+};
 
-typedef struct module_log_level module_log_level;
+struct _GmpvMpvObj
+{
+	GObject parent;
+	GmpvMpvObjState state;
+	mpv_handle *mpv_ctx;
+	mpv_opengl_cb_context *opengl_ctx;
+	GmpvPlaylist *playlist;
+	GtkGLArea *glarea;
+	gchar *tmp_input_file;
+	GSList *log_level_list;
+	gdouble autofit_ratio;
+	gboolean force_opengl;
+	gint64 wid;
+	void *event_callback_data;
+	void *opengl_cb_callback_data;
+	void (*event_callback)(mpv_event *, void *data);
+	void (*opengl_cb_callback)(void *data);
+};
 
-struct module_log_level
+struct _GmpvMpvObjClass
 {
-	gchar *prefix;
-	mpv_log_level level;
+	GObjectClass parent_class;
 };
 
-void mpv_opt_handle_autofit(MpvObj *mpv);
-void mpv_opt_handle_msg_level(MpvObj *mpv);
+G_END_DECLS
 
 #endif
diff --git a/src/mpv_opt.c b/src/gmpv_mpv_opt.c
similarity index 97%
rename from src/mpv_opt.c
rename to src/gmpv_mpv_opt.c
index 7466687..92ed1d7 100644
--- a/src/mpv_opt.c
+++ b/src/gmpv_mpv_opt.c
@@ -20,8 +20,9 @@
 #include <string.h>
 #include <mpv/client.h>
 
-#include "mpv_opt.h"
-#include "def.h"
+#include "gmpv_mpv_opt.h"
+#include "gmpv_mpv_obj_private.h"
+#include "gmpv_def.h"
 
 static void parse_dim_string(const gchar *geom_str, gint dim[2]);
 
@@ -65,7 +66,7 @@ static void parse_dim_string(const gchar *geom_str, gint dim[2])
 	g_strfreev(tokens);
 }
 
-void mpv_opt_handle_autofit(MpvObj *mpv)
+void gmpv_mpv_opt_handle_autofit(GmpvMpvObj *mpv)
 {
 	gchar *scale_str = NULL;
 	gchar *autofit_str = NULL;
@@ -219,7 +220,7 @@ void mpv_opt_handle_autofit(MpvObj *mpv)
 	mpv_free(smaller_str);
 }
 
-void mpv_opt_handle_msg_level(MpvObj *mpv)
+void gmpv_mpv_opt_handle_msg_level(GmpvMpvObj *mpv)
 {
 	const struct
 	{
diff --git a/src/mpv_opt.h b/src/gmpv_mpv_opt.h
similarity index 85%
copy from src/mpv_opt.h
copy to src/gmpv_mpv_opt.h
index 93e6920..5bc2c5c 100644
--- a/src/mpv_opt.h
+++ b/src/gmpv_mpv_opt.h
@@ -22,7 +22,9 @@
 
 #include <mpv/client.h>
 
-#include "mpv_obj.h"
+#include "gmpv_mpv_obj.h"
+
+G_BEGIN_DECLS
 
 typedef struct module_log_level module_log_level;
 
@@ -32,7 +34,9 @@ struct module_log_level
 	mpv_log_level level;
 };
 
-void mpv_opt_handle_autofit(MpvObj *mpv);
-void mpv_opt_handle_msg_level(MpvObj *mpv);
+void gmpv_mpv_opt_handle_autofit(GmpvMpvObj *mpv);
+void gmpv_mpv_opt_handle_msg_level(GmpvMpvObj *mpv);
+
+G_END_DECLS
 
 #endif
diff --git a/src/open_loc_dialog.c b/src/gmpv_open_loc_dialog.c
similarity index 81%
rename from src/open_loc_dialog.c
rename to src/gmpv_open_loc_dialog.c
index c858c50..06b8e17 100644
--- a/src/open_loc_dialog.c
+++ b/src/gmpv_open_loc_dialog.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 gnome-mpv
+ * Copyright (c) 2014, 2016 gnome-mpv
  *
  * This file is part of GNOME MPV.
  *
@@ -19,10 +19,10 @@
 
 #include <glib/gi18n.h>
 
-#include "open_loc_dialog.h"
-#include "main_window.h"
+#include "gmpv_open_loc_dialog.h"
+#include "gmpv_main_window.h"
 
-struct _OpenLocDialog
+struct _GmpvOpenLocDialog
 {
 	GtkDialog parent_instance;
 	GtkWidget *content_area;
@@ -31,12 +31,12 @@ struct _OpenLocDialog
 	GtkWidget *loc_entry;
 };
 
-struct _OpenLocDialogClass
+struct _GmpvOpenLocDialogClass
 {
 	GtkDialogClass parent_class;
 };
 
-G_DEFINE_TYPE(OpenLocDialog, open_loc_dialog, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE(GmpvOpenLocDialog, gmpv_open_loc_dialog, GTK_TYPE_DIALOG)
 
 static gboolean key_press_handler (GtkWidget *widget, GdkEventKey *event)
 {
@@ -56,17 +56,18 @@ static gboolean key_press_handler (GtkWidget *widget, GdkEventKey *event)
 		gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_ACCEPT);
 	}
 
-	return GTK_WIDGET_CLASS(open_loc_dialog_parent_class)->key_press_event (widget, event);
+	return	GTK_WIDGET_CLASS(gmpv_open_loc_dialog_parent_class)
+		->key_press_event (widget, event);
 }
 
-static void open_loc_dialog_class_init(OpenLocDialogClass *klass)
+static void gmpv_open_loc_dialog_class_init(GmpvOpenLocDialogClass *klass)
 {
 	GtkWidgetClass *wid_class = GTK_WIDGET_CLASS(klass);
 
 	wid_class->key_press_event = key_press_handler;
 }
 
-static void open_loc_dialog_init(OpenLocDialog *dlg)
+static void gmpv_open_loc_dialog_init(GmpvOpenLocDialog *dlg)
 {
 	GdkGeometry geom;
 
@@ -121,15 +122,15 @@ static void open_loc_dialog_init(OpenLocDialog *dlg)
 	gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_ACCEPT);
 }
 
-GtkWidget *open_loc_dialog_new(GtkWindow *parent)
+GtkWidget *gmpv_open_loc_dialog_new(GtkWindow *parent)
 {
 	GtkWidget *dlg;
 	GtkWidget *header_bar;
 	gboolean csd_enabled;
 
-	csd_enabled = main_window_get_csd_enabled(MAIN_WINDOW(parent));
+	csd_enabled = gmpv_main_window_get_csd_enabled(GMPV_MAIN_WINDOW(parent));
 
-	dlg = g_object_new(	open_loc_dialog_get_type(),
+	dlg = g_object_new(	gmpv_open_loc_dialog_get_type(),
 				"use-header-bar", csd_enabled,
 				NULL );
 
@@ -158,12 +159,12 @@ GtkWidget *open_loc_dialog_new(GtkWindow *parent)
 	return dlg;
 }
 
-const gchar *open_loc_dialog_get_string(OpenLocDialog *dlg)
+const gchar *gmpv_open_loc_dialog_get_string(GmpvOpenLocDialog *dlg)
 {
 	return gtk_entry_get_text(GTK_ENTRY(dlg->loc_entry));
 }
 
-guint64 open_loc_dialog_get_string_length(OpenLocDialog *dlg)
+guint64 gmpv_open_loc_dialog_get_string_length(GmpvOpenLocDialog *dlg)
 {
 	return gtk_entry_get_text_length(GTK_ENTRY(dlg->loc_entry));
 }
diff --git a/src/mpv_opt.h b/src/gmpv_open_loc_dialog.h
similarity index 58%
copy from src/mpv_opt.h
copy to src/gmpv_open_loc_dialog.h
index 93e6920..52777c3 100644
--- a/src/mpv_opt.h
+++ b/src/gmpv_open_loc_dialog.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 gnome-mpv
+ * Copyright (c) 2014 gnome-mpv
  *
  * This file is part of GNOME MPV.
  *
@@ -17,22 +17,21 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef MPV_OPT_H
-#define MPV_OPT_H
+#ifndef OPEN_LOC_DIALOG_H
+#define OPEN_LOC_DIALOG_H
 
-#include <mpv/client.h>
+#include <gtk/gtk.h>
 
-#include "mpv_obj.h"
+G_BEGIN_DECLS
 
-typedef struct module_log_level module_log_level;
+#define GMPV_TYPE_OPEN_LOC_DIALOG (gmpv_open_loc_dialog_get_type ())
 
-struct module_log_level
-{
-	gchar *prefix;
-	mpv_log_level level;
-};
+G_DECLARE_FINAL_TYPE(GmpvOpenLocDialog, gmpv_open_loc_dialog, GMPV, OPEN_LOC_DIALOG, GtkDialog)
 
-void mpv_opt_handle_autofit(MpvObj *mpv);
-void mpv_opt_handle_msg_level(MpvObj *mpv);
+GtkWidget *gmpv_open_loc_dialog_new(GtkWindow *parent);
+const gchar *gmpv_open_loc_dialog_get_string(GmpvOpenLocDialog *dlg);
+guint64 gmpv_open_loc_dialog_get_string_length(GmpvOpenLocDialog *dlg);
+
+G_END_DECLS
 
 #endif
diff --git a/src/playbackctl.c b/src/gmpv_playbackctl.c
similarity index 72%
rename from src/playbackctl.c
rename to src/gmpv_playbackctl.c
index 6edff09..ca286c7 100644
--- a/src/playbackctl.c
+++ b/src/gmpv_playbackctl.c
@@ -19,10 +19,10 @@
 
 #include <gtk/gtk.h>
 
-#include "playbackctl.h"
-#include "control_box.h"
-#include "common.h"
-#include "mpv_obj.h"
+#include "gmpv_playbackctl.h"
+#include "gmpv_control_box.h"
+#include "gmpv_common.h"
+#include "gmpv_mpv_obj.h"
 
 static void play_handler(GtkWidget *widget, gpointer data);
 static void stop_handler(GtkWidget *widget, gpointer data);
@@ -36,20 +36,21 @@ static void fullscreen_handler(GtkWidget *button, gpointer data);
 
 static void play_handler(GtkWidget *widget, gpointer data)
 {
-	Application *app = data;
+	GmpvApplication *app = data;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(app);
 
-	mpv_obj_set_property_flag
-		(	app->mpv,
+	gmpv_mpv_obj_set_property_flag
+		(	mpv,
 			"pause",
-			!mpv_obj_get_property_flag(app->mpv, "pause") );
+			!gmpv_mpv_obj_get_property_flag(mpv, "pause") );
 }
 
 static void stop_handler(GtkWidget *widget, gpointer data)
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 	const gchar *cmd[] = {"stop", NULL};
 
-	mpv_obj_command(app->mpv, cmd);
+	gmpv_mpv_obj_command(gmpv_application_get_mpv_obj(app), cmd);
 }
 
 static void seek_handler(GtkWidget *widget, gdouble value, gpointer data)
@@ -59,53 +60,57 @@ static void seek_handler(GtkWidget *widget, gdouble value, gpointer data)
 
 static void forward_handler(GtkWidget *widget, gpointer data)
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 	const gchar *cmd[] = {"seek", "10", NULL};
 
-	mpv_obj_command(app->mpv, cmd);
+	gmpv_mpv_obj_command(gmpv_application_get_mpv_obj(app), cmd);
 }
 
 static void rewind_handler(GtkWidget *widget, gpointer data)
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 	const gchar *cmd[] = {"seek", "-10", NULL};
 
-	mpv_obj_command(app->mpv, cmd);
+	gmpv_mpv_obj_command(gmpv_application_get_mpv_obj(app), cmd);
 }
 
 static void chapter_previous_handler(GtkWidget *widget, gpointer data)
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 	const gchar *cmd[] = {"osd-msg", "cycle", "chapter", "down", NULL};
 
-	mpv_obj_command(app->mpv, cmd);
+	gmpv_mpv_obj_command(gmpv_application_get_mpv_obj(app), cmd);
 }
 
 static void chapter_next_handler(GtkWidget *widget, gpointer data)
 {
-	Application *app = data;
+	GmpvApplication *app = data;
 	const gchar *cmd[] = {"osd-msg", "cycle", "chapter", NULL};
 
-	mpv_obj_command(app->mpv, cmd);
+	gmpv_mpv_obj_command(gmpv_application_get_mpv_obj(app), cmd);
 }
 
 static void volume_handler(GtkWidget *widget, gdouble value, gpointer data)
 {
-	Application *app = data;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(GMPV_APPLICATION(data));
 
 	value *= 100;
 
-	mpv_obj_set_property(app->mpv, "volume", MPV_FORMAT_DOUBLE, &value);
+	gmpv_mpv_obj_set_property(mpv, "volume", MPV_FORMAT_DOUBLE, &value);
 }
 
 static void fullscreen_handler(GtkWidget *widget, gpointer data)
 {
-	main_window_toggle_fullscreen(APPLICATION(data)->gui);
+	GmpvMainWindow *wnd =	gmpv_application_get_main_window
+				(GMPV_APPLICATION(data));
+
+	gmpv_main_window_toggle_fullscreen(wnd);
 }
 
-void playbackctl_connect_signals(Application *app)
+void gmpv_playbackctl_connect_signals(GmpvApplication *app)
 {
-	ControlBox *control_box = CONTROL_BOX(app->gui->control_box);
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(app);
+	GmpvControlBox *control_box = gmpv_main_window_get_control_box(wnd);
 
 	const struct
 	{
diff --git a/src/playbackctl.h b/src/gmpv_playbackctl.h
similarity index 84%
rename from src/playbackctl.h
rename to src/gmpv_playbackctl.h
index 1e9254a..82ac2c6 100644
--- a/src/playbackctl.h
+++ b/src/gmpv_playbackctl.h
@@ -20,9 +20,13 @@
 #ifndef PLAYBACKCTL_H
 #define PLAYBACKCTL_H
 
-#include "playbackctl.h"
-#include "common.h"
+#include "gmpv_playbackctl.h"
+#include "gmpv_common.h"
 
-void playbackctl_connect_signals(Application *app);
+G_BEGIN_DECLS
+
+void gmpv_playbackctl_connect_signals(GmpvApplication *app);
+
+G_END_DECLS
 
 #endif
diff --git a/src/playlist.c b/src/gmpv_playlist.c
similarity index 79%
rename from src/playlist.c
rename to src/gmpv_playlist.c
index 2dc5bf3..6afda56 100644
--- a/src/playlist.c
+++ b/src/gmpv_playlist.c
@@ -19,21 +19,21 @@
 
 #include <glib/gi18n.h>
 
-#include "playlist.h"
-#include "marshal.h"
-#include "common.h"
-#include "mpv_obj.h"
-#include "control_box.h"
-#include "playlist_widget.h"
-
-struct _Playlist
+#include "gmpv_playlist.h"
+#include "gmpv_marshal.h"
+#include "gmpv_common.h"
+#include "gmpv_mpv_obj.h"
+#include "gmpv_control_box.h"
+#include "gmpv_playlist_widget.h"
+
+struct _GmpvPlaylist
 {
 	GObject parent;
 	GtkListStore *store;
 	gboolean move_dest;
 };
 
-struct _PlaylistClass
+struct _GmpvPlaylistClass
 {
 	GObjectClass parent_class;
 };
@@ -46,14 +46,14 @@ static void row_deleted_handler(	GtkTreeModel *tree_model,
 					GtkTreePath *path,
 					gpointer data );
 
-G_DEFINE_TYPE(Playlist, playlist, G_TYPE_OBJECT)
+G_DEFINE_TYPE(GmpvPlaylist, gmpv_playlist, G_TYPE_OBJECT)
 
 static void row_inserted_handler(	GtkTreeModel *tree_model,
 					GtkTreePath *path,
 					GtkTreeIter *iter,
 					gpointer data )
 {
-	Playlist *pl = data;
+	GmpvPlaylist *pl = data;
 	const gint dest = gtk_tree_path_get_indices(path)[0];
 
 	pl->move_dest = dest;
@@ -65,7 +65,7 @@ static void row_deleted_handler(	GtkTreeModel *tree_model,
 					GtkTreePath *path,
 					gpointer data )
 {
-	Playlist *pl = data;
+	GmpvPlaylist *pl = data;
 	const gint src = gtk_tree_path_get_indices(path)[0];
 	const gint dest = pl->move_dest;
 
@@ -81,7 +81,7 @@ static void row_deleted_handler(	GtkTreeModel *tree_model,
 	}
 }
 
-static void playlist_class_init(PlaylistClass *klass)
+static void gmpv_playlist_class_init(GmpvPlaylistClass *klass)
 {
 	g_signal_new(	"row-inserted",
 			G_TYPE_FROM_CLASS(klass),
@@ -93,7 +93,6 @@ static void playlist_class_init(PlaylistClass *klass)
 			G_TYPE_NONE,
 			1,
 			G_TYPE_INT );
-
 	g_signal_new(	"row-deleted",
 			G_TYPE_FROM_CLASS(klass),
 			G_SIGNAL_RUN_FIRST,
@@ -104,7 +103,6 @@ static void playlist_class_init(PlaylistClass *klass)
 			G_TYPE_NONE,
 			1,
 			G_TYPE_INT );
-
 	g_signal_new(	"row-reordered",
 			G_TYPE_FROM_CLASS(klass),
 			G_SIGNAL_RUN_FIRST,
@@ -118,7 +116,7 @@ static void playlist_class_init(PlaylistClass *klass)
 			G_TYPE_INT );
 }
 
-static void playlist_init(Playlist *pl)
+static void gmpv_playlist_init(GmpvPlaylist *pl)
 {
 	pl->store = gtk_list_store_new(	3,
 					G_TYPE_STRING,
@@ -131,24 +129,23 @@ static void playlist_init(Playlist *pl)
 				"row-inserted",
 				G_CALLBACK(row_inserted_handler),
 				pl );
-
 	g_signal_connect(	pl->store,
 				"row-deleted",
 				G_CALLBACK(row_deleted_handler),
 				pl );
 }
 
-Playlist *playlist_new()
+GmpvPlaylist *gmpv_playlist_new()
 {
-	return PLAYLIST(g_object_new(playlist_get_type(), NULL));
+	return GMPV_PLAYLIST(g_object_new(gmpv_playlist_get_type(), NULL));
 }
 
-GtkListStore *playlist_get_store(Playlist *pl)
+GtkListStore *gmpv_playlist_get_store(GmpvPlaylist *pl)
 {
 	return pl->store;
 }
 
-void playlist_append(Playlist *pl, const gchar *name, const gchar *uri)
+void gmpv_playlist_append(GmpvPlaylist *pl, const gchar *name, const gchar *uri)
 {
 	GtkTreeIter iter;
 
@@ -159,7 +156,7 @@ void playlist_append(Playlist *pl, const gchar *name, const gchar *uri)
 	pl->move_dest = -1;
 }
 
-void playlist_remove(Playlist *pl, gint pos)
+void gmpv_playlist_remove(GmpvPlaylist *pl, gint pos)
 {
 	GtkTreeIter iter;
 	gboolean rc;
@@ -178,19 +175,19 @@ void playlist_remove(Playlist *pl, gint pos)
 	}
 }
 
-void playlist_clear(Playlist *pl)
+void gmpv_playlist_clear(GmpvPlaylist *pl)
 {
 	gtk_list_store_clear(pl->store);
 }
 
-gboolean playlist_empty(Playlist *pl)
+gboolean gmpv_playlist_empty(GmpvPlaylist *pl)
 {
 	GtkTreeIter iter;
 
 	return !gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pl->store), &iter);
 }
 
-void playlist_set_indicator_pos(Playlist *pl, gint pos)
+void gmpv_playlist_set_indicator_pos(GmpvPlaylist *pl, gint pos)
 {
 	GtkTreeIter iter;
 	gboolean rc;
@@ -212,7 +209,7 @@ void playlist_set_indicator_pos(Playlist *pl, gint pos)
 	}
 }
 
-void playlist_reset(Playlist *pl)
+void gmpv_playlist_reset(GmpvPlaylist *pl)
 {
-	playlist_set_indicator_pos(pl, 0);
+	gmpv_playlist_set_indicator_pos(pl, 0);
 }
diff --git a/src/playlist.h b/src/gmpv_playlist.h
similarity index 53%
rename from src/playlist.h
rename to src/gmpv_playlist.h
index 4155e68..c6bc96b 100644
--- a/src/playlist.h
+++ b/src/gmpv_playlist.h
@@ -24,21 +24,9 @@
 
 G_BEGIN_DECLS
 
-#define PLAYLIST_TYPE (playlist_get_type ())
+#define GMPV_TYPE_PLAYLIST (gmpv_playlist_get_type ())
 
-#define	PLAYLIST(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST \
-		((obj), PLAYLIST_TYPE, Playlist))
-
-#define	PLAYLIST_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST \
-		((klass), PLAYLIST_TYPE, PlaylistClass))
-
-#define	IS_PLAYLIST(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), PLAYLIST_TYPE))
-
-#define	IS_PLAYLIST_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), PLAYLIST_TYPE))
+G_DECLARE_FINAL_TYPE(GmpvPlaylist, gmpv_playlist, GMPV, PLAYLIST, GObject)
 
 enum PlaylistStoreColumn
 {
@@ -49,18 +37,15 @@ enum PlaylistStoreColumn
 };
 
 typedef enum PlaylistStoreColumn PlaylistStoreColumn;
-typedef struct _Playlist Playlist;
-typedef struct _PlaylistClass PlaylistClass;
 
-Playlist *playlist_new(void);
-GType playlist_get_type(void);
-GtkListStore *playlist_get_store(Playlist *pl);
-void playlist_set_indicator_pos(Playlist *pl, gint pos);
-void playlist_append(Playlist *pl, const gchar *name, const gchar *uri);
-void playlist_remove(Playlist *pl, gint pos);
-void playlist_clear(Playlist *pl);
-gboolean playlist_empty(Playlist *pl);
-void playlist_reset(Playlist *pl);
+GmpvPlaylist *gmpv_playlist_new(void);
+GtkListStore *gmpv_playlist_get_store(GmpvPlaylist *pl);
+void gmpv_playlist_set_indicator_pos(GmpvPlaylist *pl, gint pos);
+void gmpv_playlist_append(GmpvPlaylist *pl, const gchar *name, const gchar *uri);
+void gmpv_playlist_remove(GmpvPlaylist *pl, gint pos);
+void gmpv_playlist_clear(GmpvPlaylist *pl);
+gboolean gmpv_playlist_empty(GmpvPlaylist *pl);
+void gmpv_playlist_reset(GmpvPlaylist *pl);
 
 G_END_DECLS
 
diff --git a/src/gmpv_playlist_widget.c b/src/gmpv_playlist_widget.c
new file mode 100644
index 0000000..88d43fa
--- /dev/null
+++ b/src/gmpv_playlist_widget.c
@@ -0,0 +1,644 @@
+/*
+ * Copyright (c) 2014-2016 gnome-mpv
+ *
+ * This file is part of GNOME MPV.
+ *
+ * GNOME MPV 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "gmpv_playlist_widget.h"
+#include "gmpv_playlist.h"
+#include "gmpv_marshal.h"
+#include "gmpv_def.h"
+
+enum
+{
+	PROP_0,
+	PROP_STORE,
+	N_PROPERTIES
+};
+
+struct _GmpvPlaylistWidget
+{
+	GtkScrolledWindow parent_instance;
+	GtkWidget *tree_view;
+	GmpvPlaylist *store;
+	GtkTreeViewColumn *title_column;
+	GtkCellRenderer *title_renderer;
+	gint last_x;
+	gint last_y;
+	gboolean dnd_delete;
+};
+
+struct _GmpvPlaylistWidgetClass
+{
+	GtkScrolledWindowClass parent_class;
+};
+
+static void gmpv_playlist_widget_constructed(GObject *object);
+static void gmpv_playlist_widget_set_property(	GObject *object,
+						guint property_id,
+						const GValue *value,
+						GParamSpec *pspec );
+static void gmpv_playlist_widget_get_property(	GObject *object,
+						guint property_id,
+						GValue *value,
+						GParamSpec *pspec );
+static void drag_begin_handler(	GtkWidget *widget,
+				GdkDragContext *context,
+				gpointer data );
+static void drag_data_get_handler(	GtkWidget *widget,
+					GdkDragContext *context,
+					GtkSelectionData *sel_data,
+					guint info,
+					guint time,
+					gpointer data );
+static void drag_data_received_handler(	GtkWidget *widget,
+					GdkDragContext *context,
+					gint x,
+					gint y,
+					GtkSelectionData *sel_data,
+					guint info,
+					guint time,
+					gpointer data );
+static void drag_data_delete_handler(	GtkWidget *widget,
+					GdkDragContext *context,
+					gpointer data );
+static void row_activated_handler(	GtkTreeView *tree_view,
+					GtkTreePath *path,
+					GtkTreeViewColumn *column,
+					gpointer data );
+static void row_deleted_handler(GmpvPlaylist *pl, gint pos, gpointer data);
+static void row_reodered_handler(	GmpvPlaylist *pl,
+					gint src,
+					gint dest,
+					gpointer data );
+static gboolean mouse_press_handler(	GtkWidget *widget,
+					GdkEvent *event,
+					gpointer data );
+static gchar *get_uri_selected(GmpvPlaylistWidget *wgt);
+
+G_DEFINE_TYPE(GmpvPlaylistWidget, gmpv_playlist_widget, GTK_TYPE_SCROLLED_WINDOW)
+
+static void gmpv_playlist_widget_constructed(GObject *object)
+{
+	GmpvPlaylistWidget *self = GMPV_PLAYLIST_WIDGET(object);
+	GtkTargetEntry targets[] = DND_TARGETS;
+
+	self->tree_view
+		= gtk_tree_view_new_with_model
+			(GTK_TREE_MODEL(gmpv_playlist_get_store(self->store)));
+
+	g_signal_connect(	self->tree_view,
+				"button-press-event",
+				G_CALLBACK(mouse_press_handler),
+				self );
+	g_signal_connect_after(	self->tree_view,
+				"drag-begin",
+				G_CALLBACK(drag_begin_handler),
+				self );
+	g_signal_connect(	self->tree_view,
+				"drag-data-get",
+				G_CALLBACK(drag_data_get_handler),
+				self );
+	g_signal_connect(	self->tree_view,
+				"drag-data-received",
+				G_CALLBACK(drag_data_received_handler),
+				self );
+	g_signal_connect(	self->tree_view,
+				"drag-data-delete",
+				G_CALLBACK(drag_data_delete_handler),
+				self );
+	g_signal_connect(	self->tree_view,
+				"row-activated",
+				G_CALLBACK(row_activated_handler),
+				self );
+	g_signal_connect(	self->store,
+				"row-deleted",
+				G_CALLBACK(row_deleted_handler),
+				self );
+	g_signal_connect(	self->store,
+				"row-reordered",
+				G_CALLBACK(row_reodered_handler),
+				self );
+
+	gtk_tree_view_enable_model_drag_source(	GTK_TREE_VIEW(self->tree_view),
+						GDK_BUTTON1_MASK,
+						targets,
+						G_N_ELEMENTS(targets),
+						GDK_ACTION_COPY|
+						GDK_ACTION_LINK|
+						GDK_ACTION_MOVE );
+
+	gtk_tree_view_enable_model_drag_dest(	GTK_TREE_VIEW(self->tree_view),
+						targets,
+						G_N_ELEMENTS(targets),
+						GDK_ACTION_MOVE );
+
+	gtk_widget_set_can_focus(self->tree_view, FALSE);
+	gtk_tree_view_set_reorderable(GTK_TREE_VIEW(self->tree_view), FALSE);
+
+	gtk_tree_view_append_column
+		(GTK_TREE_VIEW(self->tree_view), self->title_column);
+
+	gtk_container_add(GTK_CONTAINER(self), self->tree_view);
+
+	G_OBJECT_CLASS(gmpv_playlist_widget_parent_class)->constructed(object);
+}
+
+static void gmpv_playlist_widget_set_property(	GObject *object,
+						guint property_id,
+						const GValue *value,
+						GParamSpec *pspec )
+{
+	GmpvPlaylistWidget *self = GMPV_PLAYLIST_WIDGET(object);
+
+	if(property_id == PROP_STORE)
+	{
+		self->store = g_value_get_pointer(value);
+
+	}
+	else
+	{
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+	}
+}
+
+static void gmpv_playlist_widget_get_property(	GObject *object,
+						guint property_id,
+						GValue *value,
+						GParamSpec *pspec )
+{
+	GmpvPlaylistWidget *self = GMPV_PLAYLIST_WIDGET(object);
+
+	if(property_id == PROP_STORE)
+	{
+		g_value_set_pointer(value, self->store);
+	}
+	else
+	{
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+	}
+}
+
+static void drag_begin_handler(	GtkWidget *widget,
+				GdkDragContext *context,
+				gpointer data )
+{
+	const gint padding = 6;
+	const gint border_width = 1;
+	GmpvPlaylistWidget *wgt = data;
+	GtkTreeView *tree_view = GTK_TREE_VIEW(widget);
+	GtkStyleContext *style = gtk_widget_get_style_context(widget);
+	GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
+	GtkTreePath *path = NULL;
+	GtkTreeIter iter;
+	GdkWindow *window = gtk_widget_get_window(widget);
+	PangoContext *pango_ctx = gtk_widget_get_pango_context(widget);
+	PangoLayout *layout = pango_layout_new(pango_ctx);
+	gint width = 0, height = 0;
+	gint text_width = 0, text_height = 0;
+	gint cell_x = 0, cell_y = 0;
+	gchar *name = NULL;
+	GdkRGBA *border_color = NULL;
+	GdkRGBA *fg_color = NULL;
+	cairo_surface_t *surface = NULL;
+	cairo_t *cr = NULL;
+
+	gtk_tree_view_get_path_at_pos(	tree_view,
+					wgt->last_x, wgt->last_y,
+					NULL,
+					NULL,
+					&cell_x, &cell_y );
+
+	gtk_tree_view_get_cursor(tree_view, &path, NULL);
+	gtk_tree_model_get_iter(model, &iter, path);
+	gtk_tree_model_get(model, &iter, PLAYLIST_NAME_COLUMN, &name, -1);
+	pango_layout_set_text(layout, name, (gint)strlen(name));
+	pango_layout_get_pixel_size(layout, &text_width, &text_height);
+
+	gtk_cell_renderer_get_preferred_height(	wgt->title_renderer,
+						widget,
+						NULL,
+						&height );
+
+	width = text_width+2*(padding+border_width);
+	height += 2*border_width;
+
+	surface =	gdk_window_create_similar_surface
+			(window, CAIRO_CONTENT_COLOR, width, height);
+	cr = cairo_create(surface);
+
+	gtk_style_context_get(	style,
+				GTK_STATE_FLAG_NORMAL,
+				GTK_STYLE_PROPERTY_COLOR, &fg_color,
+				GTK_STYLE_PROPERTY_BORDER_COLOR, &border_color,
+				NULL);
+
+	gtk_render_background(style, cr, 0, 0, width, height);
+
+	/* Draw border */
+	gdk_cairo_set_source_rgba(cr, border_color);
+	cairo_set_line_width(cr, border_width);
+	cairo_rectangle(	cr,
+				border_width/2.0, border_width/2.0,
+				width-border_width, height-border_width );
+	cairo_stroke(cr);
+
+	/* Draw text */
+	gdk_cairo_set_source_rgba(cr, fg_color);
+	cairo_translate(cr, padding, (height-text_height)/2.0);
+	pango_cairo_show_layout(cr, layout);
+
+	cairo_surface_set_device_offset
+		(	surface,
+			(-1)*(MIN(cell_x+border_width, width-border_width)),
+			(-1)*(cell_y+border_width) );
+	gtk_drag_set_icon_surface(context, surface);
+
+	gdk_rgba_free(fg_color);
+	gdk_rgba_free(border_color);
+	cairo_destroy(cr);
+	g_object_unref(layout);
+}
+
+static void drag_data_get_handler(	GtkWidget *widget,
+					GdkDragContext *context,
+					GtkSelectionData *sel_data,
+					guint info,
+					guint time,
+					gpointer data )
+{
+	gchar *type = gdk_atom_name(gtk_selection_data_get_target(sel_data));
+	gchar *text = get_uri_selected(data);
+
+	if(g_strcmp0(type, "PLAYLIST_PATH") == 0)
+	{
+		GmpvPlaylistWidget *wgt = data;
+		GtkTreePath *path = NULL;
+		gchar *path_str = NULL;
+		GdkAtom atom = gdk_atom_intern_static_string("PLAYLIST_PATH");
+
+		gtk_tree_view_get_cursor
+			(GTK_TREE_VIEW(wgt->tree_view), &path, NULL);
+
+		path_str = gtk_tree_path_to_string(path);
+
+		gtk_selection_data_set(	sel_data,
+					atom,
+					8,
+					(const guchar *)path_str,
+					(gint)strlen(path_str) );
+
+		g_free(path_str);
+	}
+	else if(g_strcmp0(type, "text/uri-list") == 0)
+	{
+		/* Only one URI can be selected at a time */
+		gchar *uris[] = {text, NULL};
+
+		gtk_selection_data_set_uris(sel_data, uris);
+	}
+	else
+	{
+		gtk_selection_data_set_text(sel_data, text, -1);
+	}
+
+	g_free(type);
+	g_free(text);
+}
+
+static void drag_data_received_handler(	GtkWidget *widget,
+					GdkDragContext *context,
+					gint x,
+					gint y,
+					GtkSelectionData *sel_data,
+					guint info,
+					guint time,
+					gpointer data)
+{
+	GmpvPlaylistWidget *wgt = data;
+	gchar *type = gdk_atom_name(gtk_selection_data_get_target(sel_data));
+	gboolean reorder = (widget == gtk_drag_get_source_widget(context));
+
+	if(reorder)
+	{
+		GtkListStore *store;
+		const guchar *raw_data;
+		gint src_index, dest_index;
+		GtkTreeIter src_iter, dest_iter;
+		GtkTreePath *src_path, *dest_path;
+		GtkTreeViewDropPosition before_mask;
+		GtkTreeViewDropPosition drop_pos;
+		gboolean insert_before;
+		gboolean dest_row_exist;
+
+		store = gmpv_playlist_get_store(wgt->store);
+		raw_data = gtk_selection_data_get_data(sel_data);
+		src_path =	gtk_tree_path_new_from_string
+				((const gchar *)raw_data);
+		src_index = gtk_tree_path_get_indices(src_path)[0];
+		before_mask =	GTK_TREE_VIEW_DROP_BEFORE|
+				GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
+		dest_row_exist =	gtk_tree_view_get_dest_row_at_pos
+					(	GTK_TREE_VIEW(widget),
+						x, y,
+						&dest_path,
+						&drop_pos );
+
+		wgt->dnd_delete = FALSE;
+
+		g_assert(g_strcmp0(type, "PLAYLIST_PATH") == 0);
+		g_assert(src_path);
+
+		gtk_tree_model_get_iter(	GTK_TREE_MODEL(store),
+						&src_iter,
+						src_path );
+
+		if(dest_row_exist)
+		{
+			g_assert(dest_path);
+
+			dest_index = gtk_tree_path_get_indices(dest_path)[0];
+
+			gtk_tree_model_get_iter(	GTK_TREE_MODEL(store),
+							&dest_iter,
+							dest_path );
+		}
+		else
+		{
+			/* Set dest_iter to the last child */
+			GtkTreeIter iter;
+			gboolean has_next;
+
+			drop_pos = GTK_TREE_VIEW_DROP_AFTER;
+			dest_index = -1;
+
+			gtk_tree_model_get_iter_first
+				(GTK_TREE_MODEL(store), &iter);
+
+			do
+			{
+				dest_iter = iter;
+				has_next =	gtk_tree_model_iter_next
+						(GTK_TREE_MODEL(store), &iter);
+
+				dest_index++;
+			}
+			while(has_next);
+		}
+
+		insert_before = (drop_pos&before_mask || drop_pos == 0);
+
+		if(insert_before)
+		{
+			gtk_list_store_move_before(store, &src_iter, &dest_iter);
+		}
+		else
+		{
+			gtk_list_store_move_after(store, &src_iter, &dest_iter);
+		}
+
+		g_signal_emit_by_name(	wgt,
+					"row-reordered",
+					src_index+(src_index>dest_index),
+					dest_index+!insert_before );
+
+		gtk_tree_path_free(src_path);
+		gtk_tree_path_free(dest_path);
+	}
+	else
+	{
+		g_signal_emit_by_name(	wgt,
+					"drag-data-received",
+					context,
+					x, y,
+					sel_data,
+					info,
+					time,
+					data );
+	}
+}
+
+static void drag_data_delete_handler(	GtkWidget *widget,
+					GdkDragContext *context,
+					gpointer data )
+{
+	GmpvPlaylistWidget *wgt = data;
+
+	/* Prevent default handler from deleting the source row when reordering.
+	 * When reordering, dnd_delete will be set to FALSE in
+	 * drag_data_received_handler().
+	 */
+	if(!wgt->dnd_delete)
+	{
+		g_signal_stop_emission_by_name(widget, "drag-data-delete");
+	}
+
+	wgt->dnd_delete = TRUE;
+}
+
+static void row_activated_handler(	GtkTreeView *tree_view,
+					GtkTreePath *path,
+					GtkTreeViewColumn *column,
+					gpointer data )
+{
+	gint *indices = gtk_tree_path_get_indices(path);
+	gint64 index = indices?indices[0]:-1;
+
+	g_signal_emit_by_name(data, "row-activated", index);
+}
+
+static void row_deleted_handler(GmpvPlaylist *pl, gint pos, gpointer data)
+{
+	g_signal_emit_by_name(data, "row-deleted", pos);
+}
+
+static void row_reodered_handler(	GmpvPlaylist *pl,
+					gint src,
+					gint dest,
+					gpointer data )
+{
+	g_signal_emit_by_name(data, "row-reordered", src, dest);
+}
+
+static gboolean mouse_press_handler(	GtkWidget *widget,
+					GdkEvent *event,
+					gpointer data )
+{
+	GmpvPlaylistWidget *wgt = data;
+	GdkEventButton *btn_event = (GdkEventButton *)event;
+	gboolean handled;
+
+	wgt->last_x = (gint)btn_event->x;
+	wgt->last_y = (gint)btn_event->y;
+
+	handled = (	btn_event->type == GDK_BUTTON_PRESS &&
+			btn_event->button == 3 );
+
+	if(handled)
+	{
+		GMenu *menu;
+		GMenuItem *add_menu_item;
+		GMenuItem *loop_menu_item;
+		GtkWidget *ctx_menu;
+
+		menu = g_menu_new();
+		add_menu_item = g_menu_item_new(_("_Add…"), "app.open(true)");
+		loop_menu_item = g_menu_item_new(_("Loop"), "app.loop");
+
+		g_menu_append_item(menu, add_menu_item);
+		g_menu_append_item(menu, loop_menu_item);
+		g_menu_freeze(menu);
+
+		ctx_menu = gtk_menu_new_from_model(G_MENU_MODEL(menu));
+
+		gtk_menu_attach_to_widget(GTK_MENU(ctx_menu), widget, NULL);
+		gtk_widget_show_all(ctx_menu);
+
+		gtk_menu_popup(	GTK_MENU(ctx_menu), NULL, NULL, NULL, NULL,
+				btn_event->button, btn_event->time );
+	}
+
+	return handled;
+}
+
+static gchar *get_uri_selected(GmpvPlaylistWidget *wgt)
+{
+	GtkTreeIter iter;
+	GtkTreePath *path = NULL;
+	GtkTreeModel *model = NULL;
+	gchar *result = NULL;
+	gboolean rc = FALSE;
+
+	gtk_tree_view_get_cursor(GTK_TREE_VIEW(wgt->tree_view), &path, NULL);
+
+	if(path)
+	{
+		model = GTK_TREE_MODEL(gmpv_playlist_get_store(wgt->store));
+		rc = gtk_tree_model_get_iter(model, &iter, path);
+	}
+
+	if(rc)
+	{
+		gtk_tree_model_get
+			(model, &iter, PLAYLIST_URI_COLUMN, &result, -1);
+	}
+
+	return result;
+}
+
+static void gmpv_playlist_widget_class_init(GmpvPlaylistWidgetClass *klass)
+{
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	GParamSpec *pspec = NULL;
+
+	obj_class->constructed = gmpv_playlist_widget_constructed;
+	obj_class->set_property = gmpv_playlist_widget_set_property;
+	obj_class->get_property = gmpv_playlist_widget_get_property;
+
+	pspec = g_param_spec_pointer
+		(	"store",
+			"Store",
+			"GmpvPlaylist used to store playlist items",
+			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
+	g_object_class_install_property(obj_class, PROP_STORE, pspec);
+
+	g_signal_new(	"row-activated",
+			G_TYPE_FROM_CLASS(klass),
+			G_SIGNAL_RUN_FIRST,
+			0,
+			NULL,
+			NULL,
+			g_cclosure_gen_marshal_VOID__INT64,
+			G_TYPE_NONE,
+			1,
+			G_TYPE_INT );
+	g_signal_new(	"row-deleted",
+			G_TYPE_FROM_CLASS(klass),
+			G_SIGNAL_RUN_FIRST,
+			0,
+			NULL,
+			NULL,
+			g_cclosure_marshal_VOID__INT,
+			G_TYPE_NONE,
+			1,
+			G_TYPE_INT );
+	g_signal_new(	"row-reordered",
+			G_TYPE_FROM_CLASS(klass),
+			G_SIGNAL_RUN_FIRST,
+			0,
+			NULL,
+			NULL,
+			g_cclosure_gen_marshal_VOID__INT_INT,
+			G_TYPE_NONE,
+			2,
+			G_TYPE_INT,
+			G_TYPE_INT );
+}
+
+static void gmpv_playlist_widget_init(GmpvPlaylistWidget *wgt)
+{
+	wgt->title_renderer = gtk_cell_renderer_text_new();
+	wgt->title_column
+		= gtk_tree_view_column_new_with_attributes
+			(	_("Playlist"),
+				wgt->title_renderer,
+				"text", PLAYLIST_NAME_COLUMN,
+				"weight", PLAYLIST_WEIGHT_COLUMN,
+				NULL );
+	wgt->dnd_delete = TRUE;
+
+	gtk_widget_set_size_request
+		(GTK_WIDGET(wgt), PLAYLIST_MIN_WIDTH, -1);
+	gtk_tree_view_column_set_sizing
+		(wgt->title_column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+}
+
+GtkWidget *gmpv_playlist_widget_new(GmpvPlaylist *store)
+{
+	return GTK_WIDGET(g_object_new(	gmpv_playlist_widget_get_type(),
+					"store", store,
+					NULL ));
+}
+
+void gmpv_playlist_widget_remove_selected(GmpvPlaylistWidget *wgt)
+{
+	GtkTreePath *path;
+
+	gtk_tree_view_get_cursor
+		(	GTK_TREE_VIEW(wgt->tree_view),
+			&path,
+			NULL );
+
+	if(path)
+	{
+		gint index;
+		gchar *index_str;
+
+		index = gtk_tree_path_get_indices(path)[0];
+		index_str = g_strdup_printf("%d", index);
+
+		gmpv_playlist_remove(wgt->store, index);
+
+		g_free(index_str);
+	}
+}
+
+GmpvPlaylist *gmpv_playlist_widget_get_store(GmpvPlaylistWidget *wgt)
+{
+	return wgt->store;
+}
diff --git a/src/main.c b/src/gmpv_playlist_widget.h
similarity index 58%
rename from src/main.c
rename to src/gmpv_playlist_widget.h
index 0d34db3..605ffd3 100644
--- a/src/main.c
+++ b/src/gmpv_playlist_widget.h
@@ -17,21 +17,23 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <glib/gi18n.h>
-#include <gdk/gdk.h>
+#ifndef PLAYLIST_WIDGET_H
+#define PLAYLIST_WIDGET_H
 
-#include "application.h"
-#include "def.h"
+#include <gtk/gtk.h>
 
-int main(int argc, char **argv)
-{
-	Application *app;
-	gint status;
+#include "gmpv_playlist.h"
 
-	app = application_new(APP_ID, G_APPLICATION_HANDLES_OPEN);
-	status = g_application_run(G_APPLICATION(app), argc, argv);
+G_BEGIN_DECLS
 
-	g_object_unref(app);
+#define GMPV_TYPE_PLAYLIST_WIDGET (gmpv_playlist_widget_get_type ())
 
-	return status;
-}
+G_DECLARE_FINAL_TYPE(GmpvPlaylistWidget, gmpv_playlist_widget, GMPV, PLAYLIST_WIDGET, GtkScrolledWindow)
+
+GtkWidget *gmpv_playlist_widget_new(GmpvPlaylist *store);
+void gmpv_playlist_widget_remove_selected(GmpvPlaylistWidget *wgt);
+GmpvPlaylist *gmpv_playlist_widget_get_store(GmpvPlaylistWidget *wgt);
+
+G_END_DECLS
+
+#endif
diff --git a/src/plugins_manager.c b/src/gmpv_plugins_manager.c
similarity index 67%
rename from src/plugins_manager.c
rename to src/gmpv_plugins_manager.c
index 64b530f..eb1f27f 100644
--- a/src/plugins_manager.c
+++ b/src/gmpv_plugins_manager.c
@@ -19,9 +19,9 @@
 
 #include <glib/gi18n.h>
 
-#include "plugins_manager.h"
-#include "plugins_manager_item.h"
-#include "common.h"
+#include "gmpv_plugins_manager.h"
+#include "gmpv_plugins_manager_item.h"
+#include "gmpv_common.h"
 
 enum
 {
@@ -30,7 +30,7 @@ enum
 	N_PROPERTIES
 };
 
-struct _PluginsManager
+struct _GmpvPluginsManager
 {
 	GtkGrid parent;
 	GtkWindow *parent_window;
@@ -40,59 +40,68 @@ struct _PluginsManager
 	gchar *directory;
 };
 
-struct _PluginsManagerClass
+struct _GmpvPluginsManagerClass
 {
 	GtkGridClass parent_class;
 };
 
-G_DEFINE_TYPE(PluginsManager, plugins_manager, GTK_TYPE_GRID)
+G_DEFINE_TYPE(GmpvPluginsManager, gmpv_plugins_manager, GTK_TYPE_GRID)
 
-static void plugins_manager_constructed(GObject *object);
-static void plugins_manager_finalize(GObject *object);
-static void plugins_manager_set_property(	GObject *object,
+static void gmpv_plugins_manager_constructed(GObject *object);
+static void gmpv_plugins_manager_finalize(GObject *object);
+static void gmpv_plugins_manager_set_property(	GObject *object,
 						guint property_id,
 						const GValue *value,
 						GParamSpec *pspec );
-static void plugins_manager_get_property(	GObject *object,
+static void gmpv_plugins_manager_get_property(	GObject *object,
 						guint property_id,
 						GValue *value,
 						GParamSpec *pspec );
 static void add_handler(GtkButton *button, gpointer data);
+static void drag_data_handler(	GtkWidget *widget,
+				GdkDragContext *context,
+				gint x,
+				gint y,
+				GtkSelectionData *sel_data,
+				guint info,
+				guint time,
+				gpointer data);
 static void changed_handler(	GFileMonitor *monitor,
 				GFile *file,
 				GFile *other_file,
 				GFileMonitorEvent event_type,
 				gpointer data );
+static void copy_file_to_directory(GmpvPluginsManager *pmgr, GFile *src);
 
-static void plugins_manager_constructed(GObject *object)
+static void gmpv_plugins_manager_constructed(GObject *object)
 {
-	PluginsManager *self = PLUGINS_MANAGER(object);
+	GmpvPluginsManager *self = GMPV_PLUGINS_MANAGER(object);
 	gchar *scripts_dir = get_scripts_dir_path();
 
 	g_mkdir_with_parents(scripts_dir, 0700);
-	plugins_manager_set_directory(self, scripts_dir);
+	gmpv_plugins_manager_set_directory(self, scripts_dir);
 
 	g_free(scripts_dir);
 
-	G_OBJECT_CLASS(plugins_manager_parent_class)->constructed(object);
+	G_OBJECT_CLASS(gmpv_plugins_manager_parent_class)->constructed(object);
 }
 
-static void plugins_manager_finalize(GObject *object)
+static void gmpv_plugins_manager_finalize(GObject *object)
 {
-	PluginsManager *pmgr = PLUGINS_MANAGER(object);
+	GmpvPluginsManager *pmgr = GMPV_PLUGINS_MANAGER(object);
 
 	g_clear_object(&pmgr->monitor);
 	g_free(pmgr->directory);
 
-	G_OBJECT_CLASS(plugins_manager_parent_class)->finalize(object);
+	G_OBJECT_CLASS(gmpv_plugins_manager_parent_class)->finalize(object);
 }
 
-static void plugins_manager_set_property(	GObject *object,
+static void gmpv_plugins_manager_set_property(	GObject *object,
 						guint property_id,
 						const GValue *value,
 						GParamSpec *pspec )
 {
-	PluginsManager *self = PLUGINS_MANAGER(object);
+	GmpvPluginsManager *self = GMPV_PLUGINS_MANAGER(object);
 
 	if(property_id == PROP_PARENT)
 	{
@@ -104,12 +113,12 @@ static void plugins_manager_set_property(	GObject *object,
 	}
 }
 
-static void plugins_manager_get_property(	GObject *object,
+static void gmpv_plugins_manager_get_property(	GObject *object,
 						guint property_id,
 						GValue *value,
 						GParamSpec *pspec )
 {
-	PluginsManager *self = PLUGINS_MANAGER(object);
+	GmpvPluginsManager *self = GMPV_PLUGINS_MANAGER(object);
 
 	if(property_id == PROP_PARENT)
 	{
@@ -123,15 +132,11 @@ static void plugins_manager_get_property(	GObject *object,
 
 static void add_handler(GtkButton *button, gpointer data)
 {
-	PluginsManager *pmgr = data;
+	GmpvPluginsManager *pmgr = data;
 	GtkWidget *dialog = NULL;
 	GFile *src = NULL;
-	GFile *dest = NULL;
-	gchar *src_path = NULL;
-	gchar *dest_path = NULL;
-	GError *error = NULL;
 
-	dialog = gtk_file_chooser_dialog_new(	"Add Lua Script",
+	dialog = gtk_file_chooser_dialog_new(	_("Add Lua Script"),
 						pmgr->parent_window,
 						GTK_FILE_CHOOSER_ACTION_OPEN,
 						_("Cancel"),
@@ -140,61 +145,43 @@ static void add_handler(GtkButton *button, gpointer data)
 						GTK_RESPONSE_ACCEPT,
 						NULL );
 
-	g_assert(pmgr->directory);
-
 	if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
 	{
 		GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog);
 
 		src = gtk_file_chooser_get_file(chooser);
-		dest_path = g_build_filename(	pmgr->directory,
-						g_file_get_basename(src),
-						NULL );
-		dest = g_file_new_for_path(dest_path);
-
-		g_file_copy(	src,
-				dest,
-				G_FILE_COPY_NONE,
-				NULL, NULL, NULL,
-				&error );
 	}
 
 	gtk_widget_destroy(dialog);
 
-	if(error)
-	{
-		GtkWidget *error_dialog;
+	copy_file_to_directory(pmgr, src);
 
-		src_path = g_file_get_path(src)?:g_file_get_uri(src);
+	g_clear_object(&src);
+}
 
-		error_dialog =	gtk_message_dialog_new
-				(	pmgr->parent_window,
-					GTK_DIALOG_MODAL|
-					GTK_DIALOG_DESTROY_WITH_PARENT,
-					GTK_MESSAGE_ERROR,
-					GTK_BUTTONS_OK,
-					_("Failed to copy file from '%s' "
-					"to '%s'. Reason: %s"),
-					src_path,
-					dest_path,
-					error->message );
+static void drag_data_handler(	GtkWidget *widget,
+				GdkDragContext *context,
+				gint x,
+				gint y,
+				GtkSelectionData *sel_data,
+				guint info,
+				guint time,
+				gpointer data)
+{
+	gchar **uri_list = gtk_selection_data_get_uris(sel_data);
 
-		g_warning(	"Failed to copy file from '%s' to '%s'. "
-				"Reason: %s",
-				src_path,
-				dest_path,
-				error->message );
+	g_assert(uri_list);
 
-		gtk_dialog_run(GTK_DIALOG(error_dialog));
+	for(gint i = 0; uri_list[i]; i++)
+	{
+		GFile *file = g_file_new_for_uri(uri_list[i]);
 
-		gtk_widget_destroy(error_dialog);
-		g_error_free(error);
+		copy_file_to_directory(data, file);
+
+		g_clear_object(&file);
 	}
 
-	g_clear_object(&src);
-	g_clear_object(&dest);
-	g_free(src_path);
-	g_free(dest_path);
+	g_strfreev(uri_list);
 }
 
 static void changed_handler(	GFileMonitor *monitor,
@@ -203,7 +190,7 @@ static void changed_handler(	GFileMonitor *monitor,
 				GFileMonitorEvent event_type,
 				gpointer data )
 {
-	PluginsManager *pmgr = data;
+	GmpvPluginsManager *pmgr = data;
 	GDir *dir = NULL;
 	const gchar *filename = NULL;
 	gboolean empty = TRUE;
@@ -245,7 +232,7 @@ static void changed_handler(	GFileMonitor *monitor,
 			{
 				GtkWidget *item;
 
-				item =	plugins_manager_item_new
+				item =	gmpv_plugins_manager_item_new
 					(	pmgr->parent_window,
 						filename,
 						full_path );
@@ -266,15 +253,73 @@ static void changed_handler(	GFileMonitor *monitor,
 	}
 }
 
-static void plugins_manager_class_init(PluginsManagerClass *klass)
+static void copy_file_to_directory(GmpvPluginsManager *pmgr, GFile *src)
+{
+	gchar *dest_path = NULL;
+	GFile *dest = NULL;
+	GError *error = NULL;
+
+	if(src)
+	{
+		g_assert(pmgr->directory);
+
+		dest_path = g_build_filename(	pmgr->directory,
+						g_file_get_basename(src),
+						NULL );
+		dest = g_file_new_for_path(dest_path);
+
+		g_file_copy(	src,
+				dest,
+				G_FILE_COPY_NONE,
+				NULL, NULL, NULL,
+				&error );
+	}
+
+	if(error)
+	{
+		GtkWidget *error_dialog = NULL;
+		gchar *src_path = NULL;
+
+		src_path = g_file_get_path(src)?:g_file_get_uri(src);
+
+		error_dialog =	gtk_message_dialog_new
+				(	pmgr->parent_window,
+					GTK_DIALOG_MODAL|
+					GTK_DIALOG_DESTROY_WITH_PARENT,
+					GTK_MESSAGE_ERROR,
+					GTK_BUTTONS_OK,
+					_("Failed to copy file from '%s' "
+					"to '%s'. Reason: %s"),
+					src_path,
+					dest_path,
+					error->message );
+
+		g_warning(	"Failed to copy file from '%s' to '%s'. "
+				"Reason: %s",
+				src_path,
+				dest_path,
+				error->message );
+
+		gtk_dialog_run(GTK_DIALOG(error_dialog));
+
+		gtk_widget_destroy(error_dialog);
+		g_error_free(error);
+		g_free(src_path);
+	}
+
+	g_clear_object(&dest);
+	g_free(dest_path);
+}
+
+static void gmpv_plugins_manager_class_init(GmpvPluginsManagerClass *klass)
 {
 	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
 	GParamSpec *pspec = NULL;
 
-	obj_class->constructed = plugins_manager_constructed;
-	obj_class->finalize = plugins_manager_finalize;
-	obj_class->set_property = plugins_manager_set_property;
-	obj_class->get_property = plugins_manager_get_property;
+	obj_class->constructed = gmpv_plugins_manager_constructed;
+	obj_class->finalize = gmpv_plugins_manager_finalize;
+	obj_class->set_property = gmpv_plugins_manager_set_property;
+	obj_class->get_property = gmpv_plugins_manager_get_property;
 
 	pspec = g_param_spec_pointer
 		(	"parent",
@@ -285,7 +330,7 @@ static void plugins_manager_class_init(PluginsManagerClass *klass)
 	g_object_class_install_property(obj_class, PROP_PARENT, pspec);
 }
 
-static void plugins_manager_init(PluginsManager *pmgr)
+static void gmpv_plugins_manager_init(GmpvPluginsManager *pmgr)
 {
 	GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
 	GtkWidget *overlay = gtk_overlay_new();
@@ -301,10 +346,22 @@ static void plugins_manager_init(PluginsManager *pmgr)
 				"clicked",
 				G_CALLBACK(add_handler),
 				pmgr );
+	g_signal_connect(	pmgr->list_box,
+				"drag-data-received",
+				G_CALLBACK(drag_data_handler),
+				pmgr );
+
+	gtk_drag_dest_set(	pmgr->list_box,
+				GTK_DEST_DEFAULT_ALL,
+				NULL,
+				0,
+				GDK_ACTION_LINK );
+	gtk_drag_dest_add_uri_targets(pmgr->list_box);
 
 	gtk_widget_set_hexpand(GTK_WIDGET(scrolled_window), TRUE);
 	gtk_widget_set_vexpand(GTK_WIDGET(scrolled_window), TRUE);
 
+	gtk_widget_set_tooltip_text(add_button, _("Add Lua Script"));
 	gtk_widget_set_sensitive(pmgr->placeholder_label, FALSE);
 	gtk_widget_set_no_show_all(pmgr->placeholder_label, TRUE);
 	gtk_widget_show(pmgr->placeholder_label);
@@ -325,14 +382,15 @@ static void plugins_manager_init(PluginsManager *pmgr)
 	gtk_container_add(GTK_CONTAINER(scrolled_window), pmgr->list_box);
 }
 
-GtkWidget *plugins_manager_new(GtkWindow *parent)
+GtkWidget *gmpv_plugins_manager_new(GtkWindow *parent)
 {
-	return g_object_new(	plugins_manager_get_type(),
+	return g_object_new(	gmpv_plugins_manager_get_type(),
 				"parent", parent,
 				NULL);
 }
 
-void plugins_manager_set_directory(PluginsManager *pmgr, const gchar *path)
+void gmpv_plugins_manager_set_directory(	GmpvPluginsManager *pmgr,
+						const gchar *path )
 {
 	GFile *directory = g_file_new_for_path(path);
 
diff --git a/src/mpv_opt.h b/src/gmpv_plugins_manager.h
similarity index 63%
copy from src/mpv_opt.h
copy to src/gmpv_plugins_manager.h
index 93e6920..a8867c7 100644
--- a/src/mpv_opt.h
+++ b/src/gmpv_plugins_manager.h
@@ -17,22 +17,21 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef MPV_OPT_H
-#define MPV_OPT_H
+#ifndef PLUGINS_MANAGER_H
+#define PLUGINS_MANAGER_H
 
-#include <mpv/client.h>
+#include <gtk/gtk.h>
 
-#include "mpv_obj.h"
+G_BEGIN_DECLS
 
-typedef struct module_log_level module_log_level;
+#define GMPV_TYPE_PLUGINS_MANAGER (gmpv_plugins_manager_get_type ())
 
-struct module_log_level
-{
-	gchar *prefix;
-	mpv_log_level level;
-};
+G_DECLARE_FINAL_TYPE(GmpvPluginsManager, gmpv_plugins_manager, GMPV, PLUGINS_MANAGER, GtkGrid)
 
-void mpv_opt_handle_autofit(MpvObj *mpv);
-void mpv_opt_handle_msg_level(MpvObj *mpv);
+GtkWidget *gmpv_plugins_manager_new(GtkWindow *parent);
+void gmpv_plugins_manager_set_directory(	GmpvPluginsManager *pmgr,
+						const gchar *path );
+
+G_END_DECLS
 
 #endif
diff --git a/src/plugins_manager_item.c b/src/gmpv_plugins_manager_item.c
similarity index 73%
rename from src/plugins_manager_item.c
rename to src/gmpv_plugins_manager_item.c
index 94c78b8..e1c43ac 100644
--- a/src/plugins_manager_item.c
+++ b/src/gmpv_plugins_manager_item.c
@@ -19,7 +19,7 @@
 
 #include <glib/gi18n.h>
 
-#include "plugins_manager_item.h"
+#include "gmpv_plugins_manager_item.h"
 
 enum
 {
@@ -30,7 +30,7 @@ enum
 	N_PROPERTIES
 };
 
-struct _PluginsManagerItem
+struct _GmpvPluginsManagerItem
 {
 	GtkListBoxRow parent;
 	GtkWindow *parent_window;
@@ -38,28 +38,28 @@ struct _PluginsManagerItem
 	gchar *path;
 };
 
-struct _PluginsManagerItemClass
+struct _GmpvPluginsManagerItemClass
 {
 	GtkListBoxRowClass parent_class;
 };
 
-G_DEFINE_TYPE(PluginsManagerItem, plugins_manager_item, GTK_TYPE_LIST_BOX_ROW)
+G_DEFINE_TYPE(GmpvPluginsManagerItem, gmpv_plugins_manager_item, GTK_TYPE_LIST_BOX_ROW)
 
-static void plugins_manager_item_constructed(GObject *object);
-static void plugins_manager_item_finalize(GObject *object);
-static void plugins_manager_item_set_property(	GObject *object,
+static void gmpv_plugins_manager_item_constructed(GObject *object);
+static void gmpv_plugins_manager_item_finalize(GObject *object);
+static void gmpv_plugins_manager_item_set_property(	GObject *object,
 						guint property_id,
 						const GValue *value,
 						GParamSpec *pspec );
-static void plugins_manager_item_get_property(	GObject *object,
+static void gmpv_plugins_manager_item_get_property(	GObject *object,
 						guint property_id,
 						GValue *value,
 						GParamSpec *pspec );
 static void remove_handler(GtkButton *button, gpointer data);
 
-static void plugins_manager_item_constructed(GObject *object)
+static void gmpv_plugins_manager_item_constructed(GObject *object)
 {
-	PluginsManagerItem *self = PLUGINS_MANAGER_ITEM(object);
+	GmpvPluginsManagerItem *self = GMPV_PLUGINS_MANAGER_ITEM(object);
 	GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
 	GtkWidget *title_label = gtk_label_new(self->title);
 	GtkWidget *remove_button = gtk_button_new_with_label(_("Remove"));
@@ -77,25 +77,26 @@ static void plugins_manager_item_constructed(GObject *object)
 	gtk_box_pack_end(GTK_BOX(box), remove_button, FALSE, FALSE, 0);
 	gtk_container_add(GTK_CONTAINER(self), box);
 
-	G_OBJECT_CLASS(plugins_manager_item_parent_class)->constructed(object);
+	G_OBJECT_CLASS(gmpv_plugins_manager_item_parent_class)
+	->constructed(object);
 }
 
-static void plugins_manager_item_finalize(GObject *object)
+static void gmpv_plugins_manager_item_finalize(GObject *object)
 {
-	PluginsManagerItem *self = PLUGINS_MANAGER_ITEM(object);
+	GmpvPluginsManagerItem *self = GMPV_PLUGINS_MANAGER_ITEM(object);
 
 	g_free(self->title);
 	g_free(self->path);
 
-	G_OBJECT_CLASS(plugins_manager_item_parent_class)->finalize(object);
+	G_OBJECT_CLASS(gmpv_plugins_manager_item_parent_class)->finalize(object);
 }
 
-static void plugins_manager_item_set_property(	GObject *object,
+static void gmpv_plugins_manager_item_set_property(	GObject *object,
 						guint property_id,
 						const GValue *value,
 						GParamSpec *pspec )
 {
-	PluginsManagerItem *self = PLUGINS_MANAGER_ITEM(object);
+	GmpvPluginsManagerItem *self = GMPV_PLUGINS_MANAGER_ITEM(object);
 
 	if(property_id == PROP_PARENT)
 	{
@@ -119,12 +120,12 @@ static void plugins_manager_item_set_property(	GObject *object,
 	}
 }
 
-static void plugins_manager_item_get_property(	GObject *object,
+static void gmpv_plugins_manager_item_get_property(	GObject *object,
 						guint property_id,
 						GValue *value,
 						GParamSpec *pspec )
 {
-	PluginsManagerItem *self = PLUGINS_MANAGER_ITEM(object);
+	GmpvPluginsManagerItem *self = GMPV_PLUGINS_MANAGER_ITEM(object);
 
 	if(property_id == PROP_PARENT)
 	{
@@ -146,7 +147,7 @@ static void plugins_manager_item_get_property(	GObject *object,
 
 static void remove_handler(GtkButton *button, gpointer data)
 {
-	PluginsManagerItem *item = data;
+	GmpvPluginsManagerItem *item = data;
 	GFile *file = g_file_new_for_path(item->path);
 	GError *error = NULL;
 	GtkWidget *confirm_dialog =	gtk_message_dialog_new
@@ -192,22 +193,21 @@ static void remove_handler(GtkButton *button, gpointer data)
 	}
 }
 
-static void plugins_manager_item_class_init(PluginsManagerItemClass *klass)
+static void gmpv_plugins_manager_item_class_init(GmpvPluginsManagerItemClass *klass)
 {
 	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
 	GParamSpec *pspec = NULL;
 
-	obj_class->constructed = plugins_manager_item_constructed;
-	obj_class->finalize = plugins_manager_item_finalize;
-	obj_class->set_property = plugins_manager_item_set_property;
-	obj_class->get_property = plugins_manager_item_get_property;
+	obj_class->constructed = gmpv_plugins_manager_item_constructed;
+	obj_class->finalize = gmpv_plugins_manager_item_finalize;
+	obj_class->set_property = gmpv_plugins_manager_item_set_property;
+	obj_class->get_property = gmpv_plugins_manager_item_get_property;
 
 	pspec = g_param_spec_pointer
 		(	"parent",
 			"Parent",
 			"Parent window for the dialogs",
 			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
-
 	g_object_class_install_property(obj_class, PROP_PARENT, pspec);
 
 	pspec = g_param_spec_string
@@ -216,7 +216,6 @@ static void plugins_manager_item_class_init(PluginsManagerItemClass *klass)
 			"The string to display as the title of the item",
 			"",
 			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
-
 	g_object_class_install_property(obj_class, PROP_TITLE, pspec);
 
 	pspec = g_param_spec_string
@@ -225,22 +224,21 @@ static void plugins_manager_item_class_init(PluginsManagerItemClass *klass)
 			"The path to the file that this item references",
 			"",
 			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
-
 	g_object_class_install_property(obj_class, PROP_PATH, pspec);
 }
 
-static void plugins_manager_item_init(PluginsManagerItem *item)
+static void gmpv_plugins_manager_item_init(GmpvPluginsManagerItem *item)
 {
 	item->parent_window = NULL;
 	item->title = NULL;
 	item->path = NULL;
 }
 
-GtkWidget *plugins_manager_item_new(	GtkWindow *parent,
+GtkWidget *gmpv_plugins_manager_item_new(	GtkWindow *parent,
 					const gchar *title,
 					const gchar *path )
 {
-	return GTK_WIDGET(g_object_new(	plugins_manager_item_get_type(),
+	return GTK_WIDGET(g_object_new(	gmpv_plugins_manager_item_get_type(),
 					"parent", parent,
 					"title", title,
 					"path", path,
diff --git a/src/mpv_opt.h b/src/gmpv_plugins_manager_item.h
similarity index 63%
copy from src/mpv_opt.h
copy to src/gmpv_plugins_manager_item.h
index 93e6920..7c3e17f 100644
--- a/src/mpv_opt.h
+++ b/src/gmpv_plugins_manager_item.h
@@ -17,22 +17,21 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef MPV_OPT_H
-#define MPV_OPT_H
+#ifndef PLUGINS_MANAGER_ITEM_H
+#define PLUGINS_MANAGER_ITEM_H
 
-#include <mpv/client.h>
+#include <gtk/gtk.h>
 
-#include "mpv_obj.h"
+G_BEGIN_DECLS
 
-typedef struct module_log_level module_log_level;
+#define GMPV_TYPE_PLUGINS_MANAGER_ITEM (gmpv_plugins_manager_item_get_type ())
 
-struct module_log_level
-{
-	gchar *prefix;
-	mpv_log_level level;
-};
+G_DECLARE_FINAL_TYPE(GmpvPluginsManagerItem, gmpv_plugins_manager_item, GMPV, PLUGINS_MANAGER_ITEM, GtkListBoxRow)
 
-void mpv_opt_handle_autofit(MpvObj *mpv);
-void mpv_opt_handle_msg_level(MpvObj *mpv);
+GtkWidget *gmpv_plugins_manager_item_new(	GtkWindow *parent,
+						const gchar *title,
+						const gchar *path );
+
+G_END_DECLS
 
 #endif
diff --git a/src/pref_dialog.c b/src/gmpv_pref_dialog.c
similarity index 90%
rename from src/pref_dialog.c
rename to src/gmpv_pref_dialog.c
index 8c6269b..7406a6e 100644
--- a/src/pref_dialog.c
+++ b/src/gmpv_pref_dialog.c
@@ -19,15 +19,15 @@
 
 #include <glib/gi18n.h>
 
-#include "pref_dialog.h"
-#include "plugins_manager.h"
-#include "main_window.h"
-#include "def.h"
+#include "gmpv_pref_dialog.h"
+#include "gmpv_plugins_manager.h"
+#include "gmpv_main_window.h"
+#include "gmpv_def.h"
 
 typedef struct PrefDialogItem PrefDialogItem;
 typedef enum PrefDialogItemType PrefDialogItemType;
 
-struct _PrefDialog
+struct _GmpvPrefDialog
 {
 	GtkDialog parent_instance;
 	GSettings *settings;
@@ -35,7 +35,7 @@ struct _PrefDialog
 	GtkWidget *grid;
 };
 
-struct _PrefDialogClass
+struct _GmpvPrefDialogClass
 {
 	GtkDialogClass parent_class;
 };
@@ -57,12 +57,12 @@ struct PrefDialogItem
 	PrefDialogItemType type;
 };
 
-G_DEFINE_TYPE(PrefDialog, pref_dialog, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE(GmpvPrefDialog, gmpv_pref_dialog, GTK_TYPE_DIALOG)
 
 static void file_set_handler(GtkFileChooserButton *widget, gpointer data)
 {
 	GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(widget));
-	PrefDialog *dlg = PREF_DIALOG(toplevel);
+	GmpvPrefDialog *dlg = GMPV_PREF_DIALOG(toplevel);
 	GtkFileChooser *chooser = GTK_FILE_CHOOSER(widget);
 	const gchar *key = data;
 	gchar *filename = gtk_file_chooser_get_filename(chooser)?:g_strdup("");
@@ -74,7 +74,7 @@ static void file_set_handler(GtkFileChooserButton *widget, gpointer data)
 
 static void response_handler(GtkDialog *dialog, gint response_id)
 {
-	PrefDialog *dlg = PREF_DIALOG(dialog);
+	GmpvPrefDialog *dlg = GMPV_PREF_DIALOG(dialog);
 
 	if(response_id == GTK_RESPONSE_ACCEPT)
 	{
@@ -106,7 +106,8 @@ static gboolean key_press_handler(GtkWidget *widget, GdkEventKey *event)
 		gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_ACCEPT);
 	}
 
-	return GTK_WIDGET_CLASS(pref_dialog_parent_class)->key_press_event (widget, event);
+	return	GTK_WIDGET_CLASS(gmpv_pref_dialog_parent_class)
+		->key_press_event(widget, event);
 }
 
 static GtkWidget *build_page(const PrefDialogItem *items, GSettings *settings)
@@ -253,13 +254,13 @@ static void pref_dialog_constructed(GObject *obj)
 
 	if(!csd_enabled)
 	{
-		gtk_widget_set_margin_bottom(PREF_DIALOG(obj)->grid, 12);
+		gtk_widget_set_margin_bottom(GMPV_PREF_DIALOG(obj)->grid, 12);
 	}
 
-	G_OBJECT_CLASS(pref_dialog_parent_class)->constructed(obj);
+	G_OBJECT_CLASS(gmpv_pref_dialog_parent_class)->constructed(obj);
 }
 
-static void pref_dialog_class_init(PrefDialogClass *klass)
+static void gmpv_pref_dialog_class_init(GmpvPrefDialogClass *klass)
 {
 	GtkWidgetClass *wid_class = GTK_WIDGET_CLASS(klass);
 
@@ -268,7 +269,7 @@ static void pref_dialog_class_init(PrefDialogClass *klass)
 	G_OBJECT_CLASS(klass)->constructed = pref_dialog_constructed;
 }
 
-static void pref_dialog_init(PrefDialog *dlg)
+static void gmpv_pref_dialog_init(GmpvPrefDialog *dlg)
 {
 	const PrefDialogItem general_items[]
 		= {	{_("<b>User Interface</b>"),
@@ -340,7 +341,7 @@ static void pref_dialog_init(PrefDialog *dlg)
 					gtk_label_new(_("General")) );
 
 	gtk_notebook_append_page(	GTK_NOTEBOOK(dlg->notebook),
-					plugins_manager_new(GTK_WINDOW(dlg)),
+					gmpv_plugins_manager_new(GTK_WINDOW(dlg)),
 					gtk_label_new(_("Lua Scripts")) );
 
 	gtk_dialog_add_buttons(	GTK_DIALOG(dlg),
@@ -354,15 +355,15 @@ static void pref_dialog_init(PrefDialog *dlg)
 
 }
 
-GtkWidget *pref_dialog_new(GtkWindow *parent)
+GtkWidget *gmpv_pref_dialog_new(GtkWindow *parent)
 {
 	GtkWidget *dlg;
 	GtkWidget *header_bar;
 	gboolean csd_enabled;
 
-	csd_enabled = main_window_get_csd_enabled(MAIN_WINDOW(parent));
+	csd_enabled = gmpv_main_window_get_csd_enabled(GMPV_MAIN_WINDOW(parent));
 
-	dlg = g_object_new(	pref_dialog_get_type(),
+	dlg = g_object_new(	gmpv_pref_dialog_get_type(),
 				"title", _("Preferences"),
 				"modal", TRUE,
 				"transient-for", parent,
diff --git a/src/mpv_opt.h b/src/gmpv_pref_dialog.h
similarity index 68%
copy from src/mpv_opt.h
copy to src/gmpv_pref_dialog.h
index 93e6920..dd6dae7 100644
--- a/src/mpv_opt.h
+++ b/src/gmpv_pref_dialog.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 gnome-mpv
+ * Copyright (c) 2014-2015 gnome-mpv
  *
  * This file is part of GNOME MPV.
  *
@@ -17,22 +17,19 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef MPV_OPT_H
-#define MPV_OPT_H
+#ifndef PREF_DIALOG_H
+#define PREF_DIALOG_H
 
-#include <mpv/client.h>
+#include <gtk/gtk.h>
 
-#include "mpv_obj.h"
+G_BEGIN_DECLS
 
-typedef struct module_log_level module_log_level;
+#define GMPV_TYPE_PREF_DIALOG (gmpv_pref_dialog_get_type ())
 
-struct module_log_level
-{
-	gchar *prefix;
-	mpv_log_level level;
-};
+G_DECLARE_FINAL_TYPE(GmpvPrefDialog, gmpv_pref_dialog, GMPV, PREF_DIALOG, GtkDialog)
 
-void mpv_opt_handle_autofit(MpvObj *mpv);
-void mpv_opt_handle_msg_level(MpvObj *mpv);
+GtkWidget *gmpv_pref_dialog_new(GtkWindow *parent);
+
+G_END_DECLS
 
 #endif
diff --git a/src/shortcuts_window.c b/src/gmpv_shortcuts_window.c
similarity index 82%
rename from src/shortcuts_window.c
rename to src/gmpv_shortcuts_window.c
index 7d60996..8edaa7f 100644
--- a/src/shortcuts_window.c
+++ b/src/gmpv_shortcuts_window.c
@@ -19,21 +19,21 @@
 
 #include <glib/gi18n.h>
 
-#include "shortcuts_window.h"
+#include "gmpv_shortcuts_window.h"
 
-struct ShortcutsWindow
+struct _GmpvShortcutsWindow
 {
 	GtkShortcutsWindow parent;
 };
 
-struct ShortcutsWindowClass
+struct _GmpvShortcutsWindowClass
 {
 	GtkShortcutsWindowClass parent_class;
 };
 
-G_DEFINE_TYPE(ShortcutsWindow, shortcuts_window, GTK_TYPE_SHORTCUTS_WINDOW)
+G_DEFINE_TYPE(GmpvShortcutsWindow, gmpv_shortcuts_window, GTK_TYPE_SHORTCUTS_WINDOW)
 
-static void shortcuts_window_init(ShortcutsWindow *wnd)
+static void gmpv_shortcuts_window_init(GmpvShortcutsWindow *wnd)
 {
 	const struct
 	{
@@ -81,13 +81,13 @@ static void shortcuts_window_init(ShortcutsWindow *wnd)
 	gtk_container_add(GTK_CONTAINER(wnd), section);
 }
 
-static void shortcuts_window_class_init(ShortcutsWindowClass *klass)
+static void gmpv_shortcuts_window_class_init(GmpvShortcutsWindowClass *klass)
 {
 }
 
-GtkWidget *shortcuts_window_new(GtkWindow *parent)
+GtkWidget *gmpv_shortcuts_window_new(GtkWindow *parent)
 {
-	return GTK_WIDGET(g_object_new(	shortcuts_window_get_type(),
+	return GTK_WIDGET(g_object_new(	gmpv_shortcuts_window_get_type(),
 					"transient-for", parent,
 					"modal", TRUE,
 					NULL));
diff --git a/src/mpv_opt.h b/src/gmpv_shortcuts_window.h
similarity index 68%
rename from src/mpv_opt.h
rename to src/gmpv_shortcuts_window.h
index 93e6920..8696ad2 100644
--- a/src/mpv_opt.h
+++ b/src/gmpv_shortcuts_window.h
@@ -17,22 +17,19 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef MPV_OPT_H
-#define MPV_OPT_H
+#ifndef SHORTCUTS_WINDOW_H
+#define SHORTCUTS_WINDOW_H
 
-#include <mpv/client.h>
+#include <gtk/gtk.h>
 
-#include "mpv_obj.h"
+G_BEGIN_DECLS
 
-typedef struct module_log_level module_log_level;
+#define GMPV_TYPE_SHORTCUTS_WINDOW (gmpv_shortcuts_window_get_type ())
 
-struct module_log_level
-{
-	gchar *prefix;
-	mpv_log_level level;
-};
+G_DECLARE_FINAL_TYPE(GmpvShortcutsWindow, gmpv_shortcuts_window, GMPV, SHORTCUTS_WINDOW, GtkShortcutsWindow)
 
-void mpv_opt_handle_autofit(MpvObj *mpv);
-void mpv_opt_handle_msg_level(MpvObj *mpv);
+GtkWidget *gmpv_shortcuts_window_new(GtkWindow *parent);
+
+G_END_DECLS
 
 #endif
diff --git a/src/track.c b/src/gmpv_track.c
similarity index 86%
rename from src/track.c
rename to src/gmpv_track.c
index 59ebaee..dbbfabb 100644
--- a/src/track.c
+++ b/src/gmpv_track.c
@@ -17,11 +17,11 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "track.h"
+#include "gmpv_track.h"
 
-Track *track_new(void)
+GmpvTrack *gmpv_track_new(void)
 {
-	Track *entry = g_malloc(sizeof(Track));
+	GmpvTrack *entry = g_malloc(sizeof(GmpvTrack));
 
 	entry->type = TRACK_TYPE_INVALID;
 	entry->title = NULL;
@@ -31,7 +31,7 @@ Track *track_new(void)
 	return entry;
 }
 
-void track_free(Track *entry)
+void gmpv_track_free(GmpvTrack *entry)
 {
 	if(entry)
 	{
diff --git a/src/track.h b/src/gmpv_track.h
similarity index 88%
rename from src/track.h
rename to src/gmpv_track.h
index 5ca9790..6810a4a 100644
--- a/src/track.h
+++ b/src/gmpv_track.h
@@ -23,7 +23,7 @@
 #include <glib.h>
 
 typedef enum TrackType TrackType;
-typedef struct Track Track;
+typedef struct GmpvTrack GmpvTrack;
 
 enum TrackType
 {
@@ -33,7 +33,7 @@ enum TrackType
 	TRACK_TYPE_SUBTITLE
 };
 
-struct Track
+struct GmpvTrack
 {
 	TrackType type;
 	gint64 id;
@@ -41,7 +41,7 @@ struct Track
 	gchar *lang;
 };
 
-Track *track_new(void);
-void track_free(Track *entry);
+GmpvTrack *gmpv_track_new(void);
+void gmpv_track_free(GmpvTrack *entry);
 
 #endif
diff --git a/src/gmpv_video_area.c b/src/gmpv_video_area.c
new file mode 100644
index 0000000..be6b231
--- /dev/null
+++ b/src/gmpv_video_area.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2016 gnome-mpv
+ *
+ * This file is part of GNOME MPV.
+ *
+ * GNOME MPV 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gmpv_video_area.h"
+#include "gmpv_control_box.h"
+#include "gmpv_def.h"
+
+#ifdef GDK_WINDOWING_WAYLAND
+#include <gdk/gdkwayland.h>
+#endif
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
+struct _GmpvVideoArea
+{
+	GtkOverlay parent_instance;
+	GtkWidget *stack;
+	GtkWidget *draw_area;
+	GtkWidget *gl_area;
+	GtkWidget *control_box;
+	GtkWidget *fs_revealer;
+	guint timeout_tag;
+	gboolean fullscreen;
+	gboolean fs_control_hover;
+};
+
+struct _GmpvVideoAreaClass
+{
+	GtkOverlayClass parent_class;
+};
+
+static void set_cursor_visible(GmpvVideoArea *area, gboolean visible);
+static gboolean timeout_handler(gpointer data);
+static gboolean motion_notify_handler(GtkWidget *widget, GdkEventMotion *event);
+static gboolean fs_control_crossing_handler(	GtkWidget *widget,
+						GdkEventCrossing *event,
+						gpointer data );
+
+G_DEFINE_TYPE(GmpvVideoArea, gmpv_video_area, GTK_TYPE_OVERLAY)
+
+static void set_cursor_visible(GmpvVideoArea *area, gboolean visible)
+{
+	GdkWindow *window;
+	GdkCursor *cursor;
+
+	window = gtk_widget_get_window(GTK_WIDGET(area));
+
+	if(visible)
+	{
+		cursor =	gdk_cursor_new_from_name
+				(gdk_display_get_default(), "default");
+	}
+	else
+	{
+		cursor =	gdk_cursor_new_for_display
+				(gdk_display_get_default(), GDK_BLANK_CURSOR);
+	}
+
+	gdk_window_set_cursor(window, cursor);
+	g_object_unref(cursor);
+}
+
+static gboolean timeout_handler(gpointer data)
+{
+	GmpvVideoArea *area = data;
+	GmpvControlBox *control_box = GMPV_CONTROL_BOX(area->control_box);
+
+	if(area->fullscreen
+	&& !area->fs_control_hover
+	&& !gmpv_control_box_get_volume_popup_visible(control_box))
+	{
+		set_cursor_visible(area, FALSE);
+		gtk_revealer_set_reveal_child
+			(GTK_REVEALER(area->fs_revealer), FALSE);
+	}
+
+	area->timeout_tag = 0;
+
+	return FALSE;
+}
+
+static gboolean motion_notify_handler(GtkWidget *widget, GdkEventMotion *event)
+{
+	GmpvVideoArea *area = GMPV_VIDEO_AREA(widget);
+	GdkCursor *cursor;
+
+	cursor = gdk_cursor_new_from_name(gdk_display_get_default(), "default");
+	gdk_window_set_cursor(gtk_widget_get_window(widget), cursor);
+
+	if(area->fullscreen)
+	{
+		gtk_revealer_set_reveal_child
+			(GTK_REVEALER(area->fs_revealer), TRUE);
+	}
+
+	if(area->timeout_tag > 0)
+	{
+		g_source_remove(area->timeout_tag);
+	}
+
+	area->timeout_tag = g_timeout_add_seconds(	FS_CONTROL_HIDE_DELAY,
+							timeout_handler,
+							area );
+
+	return	GTK_WIDGET_CLASS(gmpv_video_area_parent_class)
+		->motion_notify_event(widget, event);
+}
+
+static gboolean fs_control_crossing_handler(	GtkWidget *widget,
+						GdkEventCrossing *event,
+						gpointer data )
+{
+	GMPV_VIDEO_AREA(data)->fs_control_hover = (event->type == GDK_ENTER_NOTIFY);
+
+	return FALSE;
+}
+
+static void gmpv_video_area_class_init(GmpvVideoAreaClass *klass)
+{
+	GtkWidgetClass *wgt_class = GTK_WIDGET_CLASS(klass);
+
+	wgt_class->motion_notify_event = motion_notify_handler;
+}
+
+static void gmpv_video_area_init(GmpvVideoArea *area)
+{
+	GtkTargetEntry targets[] = DND_TARGETS;
+
+	area->stack = gtk_stack_new();
+	area->draw_area = gtk_drawing_area_new();
+	area->gl_area = gtk_gl_area_new();
+	area->control_box = NULL;
+	area->fs_revealer = gtk_revealer_new();
+	area->timeout_tag = 0;
+	area->fullscreen = FALSE;
+	area->fs_control_hover = FALSE;
+
+	gtk_style_context_add_class
+		(	gtk_widget_get_style_context(area->draw_area),
+			"gmpv-vid-area" );
+
+	gtk_drag_dest_set(	GTK_WIDGET(area),
+				GTK_DEST_DEFAULT_ALL,
+				targets,
+				G_N_ELEMENTS(targets),
+				GDK_ACTION_COPY );
+
+	/* GDK_BUTTON_RELEASE_MASK is needed so that GtkMenuButtons can
+	 * hide their menus when vid_area is clicked.
+	 */
+	gtk_widget_add_events(	area->draw_area,
+				GDK_BUTTON_PRESS_MASK|
+				GDK_BUTTON_RELEASE_MASK|
+				GDK_POINTER_MOTION_MASK );
+	gtk_widget_add_events(	area->gl_area,
+				GDK_BUTTON_PRESS_MASK|
+				GDK_BUTTON_RELEASE_MASK|
+				GDK_POINTER_MOTION_MASK );
+
+	gtk_widget_set_vexpand(area->fs_revealer, FALSE);
+	gtk_widget_set_hexpand(area->fs_revealer, FALSE);
+	gtk_widget_set_halign(area->fs_revealer, GTK_ALIGN_CENTER);
+	gtk_widget_set_valign(area->fs_revealer, GTK_ALIGN_END);
+	gtk_widget_show(area->fs_revealer);
+	gtk_revealer_set_reveal_child(GTK_REVEALER(area->fs_revealer), FALSE);
+
+	g_signal_connect(	area,
+				"enter-notify-event",
+				G_CALLBACK(fs_control_crossing_handler),
+				area );
+	g_signal_connect(	area,
+				"leave-notify-event",
+				G_CALLBACK(fs_control_crossing_handler),
+				area );
+
+	gtk_stack_add_named(GTK_STACK(area->stack), area->draw_area, "draw");
+	gtk_stack_add_named(GTK_STACK(area->stack), area->gl_area, "gl");
+	gtk_stack_set_visible_child(GTK_STACK(area->stack), area->draw_area);
+
+	gtk_overlay_add_overlay(GTK_OVERLAY(area), area->fs_revealer);
+	gtk_container_add(GTK_CONTAINER(area), area->stack);
+}
+
+GtkWidget *gmpv_video_area_new()
+{
+	return GTK_WIDGET(g_object_new(gmpv_video_area_get_type(), NULL));
+}
+
+void gmpv_video_area_set_fullscreen_state(	GmpvVideoArea *area,
+						gboolean fullscreen )
+{
+	if(area->fullscreen != fullscreen)
+	{
+		area->fullscreen = fullscreen;
+
+		gtk_widget_set_visible(area->fs_revealer, fullscreen);
+		set_cursor_visible(area, !fullscreen);
+
+		if(area->control_box)
+		{
+			gmpv_control_box_set_fullscreen_state
+				(GMPV_CONTROL_BOX(area->control_box), fullscreen);
+		}
+	}
+}
+
+void gmpv_video_area_set_control_box(	GmpvVideoArea *area,
+					GtkWidget *control_box )
+{
+	if(area->control_box)
+	{
+		gtk_container_remove
+			(GTK_CONTAINER(area->fs_revealer), area->control_box);
+	}
+
+	area->control_box = control_box;
+
+	if(control_box)
+	{
+		gtk_container_add
+			(GTK_CONTAINER(area->fs_revealer), control_box);
+	}
+}
+
+void gmpv_video_area_set_use_opengl(GmpvVideoArea *area, gboolean use_opengl)
+{
+	gtk_stack_set_visible_child
+		(	GTK_STACK(area->stack),
+			use_opengl?area->gl_area:area->draw_area );
+}
+
+GtkDrawingArea *gmpv_video_area_get_draw_area(GmpvVideoArea *area)
+{
+	return GTK_DRAWING_AREA(area->draw_area);
+}
+
+GtkGLArea *gmpv_video_area_get_gl_area(GmpvVideoArea *area)
+{
+	return GTK_GL_AREA(area->gl_area);
+}
+
+gint64 gmpv_video_area_get_xid(GmpvVideoArea *area)
+{
+#ifdef GDK_WINDOWING_X11
+	if(GDK_IS_X11_DISPLAY(gdk_display_get_default()))
+	{
+		GdkWindow *window = gtk_widget_get_window(area->draw_area);
+
+		g_assert(window);
+
+		return (gint64)gdk_x11_window_get_xid(window);
+	}
+#endif
+
+	return -1;
+}
diff --git a/src/pref_dialog.h b/src/gmpv_video_area.h
similarity index 50%
rename from src/pref_dialog.h
rename to src/gmpv_video_area.h
index 43ae705..6d05fcf 100644
--- a/src/pref_dialog.h
+++ b/src/gmpv_video_area.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 gnome-mpv
+ * Copyright (c) 2016 gnome-mpv
  *
  * This file is part of GNOME MPV.
  *
@@ -17,33 +17,23 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef PREF_DIALOG_H
-#define PREF_DIALOG_H
+#ifndef VIDEO_AREA_H
+#define VIDEO_AREA_H
 
 #include <gtk/gtk.h>
 
-G_BEGIN_DECLS
+#define GMPV_TYPE_VIDEO_AREA (gmpv_video_area_get_type ())
 
-#define PREF_DIALOG_TYPE (pref_dialog_get_type ())
+G_DECLARE_FINAL_TYPE(GmpvVideoArea, gmpv_video_area, GMPV, VIDEO_AREA, GtkOverlay)
 
-#define	PREF_DIALOG(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST((obj), PREF_DIALOG_TYPE, PrefDialog))
-
-#define	PREF_DIALOG_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST((klass), PREF_DIALOG_TYPE, PrefDialogClass))
-
-#define	IS_PREF_DIALOG(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), PREF_DIALOG_TYPE))
-
-#define	IS_PREF_DIALOG_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), PREF_DIALOG_TYPE))
-
-typedef struct _PrefDialog PrefDialog;
-typedef struct _PrefDialogClass PrefDialogClass;
-
-GtkWidget *pref_dialog_new(GtkWindow *parent);
-GType pref_dialog_get_type(void);
-
-G_END_DECLS
+GtkWidget *gmpv_video_area_new(void);
+void gmpv_video_area_set_fullscreen_state(	GmpvVideoArea *area,
+						gboolean fullscreen );
+void gmpv_video_area_set_control_box(	GmpvVideoArea *area,
+					GtkWidget *control_box );
+void gmpv_video_area_set_use_opengl(GmpvVideoArea *area, gboolean use_opengl);
+GtkDrawingArea *gmpv_video_area_get_draw_area(GmpvVideoArea *area);
+GtkGLArea *gmpv_video_area_get_gl_area(GmpvVideoArea *area);
+gint64 gmpv_video_area_get_xid(GmpvVideoArea *area);
 
 #endif
diff --git a/src/main_window.h b/src/main_window.h
deleted file mode 100644
index 9d9ce22..0000000
--- a/src/main_window.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2014-2016 gnome-mpv
- *
- * This file is part of GNOME MPV.
- *
- * GNOME MPV 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 3 of the License, or
- * (at your option) any later version.
- *
- * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MAIN_WINDOW_H
-#define MAIN_WINDOW_H
-
-#include <gtk/gtk.h>
-
-#include "playlist.h"
-
-G_BEGIN_DECLS
-
-#define MAIN_WINDOW_TYPE (main_window_get_type ())
-
-#define	MAIN_WINDOW(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST((obj), MAIN_WINDOW_TYPE, MainWindow))
-
-#define	MAIN_WINDOW_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST((klass), MAIN_WINDOW_TYPE, MainWindowClass))
-
-#define	IS_MAIN_WINDOW(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), MAIN_WINDOW_TYPE))
-
-#define	IS_MAIN_WINDOW_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), MAIN_WINDOW_TYPE))
-
-typedef struct _MainWindow MainWindow;
-typedef struct _MainWindowClass MainWindowClass;
-typedef struct _MainWindowPrivate MainWindowPrivate;
-typedef struct _Application Application;
-
-struct _MainWindow
-{
-	GtkApplicationWindow parent_instance;
-	MainWindowPrivate *priv;
-	gboolean fullscreen;
-	gboolean playlist_visible;
-	gboolean fs_control_hover;
-	gboolean pre_fs_playlist_visible;
-	gint playlist_width;
-	guint timeout_tag;
-	GtkSettings* settings;
-	GtkWidget *header_bar;
-	GtkWidget *open_hdr_btn;
-	GtkWidget *fullscreen_hdr_btn;
-	GtkWidget *menu_hdr_btn;
-	GtkWidget *main_box;
-	GtkWidget *vid_area_paned;
-	GtkWidget *vid_area_overlay;
-	GtkWidget *vid_area;
-	GtkWidget *control_box;
-	GtkWidget *fs_revealer;
-	GtkWidget *playlist;
-};
-
-struct _MainWindowClass
-{
-	GtkApplicationWindowClass parent_class;
-};
-
-GtkWidget *main_window_new(	Application *app,
-				Playlist *playlist,
-				gboolean use_opengl );
-GType main_window_get_type(void);
-void main_window_set_fullscreen(MainWindow *wnd, gboolean fullscreen);
-void main_window_toggle_fullscreen(MainWindow *wnd);
-void main_window_reset(MainWindow *wnd);
-void main_window_save_state(MainWindow *wnd);
-void main_window_load_state(MainWindow *wnd);
-void main_window_update_track_list(	MainWindow *wnd,
-					const GSList *audio_list,
-					const GSList *video_list,
-					const GSList *sub_list );
-void main_window_resize_video_area(	MainWindow *wnd,
-					gint width,
-					gint height );
-gboolean main_window_get_use_opengl(MainWindow *wnd);
-void main_window_enable_csd(MainWindow *wnd);
-gboolean main_window_get_csd_enabled(MainWindow *wnd);
-void main_window_set_playlist_visible(MainWindow *wnd, gboolean visible);
-gboolean main_window_get_playlist_visible(MainWindow *wnd);
-
-G_END_DECLS
-
-#endif
diff --git a/src/media_keys/media_keys.c b/src/media_keys/gmpv_media_keys.c
similarity index 74%
rename from src/media_keys/media_keys.c
rename to src/media_keys/gmpv_media_keys.c
index 4b26c08..9b8469e 100644
--- a/src/media_keys/media_keys.c
+++ b/src/media_keys/gmpv_media_keys.c
@@ -17,8 +17,8 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "media_keys.h"
-#include "def.h"
+#include "gmpv_media_keys.h"
+#include "gmpv_def.h"
 
 static gboolean delete_handler(	GtkWidget *widget,
 				GdkEvent *event,
@@ -39,13 +39,11 @@ static gboolean delete_handler(	GtkWidget *widget,
 				GdkEvent *event,
 				gpointer data )
 {
-	media_keys *inst = data;
+	gmpv_media_keys *inst = data;
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(inst->gmpv_ctx);
 
-	g_signal_handler_disconnect(	inst->gmpv_ctx->gui,
-					inst->shutdown_sig_id );
-
-	g_signal_handler_disconnect(	inst->proxy,
-					inst->g_signal_sig_id );
+	g_signal_handler_disconnect(wnd, inst->shutdown_sig_id);
+	g_signal_handler_disconnect(inst->proxy, inst->g_signal_sig_id);
 
 	g_object_unref(inst->proxy);
 	g_object_unref(inst->session_bus_conn);
@@ -60,60 +58,60 @@ static void media_key_press_handler(	GDBusProxy *proxy,
 					GVariant *parameters,
 					gpointer data )
 {
-	media_keys *inst = data;
-	gchar *application = NULL;
+	gmpv_media_keys *inst = data;
+	gchar *gmpv_application = NULL;
 	gchar *key = NULL;
 
 	if(g_strcmp0(signal_name, "MediaPlayerKeyPressed") == 0)
 	{
-		g_variant_get(parameters, "(&s&s)", &application, &key);
+		g_variant_get(parameters, "(&s&s)", &gmpv_application, &key);
 	}
 
-	if(g_strcmp0(application, APP_ID) == 0)
+	if(g_strcmp0(gmpv_application, APP_ID) == 0)
 	{
+		GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
+
 		if(g_strcmp0(key, "Next") == 0)
 		{
 			const gchar *cmd[] = {"playlist_next", "weak", NULL};
 
-			mpv_command(inst->gmpv_ctx->mpv->mpv_ctx, cmd);
+			gmpv_mpv_obj_command(mpv, cmd);
 		}
 		else if(g_strcmp0(key, "Previous") == 0)
 		{
 			const gchar *cmd[] = {"playlist_prev", "weak", NULL};
 
-			mpv_command(inst->gmpv_ctx->mpv->mpv_ctx, cmd);
+			gmpv_mpv_obj_command(mpv, cmd);
 		}
 		else if(g_strcmp0(key, "Pause") == 0)
 		{
-			mpv_obj_set_property_flag(inst->gmpv_ctx->mpv, "pause", TRUE);
+			gmpv_mpv_obj_set_property_flag(mpv, "pause", TRUE);
 		}
 		else if(g_strcmp0(key, "Stop") == 0)
 		{
 			const gchar *cmd[] = {"stop", NULL};
 
-			mpv_command(inst->gmpv_ctx->mpv->mpv_ctx, cmd);
+			gmpv_mpv_obj_command(mpv, cmd);
 		}
 		else if(g_strcmp0(key, "Play") == 0)
 		{
 			gboolean paused;
 
-			paused =	mpv_obj_get_property_flag
-					(inst->gmpv_ctx->mpv, "pause");
+			paused = gmpv_mpv_obj_get_property_flag(mpv, "pause");
 
-			mpv_obj_set_property_flag
-				(inst->gmpv_ctx->mpv, "pause", !paused);
+			gmpv_mpv_obj_set_property_flag(mpv, "pause", !paused);
 		}
 		else if(g_strcmp0(key, "FastForward") == 0)
 		{
 			const gchar *cmd[] = {"seek", "10", NULL};
 
-			mpv_command(inst->gmpv_ctx->mpv->mpv_ctx, cmd);
+			gmpv_mpv_obj_command(mpv, cmd);
 		}
 		else if(g_strcmp0(key, "Rewind") == 0)
 		{
 			const gchar *cmd[] = {"seek", "-10", NULL};
 
-			mpv_command(inst->gmpv_ctx->mpv->mpv_ctx, cmd);
+			gmpv_mpv_obj_command(mpv, cmd);
 		}
 	}
 }
@@ -122,7 +120,7 @@ static void proxy_ready_handler(	GObject *source_object,
 					GAsyncResult *res,
 					gpointer data )
 {
-	media_keys *inst = data;
+	gmpv_media_keys *inst = data;
 
 	inst->proxy = g_dbus_proxy_new_finish(res, NULL);
 
@@ -146,7 +144,7 @@ static void session_ready_handler(	GObject *source_object,
 					GAsyncResult *res,
 					gpointer data )
 {
-	media_keys *inst = data;
+	gmpv_media_keys *inst = data;
 
 	inst->session_bus_conn = g_bus_get_finish(res, NULL);
 
@@ -161,17 +159,18 @@ static void session_ready_handler(	GObject *source_object,
 				inst );
 }
 
-void media_keys_init(Application *gmpv_ctx)
+void gmpv_media_keys_init(GmpvApplication *gmpv_ctx)
 {
-	media_keys *inst = g_malloc(sizeof(media_keys));
+	gmpv_media_keys *inst = g_malloc(sizeof(gmpv_media_keys));
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(gmpv_ctx);
 
 	inst->gmpv_ctx = gmpv_ctx;
 	inst->shutdown_sig_id = 0;
 	inst->proxy = NULL;
 	inst->session_bus_conn = NULL;
 
-	inst->shutdown_sig_id
-		= g_signal_connect(	inst->gmpv_ctx->gui,
+	inst->shutdown_sig_id =	g_signal_connect
+				(	wnd,
 					"delete-event",
 					G_CALLBACK(delete_handler),
 					inst );
diff --git a/src/media_keys/media_keys.h b/src/media_keys/gmpv_media_keys.h
similarity index 83%
rename from src/media_keys/media_keys.h
rename to src/media_keys/gmpv_media_keys.h
index b730ebd..d52b462 100644
--- a/src/media_keys/media_keys.h
+++ b/src/media_keys/gmpv_media_keys.h
@@ -20,19 +20,19 @@
 #ifndef MEDIA_KEYS_H
 #define MEDIA_KEYS_H
 
-#include "common.h"
+#include "gmpv_common.h"
 
-typedef struct media_keys media_keys;
+typedef struct gmpv_media_keys gmpv_media_keys;
 
-struct media_keys
+struct gmpv_media_keys
 {
-	Application *gmpv_ctx;
+	GmpvApplication *gmpv_ctx;
 	gulong g_signal_sig_id;
 	gulong shutdown_sig_id;
 	GDBusProxy *proxy;
 	GDBusConnection *session_bus_conn;
 };
 
-void media_keys_init(Application *gmpv_ctx);
+void gmpv_media_keys_init(GmpvApplication *gmpv_ctx);
 
 #endif
diff --git a/src/mpris/mpris.c b/src/mpris/gmpv_mpris.c
similarity index 72%
rename from src/mpris/mpris.c
rename to src/mpris/gmpv_mpris.c
index 9aa1a0b..f66f188 100644
--- a/src/mpris/mpris.c
+++ b/src/mpris/gmpv_mpris.c
@@ -21,11 +21,11 @@
 #include <gio/gio.h>
 #include <gtk/gtk.h>
 
-#include "mpris.h"
-#include "mpris_base.h"
-#include "mpris_player.h"
-#include "mpris_gdbus.h" /* auto-generated */
-#include "def.h"
+#include "gmpv_mpris.h"
+#include "gmpv_mpris_base.h"
+#include "gmpv_mpris_player.h"
+#include "gmpv_mpris_gdbus.h" /* auto-generated */
+#include "gmpv_def.h"
 
 static void bus_acquired_handler(	GDBusConnection *connection,
 					const gchar *name,
@@ -36,18 +36,18 @@ static void name_lost_handler(	GDBusConnection *connection,
 static gboolean delete_handler(	GtkWidget *widget,
 				GdkEvent *event,
 				gpointer data );
-static void unregister(mpris *inst);
+static void unregister(gmpv_mpris *inst);
 
 static void bus_acquired_handler(	GDBusConnection *connection,
 					const gchar *name,
 					gpointer data )
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
 
 	inst->session_bus_conn = connection;
 
-	mpris_base_register(inst);
-	mpris_player_register(inst);
+	gmpv_mpris_base_register(inst);
+	gmpv_mpris_player_register(inst);
 }
 
 static void name_lost_handler(	GDBusConnection *connection,
@@ -61,10 +61,10 @@ static gboolean delete_handler(	GtkWidget *widget,
 				GdkEvent *event,
 				gpointer data )
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(inst->gmpv_ctx);
 
-	g_signal_handler_disconnect(	inst->gmpv_ctx->gui,
-					inst->shutdown_sig_id );
+	g_signal_handler_disconnect(wnd, inst->shutdown_sig_id);
 
 	unregister(inst);
 	g_bus_unown_name(inst->name_id);
@@ -73,33 +73,37 @@ static gboolean delete_handler(	GtkWidget *widget,
 	return FALSE;
 }
 
-static void unregister(mpris *inst)
+static void unregister(gmpv_mpris *inst)
 {
 	if(inst->base_reg_id > 0)
 	{
-		mpris_base_unregister(inst);
+		gmpv_mpris_base_unregister(inst);
 	}
 
 	if(inst->player_reg_id > 0)
 	{
-		mpris_player_unregister(inst);
+		gmpv_mpris_player_unregister(inst);
 	}
 }
 
-void mpris_emit_prop_changed(	mpris *inst,
-				const gchar *iface_name,
-				const mpris_prop_val_pair *prop_list )
+void gmpv_mpris_emit_prop_changed(	gmpv_mpris *inst,
+					const gchar *iface_name,
+					const gmpv_mpris_prop *prop_list )
 {
-	const mpris_prop_val_pair *current;
+	const gmpv_mpris_prop *current;
 	GVariantBuilder builder;
 	GVariant *sig_args;
 
+	g_debug("Emitting property change event on interface %s", iface_name);
+
 	current = prop_list;
 
 	g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
 
 	while(current && current->name != NULL)
 	{
+		g_debug("Adding property: %s", current->name);
+
 		g_variant_builder_add(	&builder,
 					"{sv}",
 					current->name,
@@ -123,7 +127,7 @@ void mpris_emit_prop_changed(	mpris *inst,
 			NULL );
 }
 
-GVariant *mpris_build_g_variant_string_array(const gchar** list)
+GVariant *gmpv_mpris_build_g_variant_string_array(const gchar** list)
 {
 	GVariantBuilder builder;
 	gint i;
@@ -138,9 +142,9 @@ GVariant *mpris_build_g_variant_string_array(const gchar** list)
 	return g_variant_new("as", &builder);
 }
 
-void mpris_init(Application *gmpv_ctx)
+void gmpv_mpris_init(GmpvApplication *gmpv_ctx)
 {
-	mpris *inst = g_malloc(sizeof(mpris));
+	gmpv_mpris *inst = g_malloc(sizeof(gmpv_mpris));
 
 	inst->gmpv_ctx = gmpv_ctx;
 	inst->name_id = 0;
@@ -155,10 +159,11 @@ void mpris_init(Application *gmpv_ctx)
 	inst->session_bus_conn = NULL;
 
 	inst->shutdown_sig_id
-		= g_signal_connect(	inst->gmpv_ctx->gui,
-					"delete-event",
-					G_CALLBACK(delete_handler),
-					inst );
+		= g_signal_connect
+			(	gmpv_application_get_main_window(gmpv_ctx),
+				"delete-event",
+				G_CALLBACK(delete_handler),
+				inst );
 
 	inst->name_id = g_bus_own_name(	G_BUS_TYPE_SESSION,
 					MPRIS_BUS_NAME,
diff --git a/src/mpris/mpris.h b/src/mpris/gmpv_mpris.h
similarity index 71%
rename from src/mpris/mpris.h
rename to src/mpris/gmpv_mpris.h
index d4de290..63ef471 100644
--- a/src/mpris/mpris.h
+++ b/src/mpris/gmpv_mpris.h
@@ -20,14 +20,14 @@
 #ifndef MPRIS_H
 #define MPRIS_H
 
-#include "common.h"
+#include "gmpv_common.h"
 
-typedef struct mpris mpris;
-typedef struct mpris_prop_val_pair mpris_prop_val_pair;
+typedef struct gmpv_mpris gmpv_mpris;
+typedef struct gmpv_mpris_prop gmpv_mpris_prop;
 
-struct mpris
+struct gmpv_mpris
 {
-	Application* gmpv_ctx;
+	GmpvApplication* gmpv_ctx;
 	guint name_id;
 	guint base_reg_id;
 	guint player_reg_id;
@@ -40,16 +40,16 @@ struct mpris
 	GDBusConnection *session_bus_conn;
 };
 
-struct mpris_prop_val_pair
+struct gmpv_mpris_prop
 {
 	gchar *name;
 	GVariant *value;
 };
 
-void mpris_emit_prop_changed(	mpris *inst,
-				const gchar *iface_name,
-				const mpris_prop_val_pair *prop_list );
-GVariant *mpris_build_g_variant_string_array(const gchar** list);
-void mpris_init(Application *gmpv_ctx);
+void gmpv_mpris_emit_prop_changed(	gmpv_mpris *inst,
+					const gchar *iface_name,
+					const gmpv_mpris_prop *prop_list );
+GVariant *gmpv_mpris_build_g_variant_string_array(const gchar** list);
+void gmpv_mpris_init(GmpvApplication *gmpv_ctx);
 
 #endif
diff --git a/src/mpris/mpris_base.c b/src/mpris/gmpv_mpris_base.c
similarity index 72%
rename from src/mpris/mpris_base.c
rename to src/mpris/gmpv_mpris_base.c
index bd69b31..7e64cdc 100644
--- a/src/mpris/mpris_base.c
+++ b/src/mpris/gmpv_mpris_base.c
@@ -17,11 +17,11 @@
  * along with GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "mpris_base.h"
-#include "mpris_gdbus.h"
-#include "def.h"
+#include "gmpv_mpris_base.h"
+#include "gmpv_mpris_gdbus.h"
+#include "gmpv_def.h"
 
-static void prop_table_init(mpris *inst);
+static void prop_table_init(gmpv_mpris *inst);
 static void method_handler(	GDBusConnection *connection,
 				const gchar *sender,
 				const gchar *object_path,
@@ -51,7 +51,7 @@ static gboolean window_state_handler(	GtkWidget *widget,
 static GVariant *get_supported_uri_schemes(void);
 static GVariant *get_supported_mime_types(void);
 
-static void prop_table_init(mpris *inst)
+static void prop_table_init(gmpv_mpris *inst)
 {
 	const gpointer default_values[]
 		= {	"CanQuit", g_variant_new_boolean(TRUE),
@@ -84,11 +84,14 @@ static void method_handler(	GDBusConnection *connection,
 				GDBusMethodInvocation *invocation,
 				gpointer data )
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
 
 	if(g_strcmp0(method_name, "Raise") == 0)
 	{
-		gtk_window_present(GTK_WINDOW(inst->gmpv_ctx->gui));
+		GmpvMainWindow *wnd =	gmpv_application_get_main_window
+					(inst->gmpv_ctx);
+
+		gtk_window_present(GTK_WINDOW(wnd));
 	}
 	else if(g_strcmp0(method_name, "Quit") == 0)
 	{
@@ -107,7 +110,7 @@ static GVariant *get_prop_handler(	GDBusConnection *connection,
 					GError **error,
 					gpointer data )
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
 	GVariant *value;
 
 	value = g_hash_table_lookup(	inst->base_prop_table,
@@ -125,16 +128,17 @@ static gboolean set_prop_handler(	GDBusConnection *connection,
 					GError **error,
 					gpointer data )
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(inst->gmpv_ctx);
 
 	if(g_strcmp0(property_name, "Fullscreen") == 0
-	&& g_variant_get_boolean(value) != inst->gmpv_ctx->gui->fullscreen)
+	&& g_variant_get_boolean(value) != gmpv_main_window_get_fullscreen(wnd))
 	{
-		main_window_toggle_fullscreen(inst->gmpv_ctx->gui);
+		gmpv_main_window_toggle_fullscreen(wnd);
 	}
 	else
 	{
-		g_hash_table_replace(	((mpris *) data)->base_prop_table,
+		g_hash_table_replace(	((gmpv_mpris *) data)->base_prop_table,
 					g_strdup(property_name),
 					g_variant_ref(value) );
 	}
@@ -146,27 +150,29 @@ static gboolean window_state_handler(	GtkWidget *widget,
 					GdkEvent *event,
 					gpointer data )
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(inst->gmpv_ctx);
 	GdkEventWindowState *window_state_event = (GdkEventWindowState *)event;
 
 	if(window_state_event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
 	{
 		GDBusInterfaceInfo *iface;
 		GVariant *value;
-		mpris_prop_val_pair *prop_list;
+		gmpv_mpris_prop *prop_list;
 
-		iface = mpris_org_mpris_media_player2_interface_info();
-		value = g_variant_new_boolean(inst->gmpv_ctx->gui->fullscreen);
+		iface = gmpv_mpris_org_mpris_media_player2_interface_info();
+		value =	g_variant_new_boolean
+			(gmpv_main_window_get_fullscreen(wnd));
 
 		g_hash_table_replace(	inst->base_prop_table,
 					g_strdup("Fullscreen"),
 					g_variant_ref(value) );
 
-		prop_list =	(mpris_prop_val_pair[])
+		prop_list =	(gmpv_mpris_prop[])
 				{	{"Fullscreen", value},
 					{NULL, NULL} };
 
-		mpris_emit_prop_changed(inst, iface->name, prop_list);
+		gmpv_mpris_emit_prop_changed(inst, iface->name, prop_list);
 	}
 
 	return FALSE;
@@ -176,38 +182,37 @@ static GVariant *get_supported_uri_schemes(void)
 {
 	const gchar *protocols[] = SUPPORTED_PROTOCOLS;
 
-	return mpris_build_g_variant_string_array(protocols);
+	return gmpv_mpris_build_g_variant_string_array(protocols);
 }
 
 static GVariant *get_supported_mime_types(void)
 {
 	const gchar *mime_types[] = SUPPORTED_MIME_TYPES;
 
-	return mpris_build_g_variant_string_array(mime_types);
+	return gmpv_mpris_build_g_variant_string_array(mime_types);
 }
 
-void mpris_base_register(mpris *inst)
+void gmpv_mpris_base_register(gmpv_mpris *inst)
 {
+	GmpvMainWindow *wnd;
 	GDBusInterfaceVTable vtable;
 	GDBusInterfaceInfo *iface;
 
-	iface = mpris_org_mpris_media_player2_interface_info();
-
-	inst->base_prop_table = g_hash_table_new_full
-					(	g_str_hash,
-						g_str_equal,
-						NULL,
-						(GDestroyNotify)
-						g_variant_unref );
+	wnd = gmpv_application_get_main_window(inst->gmpv_ctx);
+	iface = gmpv_mpris_org_mpris_media_player2_interface_info();
 
+	inst->base_prop_table =	g_hash_table_new_full
+				(	g_str_hash,
+					g_str_equal,
+					NULL,
+					(GDestroyNotify)g_variant_unref );
 	inst->base_sig_id_list = g_malloc(2*sizeof(gulong));
 
-	inst->base_sig_id_list[0]
-		= g_signal_connect(	inst->gmpv_ctx->gui,
-					"window-state-event",
-					G_CALLBACK(window_state_handler),
-					inst );
-
+	inst->base_sig_id_list[0] =	g_signal_connect
+					(	wnd,
+						"window-state-event",
+						G_CALLBACK(window_state_handler),
+						inst );
 	inst->base_sig_id_list[1] = 0;
 
 	prop_table_init(inst);
@@ -216,18 +221,17 @@ void mpris_base_register(mpris *inst)
 	vtable.get_property = (GDBusInterfaceGetPropertyFunc)get_prop_handler;
 	vtable.set_property = (GDBusInterfaceSetPropertyFunc)set_prop_handler;
 
-	inst->base_reg_id
-		= g_dbus_connection_register_object
-			(	inst->session_bus_conn,
-				MPRIS_OBJ_ROOT_PATH,
-				iface,
-				&vtable,
-				inst,
-				NULL,
-				NULL );
+	inst->base_reg_id =	g_dbus_connection_register_object
+				(	inst->session_bus_conn,
+					MPRIS_OBJ_ROOT_PATH,
+					iface,
+					&vtable,
+					inst,
+					NULL,
+					NULL );
 }
 
-void mpris_base_unregister(mpris *inst)
+void gmpv_mpris_base_unregister(gmpv_mpris *inst)
 {
 	gulong *current_sig_id = inst->base_sig_id_list;
 
@@ -235,8 +239,10 @@ void mpris_base_unregister(mpris *inst)
 	{
 		while(current_sig_id && *current_sig_id > 0)
 		{
-			g_signal_handler_disconnect(	inst->gmpv_ctx->gui,
-							*current_sig_id );
+			GmpvMainWindow *wnd;
+
+			wnd = gmpv_application_get_main_window(inst->gmpv_ctx);
+			g_signal_handler_disconnect(wnd, *current_sig_id);
 
 			current_sig_id++;
 		}
diff --git a/src/mpris/mpris_base.h b/src/mpris/gmpv_mpris_base.h
similarity index 82%
rename from src/mpris/mpris_base.h
rename to src/mpris/gmpv_mpris_base.h
index 55cda2c..151cd7b 100644
--- a/src/mpris/mpris_base.h
+++ b/src/mpris/gmpv_mpris_base.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 gnome-mpv
+ * Copyright (c) 2015-2016 gnome-mpv
  *
  * This file is part of GNOME MPV.
  *
@@ -20,9 +20,9 @@
 #ifndef MPRIS_BASE_H
 #define MPRIS_BASE_H
 
-#include "mpris.h"
+#include "gmpv_mpris.h"
 
-void mpris_base_register(mpris *inst);
-void mpris_base_unregister(mpris *inst);
+void gmpv_mpris_base_register(gmpv_mpris *inst);
+void gmpv_mpris_base_unregister(gmpv_mpris *inst);
 
 #endif
diff --git a/src/mpris/mpris_player.c b/src/mpris/gmpv_mpris_player.c
similarity index 57%
rename from src/mpris/mpris_player.c
rename to src/mpris/gmpv_mpris_player.c
index 1719eaa..c95eb3f 100644
--- a/src/mpris/mpris_player.c
+++ b/src/mpris/gmpv_mpris_player.c
@@ -19,13 +19,15 @@
 
 #include <string.h>
 
-#include "mpris_player.h"
-#include "mpris_gdbus.h"
-#include "mpv_obj.h"
-#include "def.h"
-
-static void prop_table_init(mpris *inst);
-static void emit_prop_changed(mpris *inst, const mpris_prop_val_pair *prop_list);
+#include "gmpv_mpris_player.h"
+#include "gmpv_mpris_gdbus.h"
+#include "gmpv_mpv_obj.h"
+#include "gmpv_def.h"
+
+static void prop_table_init(gmpv_mpris *inst);
+static void emit_prop_changed(	gmpv_mpris *inst,
+				const gmpv_mpris_prop *prop_list );
+static void append_metadata_tags(GVariantBuilder *builder, mpv_node_list *list);
 static void method_handler(	GDBusConnection *connection,
 				const gchar *sender,
 				const gchar *object_path,
@@ -49,18 +51,18 @@ static gboolean set_prop_handler(	GDBusConnection *connection,
 					GVariant *value,
 					GError **error,
 					gpointer data );
-static void playback_status_update_handler(mpris *inst);
-static void playlist_update_handler(mpris *inst);
-static void speed_update_handler(mpris *inst);
-static void metadata_update_handler(mpris *inst);
-static void volume_update_handler(mpris *inst);
-static void mpv_init_handler(MainWindow *wnd, gpointer data);
-static void mpv_playback_restart_handler(MainWindow *wnd, gpointer data);
-static void mpv_prop_change_handler(	MainWindow *wnd,
+static void playback_status_update_handler(gmpv_mpris *inst);
+static void playlist_update_handler(gmpv_mpris *inst);
+static void speed_update_handler(gmpv_mpris *inst);
+static void metadata_update_handler(gmpv_mpris *inst);
+static void volume_update_handler(gmpv_mpris *inst);
+static void mpv_init_handler(GmpvMainWindow *wnd, gpointer data);
+static void mpv_playback_restart_handler(GmpvMainWindow *wnd, gpointer data);
+static void mpv_prop_change_handler(	GmpvMainWindow *wnd,
 					gchar *name,
 					gpointer data );
 
-static void prop_table_init(mpris *inst)
+static void prop_table_init(gmpv_mpris *inst)
 {
 	/* Position is retrieved from mpv on-demand */
 	const gpointer default_values[]
@@ -88,12 +90,90 @@ static void prop_table_init(mpris *inst)
 	}
 }
 
-static void emit_prop_changed(mpris *inst, const mpris_prop_val_pair *prop_list)
+static void emit_prop_changed(gmpv_mpris *inst, const gmpv_mpris_prop *prop_list)
 {
 	GDBusInterfaceInfo *iface;
 
-	iface = mpris_org_mpris_media_player2_player_interface_info();
-	mpris_emit_prop_changed(inst, iface->name, prop_list);
+	iface = gmpv_mpris_org_mpris_media_player2_player_interface_info();
+	gmpv_mpris_emit_prop_changed(inst, iface->name, prop_list);
+}
+
+static void append_metadata_tags(GVariantBuilder *builder, mpv_node_list *list)
+{
+	const struct
+	{
+		const gchar *mpv_name;
+		const gchar *tag_name;
+		const gboolean is_array;
+	}
+	tag_map[] = {	{"Album", "xesam:album", FALSE},
+			{"Album_Artist", "xesam:albumArtist", TRUE},
+			{"Artist", "xesam:artist", TRUE},
+			{"Comment", "xesam:comment", TRUE},
+			{"Composer", "xesam:composer", FALSE},
+			{"Genre", "xesam:genre", TRUE},
+			{"Title", "xesam:title", FALSE},
+			{NULL, NULL, FALSE} };
+
+	g_assert(list);
+
+	for(gint i = 0; i < list->num; i++)
+	{
+		GVariantBuilder tag_builder;
+		mpv_node mpv_value = list->values[i];
+		const gchar *mpv_key = list->keys[i];
+		const gchar *tag_name;
+		GVariant *tag_value;
+		gboolean is_array = TRUE;
+		gboolean valid = TRUE;
+		gint j = -1;
+
+		g_assert(mpv_key);
+
+		while(	tag_map[++j].mpv_name &&
+			g_ascii_strcasecmp(mpv_key, tag_map[j].mpv_name) != 0 );
+		tag_name = tag_map[j].mpv_name?tag_map[j].tag_name:mpv_key;
+		is_array = tag_map[j].mpv_name?tag_map[j].is_array:FALSE;
+
+		if(!is_array && mpv_value.format == MPV_FORMAT_STRING)
+		{
+			tag_value = g_variant_new_string(mpv_value.u.string);
+		}
+		else if(is_array && mpv_value.format == MPV_FORMAT_STRING)
+		{
+			GVariant *elem_value = 	g_variant_new_string
+						(mpv_value.u.string);
+
+			g_variant_builder_init
+				(&tag_builder, G_VARIANT_TYPE("as"));
+			g_variant_builder_add_value
+				(&tag_builder, elem_value);
+
+			tag_value = g_variant_new("as", &tag_builder);
+		}
+		else
+		{
+			valid = FALSE;
+		}
+
+		if(valid)
+		{
+			g_debug(	"Adding metadata tag \"%s\" "
+					"with type %d",
+					tag_name,
+					mpv_value.format );
+
+			g_variant_builder_add
+				(builder, "{sv}", tag_name, tag_value);
+		}
+		else
+		{
+			g_warning(	"Ignoring metadata entry \"%s\" "
+					"with unsupported format %d",
+					tag_name,
+					mpv_value.format );
+		}
+	}
 }
 
 static void method_handler(	GDBusConnection *connection,
@@ -105,43 +185,42 @@ static void method_handler(	GDBusConnection *connection,
 				GDBusMethodInvocation *invocation,
 				gpointer data )
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
 
 	if(g_strcmp0(method_name, "Next") == 0)
 	{
 		const gchar *cmd[] = {"playlist_next", "weak", NULL};
 
-		mpv_command(inst->gmpv_ctx->mpv->mpv_ctx, cmd);
+		gmpv_mpv_obj_command(mpv, cmd);
 	}
 	else if(g_strcmp0(method_name, "Previous") == 0)
 	{
 		const gchar *cmd[] = {"playlist_prev", "weak", NULL};
 
-		mpv_command(inst->gmpv_ctx->mpv->mpv_ctx, cmd);
+		gmpv_mpv_obj_command(mpv, cmd);
 	}
 	else if(g_strcmp0(method_name, "Pause") == 0)
 	{
-		mpv_obj_set_property_flag(inst->gmpv_ctx->mpv, "pause", TRUE);
+		gmpv_mpv_obj_set_property_flag(mpv, "pause", TRUE);
 	}
 	else if(g_strcmp0(method_name, "PlayPause") == 0)
 	{
 		gboolean paused;
 
-		paused =	mpv_obj_get_property_flag
-				(inst->gmpv_ctx->mpv, "pause");
+		paused = gmpv_mpv_obj_get_property_flag(mpv, "pause");
 
-		mpv_obj_set_property_flag
-			(inst->gmpv_ctx->mpv, "pause", !paused);
+		gmpv_mpv_obj_set_property_flag(mpv, "pause", !paused);
 	}
 	else if(g_strcmp0(method_name, "Stop") == 0)
 	{
 		const gchar *cmd[] = {"stop", NULL};
 
-		mpv_command(inst->gmpv_ctx->mpv->mpv_ctx, cmd);
+		gmpv_mpv_obj_command(mpv, cmd);
 	}
 	else if(g_strcmp0(method_name, "Play") == 0)
 	{
-		mpv_obj_set_property_flag(inst->gmpv_ctx->mpv, "pause", FALSE);
+		gmpv_mpv_obj_set_property_flag(mpv, "pause", FALSE);
 	}
 	else if(g_strcmp0(method_name, "Seek") == 0)
 	{
@@ -150,17 +229,17 @@ static void method_handler(	GDBusConnection *connection,
 
 		g_variant_get(parameters, "(x)", &offset_us);
 
-		mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-					"time-pos",
-					MPV_FORMAT_DOUBLE,
-					&position );
+		gmpv_mpv_obj_get_property(	mpv,
+						"time-pos",
+						MPV_FORMAT_DOUBLE,
+						&position );
 
 		position += (gdouble)offset_us/1.0e6;
 
-		mpv_set_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-					"time-pos",
-					MPV_FORMAT_DOUBLE,
-					&position );
+		gmpv_mpv_obj_set_property(	mpv,
+						"time-pos",
+						MPV_FORMAT_DOUBLE,
+						&position );
 
 		g_dbus_connection_emit_signal
 			(	inst->session_bus_conn,
@@ -187,22 +266,25 @@ static void method_handler(	GDBusConnection *connection,
 			inst->pending_seek = (gdouble)time_us/1.0e6;
 			index = g_ascii_strtoll(track_id+prefix_len, NULL, 0);
 
-			mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-						"playlist-pos",
-						MPV_FORMAT_INT64,
-						&old_index );
+			gmpv_mpv_obj_get_property(	mpv,
+							"playlist-pos",
+							MPV_FORMAT_INT64,
+							&old_index );
 
 			if(index != old_index)
 			{
-				mpv_set_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-							"playlist-pos",
-							MPV_FORMAT_INT64,
-							&index );
+				gmpv_mpv_obj_set_property(	mpv,
+								"playlist-pos",
+								MPV_FORMAT_INT64,
+								&index );
 			}
 			else
 			{
-				mpv_playback_restart_handler
-					(inst->gmpv_ctx->gui, inst);
+				GmpvMainWindow *wnd;
+
+				wnd =	gmpv_application_get_main_window
+					(inst->gmpv_ctx);
+				mpv_playback_restart_handler(wnd, inst);
 			}
 		}
 	}
@@ -211,7 +293,7 @@ static void method_handler(	GDBusConnection *connection,
 		const gchar *uri;
 
 		g_variant_get(parameters, "(&s)", &uri);
-		mpv_obj_load(inst->gmpv_ctx->mpv, uri, FALSE, TRUE);
+		gmpv_mpv_obj_load(mpv, uri, FALSE, TRUE);
 	}
 
 	g_dbus_method_invocation_return_value
@@ -226,19 +308,22 @@ static GVariant *get_prop_handler(	GDBusConnection *connection,
 					GError **error,
 					gpointer data )
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
 	GVariant *value;
 
 	if(g_strcmp0(property_name, "Position") == 0)
 	{
+		GmpvMpvObj *mpv;
+		mpv_handle *mpv_ctx;
 		gdouble position;
 		gint rc;
 
-		rc = mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
+		mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
+		mpv_ctx = gmpv_mpv_obj_get_mpv_handle(mpv);
+		rc = mpv_get_property(	mpv_ctx,
 					"time-pos",
 					MPV_FORMAT_DOUBLE,
 					&position );
-
 		value = g_variant_new_int64((gint64)((rc >= 0)*position*1e6));
 	}
 	else
@@ -259,25 +344,26 @@ static gboolean set_prop_handler(	GDBusConnection *connection,
 					GError **error,
 					gpointer data )
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
 
 	if(g_strcmp0(property_name, "Rate") == 0)
 	{
 		gdouble rate = g_variant_get_double(value);
 
-		mpv_set_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-					"speed",
-					MPV_FORMAT_DOUBLE,
-					&rate );
+		gmpv_mpv_obj_set_property(	mpv,
+						"speed",
+						MPV_FORMAT_DOUBLE,
+						&rate );
 	}
 	else if(g_strcmp0(property_name, "Volume") == 0)
 	{
 		gdouble volume = 100*g_variant_get_double(value);
 
-		mpv_set_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-					"volume",
-					MPV_FORMAT_DOUBLE,
-					&volume );
+		gmpv_mpv_obj_set_property(	mpv,
+						"volume",
+						MPV_FORMAT_DOUBLE,
+						&volume );
 	}
 
 	g_hash_table_replace(	inst->player_prop_table,
@@ -287,32 +373,29 @@ static gboolean set_prop_handler(	GDBusConnection *connection,
 	return TRUE; /* This function should always succeed */
 }
 
-static void playback_status_update_handler(mpris *inst)
+static void playback_status_update_handler(gmpv_mpris *inst)
 {
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
 	const gchar *state;
-	mpris_prop_val_pair *prop_list;
+	gmpv_mpris_prop *prop_list;
 	GVariant *state_value;
 	GVariant *can_seek_value;
 	gint idle;
 	gint core_idle;
 	gboolean can_seek;
 
-	mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				"idle",
-				MPV_FORMAT_FLAG,
-				&idle );
-
-	mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				"core-idle",
-				MPV_FORMAT_FLAG,
-				&core_idle );
+	gmpv_mpv_obj_get_property(mpv, "idle", MPV_FORMAT_FLAG, &idle);
+	gmpv_mpv_obj_get_property(mpv, "core-idle", MPV_FORMAT_FLAG, &core_idle);
 
 	if(!core_idle && !idle)
 	{
+		GmpvMainWindow *wnd =	gmpv_application_get_main_window
+					(inst->gmpv_ctx);
+
 		state = "Playing";
 		can_seek = TRUE;
 
-		mpv_playback_restart_handler(inst->gmpv_ctx->gui, inst);
+		mpv_playback_restart_handler(wnd, inst);
 	}
 	else if(core_idle && idle)
 	{
@@ -336,7 +419,7 @@ static void playback_status_update_handler(mpris *inst)
 				"CanSeek",
 				g_variant_ref(can_seek_value) );
 
-	prop_list =	(mpris_prop_val_pair[])
+	prop_list =	(gmpv_mpris_prop[])
 			{	{"PlaybackStatus", state_value},
 				{"CanSeek", can_seek_value},
 				{NULL, NULL} };
@@ -344,9 +427,10 @@ static void playback_status_update_handler(mpris *inst)
 	emit_prop_changed(inst, prop_list);
 }
 
-static void playlist_update_handler(mpris *inst)
+static void playlist_update_handler(gmpv_mpris *inst)
 {
-	mpris_prop_val_pair *prop_list;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
+	gmpv_mpris_prop *prop_list;
 	GVariant *can_prev_value;
 	GVariant *can_next_value;
 	gboolean can_prev;
@@ -355,15 +439,14 @@ static void playlist_update_handler(mpris *inst)
 	gint64 playlist_pos;
 	gint rc = 0;
 
-	rc |= mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				"playlist-count",
-				MPV_FORMAT_INT64,
-				&playlist_count );
-
-	rc |= mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				"playlist-pos",
-				MPV_FORMAT_INT64,
-				&playlist_pos );
+	rc |= gmpv_mpv_obj_get_property(	mpv,
+						"playlist-count",
+						MPV_FORMAT_INT64,
+						&playlist_count );
+	rc |= gmpv_mpv_obj_get_property(	mpv,
+						"playlist-pos",
+						MPV_FORMAT_INT64,
+						&playlist_pos );
 
 	can_prev = (rc >= 0 && playlist_pos > 0);
 	can_next = (rc >= 0 && playlist_pos < playlist_count-1);
@@ -378,7 +461,7 @@ static void playlist_update_handler(mpris *inst)
 				"CanGoNext",
 				g_variant_ref(can_next_value) );
 
-	prop_list =	(mpris_prop_val_pair[])
+	prop_list =	(gmpv_mpris_prop[])
 			{	{"CanGoPrevious", can_prev_value},
 				{"CanGoNext", can_next_value},
 				{NULL, NULL} };
@@ -386,16 +469,17 @@ static void playlist_update_handler(mpris *inst)
 	emit_prop_changed(inst, prop_list);
 }
 
-static void speed_update_handler(mpris *inst)
+static void speed_update_handler(gmpv_mpris *inst)
 {
 	gdouble speed;
 	GVariant *value;
-	mpris_prop_val_pair *prop_list;
+	gmpv_mpris_prop *prop_list;
 
-	mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				"speed",
-				MPV_FORMAT_DOUBLE,
-				&speed );
+	gmpv_mpv_obj_get_property
+		(	gmpv_application_get_mpv_obj(inst->gmpv_ctx),
+			"speed",
+			MPV_FORMAT_DOUBLE,
+			&speed );
 
 	value = g_variant_new_double(speed);
 
@@ -403,30 +487,18 @@ static void speed_update_handler(mpris *inst)
 				"Rate",
 				g_variant_ref(value) );
 
-	prop_list =	(mpris_prop_val_pair[])
+	prop_list =	(gmpv_mpris_prop[])
 			{{"Rate", value}, {NULL, NULL}};
 
 	emit_prop_changed(inst, prop_list);
 }
 
-static void metadata_update_handler(mpris *inst)
+static void metadata_update_handler(gmpv_mpris *inst)
 {
-	const struct
-	{
-		const gchar *mpv_name;
-		const gchar *xesam_name;
-		const gboolean is_array;
-	}
-	tag_map[] = {	{"Album", "xesam:album", FALSE},
-			{"Album_Artist", "xesam:albumArtist", TRUE},
-			{"Artist", "xesam:artist", TRUE},
-			{"Comment", "xesam:comment", TRUE},
-			{"Composer", "xesam:composer", FALSE},
-			{"Genre", "xesam:genre", TRUE},
-			{"Title", "xesam:title", FALSE},
-			{NULL, NULL, FALSE} };
-
-	mpris_prop_val_pair *prop_list;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
+	GmpvMainWindow *wnd = gmpv_application_get_main_window(inst->gmpv_ctx);
+	gmpv_mpris_prop *prop_list;
+	mpv_node metadata;
 	GVariantBuilder builder;
 	GVariant *value;
 	gchar *uri;
@@ -435,11 +507,10 @@ static void metadata_update_handler(mpris *inst)
 	gdouble duration;
 	gint64 playlist_pos;
 	gint rc;
-	gint i;
 
 	g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
 
-	uri = mpv_get_property_string(inst->gmpv_ctx->mpv->mpv_ctx, "path");
+	uri = gmpv_mpv_obj_get_property_string(mpv, "path");
 
 	if(uri)
 	{
@@ -451,73 +522,39 @@ static void metadata_update_handler(mpris *inst)
 		mpv_free(uri);
 	}
 
-	rc = mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				"duration",
-				MPV_FORMAT_DOUBLE,
-				&duration );
-
+	rc = gmpv_mpv_obj_get_property(	mpv,
+					"duration",
+					MPV_FORMAT_DOUBLE,
+					&duration );
 	g_variant_builder_add(	&builder,
 				"{sv}",
 				"mpris:length",
 				g_variant_new_int64
 				((gint64)((rc >= 0)*duration*1e6)) );
 
-	rc = mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				"playlist-pos",
-				MPV_FORMAT_INT64,
-				&playlist_pos );
-
+	rc = gmpv_mpv_obj_get_property(	mpv,
+					"playlist-pos",
+					MPV_FORMAT_INT64,
+					&playlist_pos );
 	playlist_pos_str = g_strdup_printf(	"%" G_GINT64_FORMAT,
 						(rc >= 0)*playlist_pos );
 
 	trackid = g_strconcat(	MPRIS_TRACK_ID_PREFIX,
 				playlist_pos_str,
 				NULL );
-
 	g_variant_builder_add(	&builder,
 				"{sv}",
 				"mpris:trackid",
 				g_variant_new_object_path(trackid) );
 
-	for(i = 0; tag_map[i].mpv_name; i++)
-	{
-		GVariantBuilder tag_builder;
-		GVariant *tag_value;
-		gchar *mpv_prop;
-		gchar *value_buf;
-
-		mpv_prop = g_strconcat(	"metadata/by-key/",
-					tag_map[i].mpv_name,
-					NULL );
-
-		value_buf = mpv_get_property_string
-				(inst->gmpv_ctx->mpv->mpv_ctx, mpv_prop);
-
-		if(value_buf)
-		{
-			tag_value = g_variant_new_string(value_buf?:"");
-
-			if(tag_map[i].is_array)
-			{
-				g_variant_builder_init
-					(&tag_builder, G_VARIANT_TYPE("as"));
-
-				g_variant_builder_add_value
-					(&tag_builder, tag_value);
-			}
-
-			g_variant_builder_add
-				(	&builder,
-					"{sv}",
-					tag_map[i].xesam_name,
-					tag_map[i].is_array?
-					g_variant_new("as", &tag_builder):
-					tag_value );
-
-			mpv_free(value_buf);
-		}
+	rc = gmpv_mpv_obj_get_property(	mpv,
+					"metadata",
+					MPV_FORMAT_NODE,
+					&metadata );
 
-		g_free(mpv_prop);
+	if(rc >= 0)
+	{
+		append_metadata_tags(&builder, metadata.u.list);
 	}
 
 	value = g_variant_new("a{sv}", &builder);
@@ -526,26 +563,28 @@ static void metadata_update_handler(mpris *inst)
 				"Metadata",
 				g_variant_ref(value) );
 
-	prop_list =	(mpris_prop_val_pair[])
+	prop_list =	(gmpv_mpris_prop[])
 			{{"Metadata", value}, {NULL, NULL}};
-
 	emit_prop_changed(inst, prop_list);
-	mpv_playback_restart_handler(inst->gmpv_ctx->gui, inst);
 
+	mpv_playback_restart_handler(wnd, inst);
+
+	mpv_free_node_contents(&metadata);
 	g_free(playlist_pos_str);
 	g_free(trackid);
 }
 
-static void volume_update_handler(mpris *inst)
+static void volume_update_handler(gmpv_mpris *inst)
 {
-	mpris_prop_val_pair *prop_list;
+	gmpv_mpris_prop *prop_list;
 	gdouble volume;
 	GVariant *value;
 
-	mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				"volume",
-				MPV_FORMAT_DOUBLE,
-				&volume );
+	gmpv_mpv_obj_get_property
+		(	gmpv_application_get_mpv_obj(inst->gmpv_ctx),
+			"volume",
+			MPV_FORMAT_DOUBLE,
+			&volume );
 
 	value = g_variant_new_double(volume/100.0);
 
@@ -553,55 +592,31 @@ static void volume_update_handler(mpris *inst)
 				"Volume",
 				g_variant_ref(value) );
 
-	prop_list =	(mpris_prop_val_pair[])
+	prop_list =	(gmpv_mpris_prop[])
 			{{"Volume", value}, {NULL, NULL}};
 
 	emit_prop_changed(inst, prop_list);
 }
 
-static void mpv_init_handler(MainWindow *wnd, gpointer data)
+static void mpv_init_handler(GmpvMainWindow *wnd, gpointer data)
 {
-	mpris *inst = data;
-
-	mpv_observe_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				0,
-				"idle",
-				MPV_FORMAT_FLAG );
-
-	mpv_observe_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				0,
-				"core-idle",
-				MPV_FORMAT_FLAG );
-
-	mpv_observe_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				0,
-				"speed",
-				MPV_FORMAT_DOUBLE );
-
-	mpv_observe_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				0,
-				"metadata",
-				MPV_FORMAT_NODE );
-
-	mpv_observe_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				0,
-				"volume",
-				MPV_FORMAT_DOUBLE );
-
-	mpv_observe_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				0,
-				"playlist-pos",
-				MPV_FORMAT_INT64 );
-
-	mpv_observe_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-				0,
-				"playlist-count",
-				MPV_FORMAT_INT64 );
+	gmpv_mpris *inst = data;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
+	mpv_handle *mpv_ctx = gmpv_mpv_obj_get_mpv_handle(mpv);
+
+	mpv_observe_property(mpv_ctx, 0, "idle", MPV_FORMAT_FLAG);
+	mpv_observe_property(mpv_ctx, 0, "core-idle", MPV_FORMAT_FLAG);
+	mpv_observe_property(mpv_ctx, 0, "speed", MPV_FORMAT_DOUBLE);
+	mpv_observe_property(mpv_ctx, 0, "metadata", MPV_FORMAT_NODE);
+	mpv_observe_property(mpv_ctx, 0, "volume", MPV_FORMAT_DOUBLE);
+	mpv_observe_property(mpv_ctx, 0, "playlist-pos", MPV_FORMAT_INT64);
+	mpv_observe_property(mpv_ctx, 0, "playlist-count", MPV_FORMAT_INT64);
 }
 
-static void mpv_playback_restart_handler(MainWindow *wnd, gpointer data)
+static void mpv_playback_restart_handler(GmpvMainWindow *wnd, gpointer data)
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
 	GDBusInterfaceInfo *iface;
 	gdouble position;
 
@@ -610,20 +625,20 @@ static void mpv_playback_restart_handler(MainWindow *wnd, gpointer data)
 		position = inst->pending_seek;
 		inst->pending_seek = -1;
 
-		mpv_set_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-					"time-pos",
-					MPV_FORMAT_DOUBLE,
-					&position );
+		gmpv_mpv_obj_set_property(	mpv,
+						"time-pos",
+						MPV_FORMAT_DOUBLE,
+						&position );
 	}
 	else
 	{
-		mpv_get_property(	inst->gmpv_ctx->mpv->mpv_ctx,
-					"time-pos",
-					MPV_FORMAT_DOUBLE,
-					&position );
+		gmpv_mpv_obj_get_property(	mpv,
+						"time-pos",
+						MPV_FORMAT_DOUBLE,
+						&position );
 	}
 
-	iface = mpris_org_mpris_media_player2_player_interface_info();
+	iface = gmpv_mpris_org_mpris_media_player2_player_interface_info();
 
 	g_dbus_connection_emit_signal
 		(	inst->session_bus_conn,
@@ -635,42 +650,50 @@ static void mpv_playback_restart_handler(MainWindow *wnd, gpointer data)
 			NULL );
 }
 
-static void mpv_prop_change_handler(	MainWindow *wnd,
+static void mpv_prop_change_handler(	GmpvMainWindow *wnd,
 					gchar *name,
 					gpointer data )
 {
-	mpris *inst = data;
+	gmpv_mpris *inst = data;
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
+	GmpvMpvObjState state;
+
+	gmpv_mpv_obj_get_state(mpv, &state);
 
 	if(g_strcmp0(name, "core-idle") == 0
 	|| g_strcmp0(name, "idle") == 0)
 	{
 		playback_status_update_handler(inst);
 	}
-	else if(g_strcmp0(name, "playlist-pos") == 0
-	|| g_strcmp0(name, "playlist-count") == 0)
-	{
-		playlist_update_handler(inst);
-	}
-	else if(g_strcmp0(name, "speed") == 0)
-	{
-		speed_update_handler(inst);
-	}
-	else if(g_strcmp0(name, "metadata") == 0)
-	{
-		metadata_update_handler(inst);
-	}
-	else if(g_strcmp0(name, "volume") == 0)
+	else if(state.loaded)
 	{
-		volume_update_handler(inst);
+		if(g_strcmp0(name, "playlist-pos") == 0
+		|| g_strcmp0(name, "playlist-count") == 0)
+		{
+			playlist_update_handler(inst);
+		}
+		else if(g_strcmp0(name, "speed") == 0)
+		{
+			speed_update_handler(inst);
+		}
+		else if(g_strcmp0(name, "metadata") == 0)
+		{
+			metadata_update_handler(inst);
+		}
+		else if(g_strcmp0(name, "volume") == 0)
+		{
+			volume_update_handler(inst);
+		}
 	}
 }
 
-void mpris_player_register(mpris *inst)
+void gmpv_mpris_player_register(gmpv_mpris *inst)
 {
+	GmpvMpvObj *mpv = gmpv_application_get_mpv_obj(inst->gmpv_ctx);
 	GDBusInterfaceInfo *iface;
 	GDBusInterfaceVTable vtable;
 
-	iface = mpris_org_mpris_media_player2_player_interface_info();
+	iface = gmpv_mpris_org_mpris_media_player2_player_interface_info();
 
 	inst->player_prop_table = g_hash_table_new_full
 					(	g_str_hash,
@@ -680,28 +703,24 @@ void mpris_player_register(mpris *inst)
 						g_variant_unref );
 
 	inst->player_sig_id_list = g_malloc(4*sizeof(gulong));
-
 	inst->player_sig_id_list[0]
-		= g_signal_connect(	inst->gmpv_ctx->mpv,
+		= g_signal_connect(	mpv,
 					"mpv-init",
 					G_CALLBACK(mpv_init_handler),
 					inst );
-
 	inst->player_sig_id_list[1]
-		= g_signal_connect(	inst->gmpv_ctx->mpv,
+		= g_signal_connect(	mpv,
 					"mpv-playback-restart",
 					G_CALLBACK(mpv_playback_restart_handler),
 					inst );
-
 	inst->player_sig_id_list[2]
-		= g_signal_connect(	inst->gmpv_ctx->mpv,
+		= g_signal_connect(	mpv,
 					"mpv-prop-change",
 					G_CALLBACK(mpv_prop_change_handler),
 					inst );
-
 	inst->player_sig_id_list[3] = 0;
 
-	mpv_init_handler(inst->gmpv_ctx->gui, inst);
+	mpv_init_handler(gmpv_application_get_main_window(inst->gmpv_ctx), inst);
 	prop_table_init(inst);
 
 	vtable.method_call = (GDBusInterfaceMethodCallFunc)method_handler;
@@ -718,16 +737,18 @@ void mpris_player_register(mpris *inst)
 					NULL );
 }
 
-void mpris_player_unregister(mpris *inst)
+void gmpv_mpris_player_unregister(gmpv_mpris *inst)
 {
 	gulong *current_sig_id = inst->player_sig_id_list;
 
 	if(current_sig_id)
 	{
+		GmpvMainWindow *wnd =	gmpv_application_get_main_window
+					(inst->gmpv_ctx);
+
 		while(current_sig_id && *current_sig_id > 0)
 		{
-			g_signal_handler_disconnect(	inst->gmpv_ctx->gui,
-							*current_sig_id );
+			g_signal_handler_disconnect(wnd, *current_sig_id);
 
 			current_sig_id++;
 		}
diff --git a/src/mpris/mpris_player.h b/src/mpris/gmpv_mpris_player.h
similarity index 81%
rename from src/mpris/mpris_player.h
rename to src/mpris/gmpv_mpris_player.h
index f591afa..79fd941 100644
--- a/src/mpris/mpris_player.h
+++ b/src/mpris/gmpv_mpris_player.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 gnome-mpv
+ * Copyright (c) 2015-2016 gnome-mpv
  *
  * This file is part of GNOME MPV.
  *
@@ -20,9 +20,9 @@
 #ifndef MPRIS_PLAYER_H
 #define MPRIS_PLAYER_H
 
-#include "mpris.h"
+#include "gmpv_mpris.h"
 
-void mpris_player_register(mpris *inst);
-void mpris_player_unregister(mpris *inst);
+void gmpv_mpris_player_register(gmpv_mpris *inst);
+void gmpv_mpris_player_unregister(gmpv_mpris *inst);
 
 #endif
diff --git a/src/mpv_obj.h b/src/mpv_obj.h
deleted file mode 100644
index 92b23cf..0000000
--- a/src/mpv_obj.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2014, 2016 gnome-mpv
- *
- * This file is part of GNOME MPV.
- *
- * GNOME MPV 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 3 of the License, or
- * (at your option) any later version.
- *
- * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MPV_OBJ_H
-#define MPV_OBJ_H
-
-#include <gtk/gtk.h>
-#include <mpv/client.h>
-#include <mpv/opengl_cb.h>
-
-#include "playlist.h"
-
-G_BEGIN_DECLS
-
-#define MPV_OBJ_TYPE (mpv_obj_get_type())
-
-#define	MPV_OBJ(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST((obj), MPV_OBJ_TYPE, MpvObj))
-
-#define	MPV_OBJ_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST((klass), MPV_OBJ_TYPE, MpvObjClass))
-
-#define	IS_MPV_OBJ(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), MPV_OBJ_TYPE))
-
-#define	IS_MPV_OBJ_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), MPV_OBJ_TYPE))
-
-typedef struct _MpvObjState MpvObjState;
-typedef struct _MpvObj MpvObj;
-typedef struct _MpvObjPrivate MpvObjPrivate;
-typedef struct _MpvObjClass MpvObjClass;
-
-struct _MpvObjState
-{
-	gboolean ready;
-	gboolean paused;
-	gboolean loaded;
-	gboolean new_file;
-	gboolean init_load;
-};
-
-struct _MpvObj
-{
-	GObject parent;
-	MpvObjPrivate *priv;
-	mpv_handle *mpv_ctx;
-	mpv_opengl_cb_context *opengl_ctx;
-	Playlist *playlist;
-	gchar *tmp_input_file;
-	GSList *log_level_list;
-	gdouble autofit_ratio;
-	void (*mpv_event_handler)(mpv_event *event, gpointer data);
-};
-
-struct _MpvObjClass
-{
-	GObjectClass parent_class;
-};
-
-GType mpv_obj_get_type(void);
-MpvObj *mpv_obj_new(	Playlist *playlist,
-			gboolean use_opengl,
-			gint64 wid,
-			GtkGLArea *glarea );
-gint mpv_obj_command(MpvObj *mpv, const gchar **cmd);
-gint mpv_obj_command_string(MpvObj *mpv, const gchar *cmd);
-gint mpv_obj_get_property(	MpvObj *mpv,
-				const gchar *name,
-				mpv_format format,
-				void *data );
-gchar *mpv_obj_get_property_string(MpvObj *mpv, const gchar *name);
-gboolean mpv_obj_get_property_flag(MpvObj *mpv, const gchar *name);
-gint mpv_obj_set_property(	MpvObj *mpv,
-				const gchar *name,
-				mpv_format format,
-				void *data );
-gint mpv_obj_set_property_flag(	MpvObj *mpv, const gchar *name, gboolean value);
-gint mpv_obj_set_property_string(	MpvObj *mpv,
-					const gchar *name,
-					const char *data );
-void mpv_obj_set_wakup_callback(	MpvObj *mpv,
-					void (*func)(void *),
-					void *data );
-void mpv_obj_set_opengl_cb_callback(	MpvObj *mpv,
-					mpv_opengl_cb_update_fn func,
-					void *data );
-void mpv_obj_wakeup_callback(void *data);
-void mpv_check_error(int status);
-gboolean mpv_obj_is_loaded(MpvObj *mpv);
-void mpv_obj_get_state(MpvObj *mpv, MpvObjState *state);
-void mpv_obj_initialize(MpvObj *mpv);
-void mpv_obj_reset(MpvObj *mpv);
-void mpv_obj_quit(MpvObj *mpv);
-void mpv_obj_load(	MpvObj *mpv,
-			const gchar *uri,
-			gboolean append,
-			gboolean update );
-void mpv_obj_load_list(	MpvObj *mpv,
-			const gchar **uri_list,
-			gboolean append,
-			gboolean update );
-
-G_END_DECLS
-
-#endif
diff --git a/src/open_loc_dialog.h b/src/open_loc_dialog.h
deleted file mode 100644
index a4acfba..0000000
--- a/src/open_loc_dialog.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2014 gnome-mpv
- *
- * This file is part of GNOME MPV.
- *
- * GNOME MPV 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 3 of the License, or
- * (at your option) any later version.
- *
- * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef OPEN_LOC_DIALOG_H
-#define OPEN_LOC_DIALOG_H
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define OPEN_LOC_DIALOG_TYPE (open_loc_dialog_get_type ())
-
-#define	OPEN_LOC_DIALOG(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST((obj), OPEN_LOC_DIALOG_TYPE, OpenLocDialog))
-
-#define	OPEN_LOC_DIALOG_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST \
-		((klass), OPEN_LOC_DIALOG_TYPE, OpenLocDialogClass))
-
-#define	IS_OPEN_LOC_DIALOG(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), OPEN_LOC_DIALOG_TYPE))
-
-#define	IS_OPEN_LOC_DIALOG_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), OPEN_LOC_DIALOG_TYPE))
-
-typedef struct _OpenLocDialog OpenLocDialog;
-typedef struct _OpenLocDialogClass OpenLocDialogClass;
-
-GtkWidget *open_loc_dialog_new(GtkWindow *parent);
-GType open_loc_dialog_get_type(void);
-const gchar *open_loc_dialog_get_string(OpenLocDialog *dlg);
-guint64 open_loc_dialog_get_string_length(OpenLocDialog *dlg);
-
-G_END_DECLS
-
-#endif
diff --git a/src/playlist_widget.c b/src/playlist_widget.c
deleted file mode 100644
index b7b2212..0000000
--- a/src/playlist_widget.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2014-2016 gnome-mpv
- *
- * This file is part of GNOME MPV.
- *
- * GNOME MPV 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 3 of the License, or
- * (at your option) any later version.
- *
- * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <glib/gi18n.h>
-
-#include "playlist_widget.h"
-#include "playlist.h"
-#include "def.h"
-
-enum
-{
-	PROP_0,
-	PROP_STORE,
-	N_PROPERTIES
-};
-
-static gboolean mouse_press_handler(	GtkWidget *widget,
-					GdkEvent *event,
-					gpointer data );
-
-G_DEFINE_TYPE(PlaylistWidget, playlist_widget, GTK_TYPE_SCROLLED_WINDOW)
-
-static void playlist_widget_constructed(GObject *object)
-{
-	PlaylistWidget *self = PLAYLIST_WIDGET(object);
-
-	self->tree_view
-		= gtk_tree_view_new_with_model
-			(GTK_TREE_MODEL(playlist_get_store(self->store)));
-
-	g_signal_connect(	self->tree_view,
-				"button-press-event",
-				G_CALLBACK(mouse_press_handler),
-				NULL );
-
-	gtk_widget_set_can_focus(GTK_WIDGET(self->tree_view), FALSE);
-	gtk_tree_view_set_reorderable(GTK_TREE_VIEW(self->tree_view), TRUE);
-
-	gtk_tree_view_append_column
-		(GTK_TREE_VIEW(self->tree_view), self->title_column);
-
-	gtk_container_add(GTK_CONTAINER(self), self->tree_view);
-
-	G_OBJECT_CLASS(playlist_widget_parent_class)->constructed(object);
-}
-
-static void playlist_widget_set_property(	GObject *object,
-						guint property_id,
-						const GValue *value,
-						GParamSpec *pspec )
-{
-	PlaylistWidget *self = PLAYLIST_WIDGET(object);
-
-	if(property_id == PROP_STORE)
-	{
-		self->store = g_value_get_pointer(value);
-
-	}
-	else
-	{
-		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
-	}
-}
-
-static void playlist_widget_get_property(	GObject *object,
-						guint property_id,
-						GValue *value,
-						GParamSpec *pspec )
-{
-	PlaylistWidget *self = PLAYLIST_WIDGET(object);
-
-	if(property_id == PROP_STORE)
-	{
-		g_value_set_pointer(value, self->store);
-	}
-	else
-	{
-		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
-	}
-}
-
-static gboolean mouse_press_handler(	GtkWidget *widget,
-					GdkEvent *event,
-					gpointer data )
-{
-	GdkEventButton *btn_event = (GdkEventButton *)event;
-	gboolean handled;
-
-	handled = (	btn_event->type == GDK_BUTTON_PRESS &&
-			btn_event->button == 3 );
-
-	if(handled)
-	{
-		GMenu *menu;
-		GMenuItem *add_menu_item;
-		GMenuItem *loop_menu_item;
-		GtkWidget *ctx_menu;
-
-		menu = g_menu_new();
-		add_menu_item = g_menu_item_new(_("_Add…"), "app.open(true)");
-		loop_menu_item = g_menu_item_new(_("Loop"), "app.loop");
-
-		g_menu_append_item(menu, add_menu_item);
-		g_menu_append_item(menu, loop_menu_item);
-		g_menu_freeze(menu);
-
-		ctx_menu = gtk_menu_new_from_model(G_MENU_MODEL(menu));
-
-		gtk_menu_attach_to_widget(GTK_MENU(ctx_menu), widget, NULL);
-		gtk_widget_show_all(ctx_menu);
-
-		gtk_menu_popup(	GTK_MENU(ctx_menu), NULL, NULL, NULL, NULL,
-				btn_event->button, btn_event->time );
-	}
-
-	return handled;
-}
-
-static void playlist_widget_class_init(PlaylistWidgetClass *klass)
-{
-	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-	GParamSpec *pspec = NULL;
-
-	obj_class->constructed = playlist_widget_constructed;
-	obj_class->set_property = playlist_widget_set_property;
-	obj_class->get_property = playlist_widget_get_property;
-
-	pspec = g_param_spec_pointer
-		(	"store",
-			"Store",
-			"Playlist object used to store playlist items",
-			G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
-
-	g_object_class_install_property(obj_class, PROP_STORE, pspec);
-}
-
-static void playlist_widget_init(PlaylistWidget *wgt)
-{
-	GtkTargetEntry targets[] = DND_TARGETS;
-
-	wgt->title_renderer = gtk_cell_renderer_text_new();
-	wgt->title_column
-		= gtk_tree_view_column_new_with_attributes
-			(	_("Playlist"),
-				wgt->title_renderer,
-				"text", PLAYLIST_NAME_COLUMN,
-				"weight", PLAYLIST_WEIGHT_COLUMN,
-				NULL );
-
-	gtk_drag_dest_set(	GTK_WIDGET(wgt),
-				GTK_DEST_DEFAULT_ALL,
-				targets,
-				G_N_ELEMENTS(targets),
-				GDK_ACTION_COPY );
-	gtk_drag_dest_add_uri_targets(GTK_WIDGET(wgt));
-
-	gtk_widget_set_size_request
-		(GTK_WIDGET(wgt), PLAYLIST_MIN_WIDTH, -1);
-	gtk_tree_view_column_set_sizing
-		(wgt->title_column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-}
-
-GtkWidget *playlist_widget_new(Playlist *store)
-{
-	return GTK_WIDGET(g_object_new(	playlist_widget_get_type(),
-					"store", store,
-					NULL ));
-}
-
-void playlist_widget_remove_selected(PlaylistWidget *wgt)
-{
-	GtkTreePath *path;
-
-	gtk_tree_view_get_cursor
-		(	GTK_TREE_VIEW(wgt->tree_view),
-			&path,
-			NULL );
-
-	if(path)
-	{
-		gint index;
-		gchar *index_str;
-
-		index = gtk_tree_path_get_indices(path)[0];
-		index_str = g_strdup_printf("%d", index);
-
-		playlist_remove(wgt->store, index);
-
-		g_free(index_str);
-	}
-}
-
diff --git a/src/playlist_widget.h b/src/playlist_widget.h
deleted file mode 100644
index ee93658..0000000
--- a/src/playlist_widget.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2014-2016 gnome-mpv
- *
- * This file is part of GNOME MPV.
- *
- * GNOME MPV 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 3 of the License, or
- * (at your option) any later version.
- *
- * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PLAYLIST_WIDGET_H
-#define PLAYLIST_WIDGET_H
-
-#include <gtk/gtk.h>
-
-#include "playlist.h"
-
-G_BEGIN_DECLS
-
-#define PLAYLIST_WIDGET_TYPE (playlist_widget_get_type ())
-
-#define	PLAYLIST_WIDGET(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST \
-		((obj), PLAYLIST_WIDGET_TYPE, PlaylistWidget))
-
-#define	PLAYLIST_WIDGET_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST \
-		((klass), PLAYLIST_WIDGET_TYPE, PlaylistWidgetClass))
-
-#define	IS_PLAYLIST_WIDGET(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), PLAYLIST_WIDGET_TYPE))
-
-#define	IS_PLAYLIST_WIDGET_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), PLAYLIST_WIDGET_TYPE))
-
-struct _PlaylistWidget
-{
-	GtkScrolledWindow parent_instance;
-	GtkWidget *tree_view;
-	Playlist *store;
-	GtkTreeViewColumn *title_column;
-	GtkCellRenderer *title_renderer;
-};
-
-struct _PlaylistWidgetClass
-{
-	GtkScrolledWindowClass parent_class;
-};
-
-typedef struct _PlaylistWidget PlaylistWidget;
-typedef struct _PlaylistWidgetClass PlaylistWidgetClass;
-
-GtkWidget *playlist_widget_new(Playlist *store);
-GType playlist_widget_get_type(void);
-void playlist_widget_remove_selected(PlaylistWidget *wgt);
-
-G_END_DECLS
-
-#endif
diff --git a/src/plugins_manager.h b/src/plugins_manager.h
deleted file mode 100644
index ac10adb..0000000
--- a/src/plugins_manager.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2016 gnome-mpv
- *
- * This file is part of GNOME MPV.
- *
- * GNOME MPV 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 3 of the License, or
- * (at your option) any later version.
- *
- * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PLUGINS_MANAGER_H
-#define PLUGINS_MANAGER_H
-
-#include <gtk/gtk.h>
-
-#define PLUGINS_MANAGER_TYPE (plugins_manager_get_type ())
-
-#define	PLUGINS_MANAGER(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST((obj), PLUGINS_MANAGER_TYPE, PluginsManager))
-
-#define	PLUGINS_MANAGER_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST((klass), PLUGINS_MANAGER_TYPE, PluginsManagerClass))
-
-#define	IS_PLUGINS_MANAGER(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), PLUGINS_MANAGER_TYPE))
-
-#define	IS_PLUGINS_MANAGER_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), PLUGINS_MANAGER_TYPE))
-
-typedef struct _PluginsManager PluginsManager;
-typedef struct _PluginsManagerClass PluginsManagerClass;
-
-GType plugins_manager_get_type(void);
-GtkWidget *plugins_manager_new(GtkWindow *parent);
-void plugins_manager_set_directory(PluginsManager *pmgr, const gchar *path);
-
-#endif
diff --git a/src/plugins_manager_item.h b/src/plugins_manager_item.h
deleted file mode 100644
index 426af2b..0000000
--- a/src/plugins_manager_item.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2016 gnome-mpv
- *
- * This file is part of GNOME MPV.
- *
- * GNOME MPV 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 3 of the License, or
- * (at your option) any later version.
- *
- * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PLUGINS_MANAGER_ITEM_H
-#define PLUGINS_MANAGER_ITEM_H
-
-#include <gtk/gtk.h>
-
-#define PLUGINS_MANAGER_ITEM_TYPE (plugins_manager_item_get_type ())
-
-#define	PLUGINS_MANAGER_ITEM(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST((obj), PLUGINS_MANAGER_ITEM_TYPE, PluginsManagerItem))
-
-#define	PLUGINS_MANAGER_ITEM_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST((klass), PLUGINS_MANAGER_ITEM_TYPE, PluginsManagerItemClass))
-
-#define	IS_PLUGINS_MANAGER_ITEM(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), PLUGINS_MANAGER_ITEM_TYPE))
-
-#define	IS_PLUGINS_MANAGER_ITEM_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), PLUGINS_MANAGER_ITEM_TYPE))
-
-typedef struct _PluginsManagerItem PluginsManagerItem;
-typedef struct _PluginsManagerItemClass PluginsManagerItemClass;
-
-GType plugins_manager_item_get_type(void);
-GtkWidget *plugins_manager_item_new(	GtkWindow *parent,
-					const gchar *title,
-					const gchar *path );
-
-#endif
diff --git a/src/shortcuts_window.h b/src/shortcuts_window.h
deleted file mode 100644
index 47c4e6b..0000000
--- a/src/shortcuts_window.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2016 gnome-mpv
- *
- * This file is part of GNOME MPV.
- *
- * GNOME MPV 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 3 of the License, or
- * (at your option) any later version.
- *
- * GNOME MPV 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 GNOME MPV.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef SHORTCUTS_WINDOW_H
-#define SHORTCUTS_WINDOW_H
-
-#include <gtk/gtk.h>
-
-#define SHORTCUTS_WINDOW_TYPE (shortcuts_window_get_type ())
-
-#define	SHORTCUTS_WINDOW(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST((obj), SHORTCUTS_WINDOW_TYPE, ShortcutsWindow))
-
-#define	SHORTCUTS_WINDOW_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST((klass), SHORTCUTS_WINDOW_TYPE, ShortcutsWindowClass))
-
-#define	IS_SHORTCUTS_WINDOW(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), SHORTCUTS_WINDOW_TYPE))
-
-#define	IS_SHORTCUTS_WINDOW_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), SHORTCUTS_WINDOW_TYPE))
-
-typedef struct ShortcutsWindow ShortcutsWindow;
-typedef struct ShortcutsWindowClass ShortcutsWindowClass;
-
-GtkWidget *shortcuts_window_new(GtkWindow *parent);
-GType shortcuts_window_get_type(void);
-
-#endif

-- 
gnome-mpv packaging



More information about the pkg-multimedia-commits mailing list