diff --git a/applications/gui/src/camera.cpp b/applications/gui/src/camera.cpp
index b8a22a2a036e9fb89af7a0457a0676b75aa2a7cb..6766c666b9302f17e0e7821aa7e3cefb34310742 100644
--- a/applications/gui/src/camera.cpp
+++ b/applications/gui/src/camera.cpp
@@ -516,6 +516,7 @@ void ftl::gui::Camera::toggleVideoRecording() {
 		src_->removeRawCallback(recorder_);
 		writer_->end();
 		fileout_->close();
+		recording_ = false;
 	} else {
 		char timestamp[18];
 		std::time_t t=std::time(NULL);
@@ -527,6 +528,7 @@ void ftl::gui::Camera::toggleVideoRecording() {
 
 		src_->inject(Channel::Calibration, src_->parameters(), Channel::Left, src_->getCapabilities());
 		src_->inject(src_->getPose());
+		recording_ = true;
 	}
 }
 
diff --git a/applications/gui/src/camera.hpp b/applications/gui/src/camera.hpp
index 89cfba056a97ceb4a5b200ba77a5d585573a6ea6..43cf9c783b1e4b5e3ae003c428b8d6126273ef40 100644
--- a/applications/gui/src/camera.hpp
+++ b/applications/gui/src/camera.hpp
@@ -44,7 +44,7 @@ class Camera {
 	
 	void togglePause();
 	void isPaused();
-	const ftl::codecs::Channels &availableChannels();
+	const ftl::codecs::Channels &availableChannels() { return channels_; }
 
 	const GLTexture &captureFrame();
 	const GLTexture &getLeft() const { return texture1_; }
diff --git a/applications/gui/src/config_window.cpp b/applications/gui/src/config_window.cpp
index 6112fe82292cd4470b626e9a5242038049600366..4832454ad3020f4337def5809bd2f05e2ed83d7e 100644
--- a/applications/gui/src/config_window.cpp
+++ b/applications/gui/src/config_window.cpp
@@ -2,7 +2,6 @@
 
 #include <nanogui/layout.h>
 #include <nanogui/label.h>
-#include <nanogui/combobox.h>
 #include <nanogui/button.h>
 #include <nanogui/entypo.h>
 #include <nanogui/formhelper.h>
diff --git a/applications/gui/src/media_panel.cpp b/applications/gui/src/media_panel.cpp
index 9a6eb7259e75d7056d1961bbbe245ec3c8337979..cbc61a3e43f3873baa4578f35e364fa1b29b5ea7 100644
--- a/applications/gui/src/media_panel.cpp
+++ b/applications/gui/src/media_panel.cpp
@@ -42,47 +42,47 @@ MediaPanel::MediaPanel(ftl::gui::Screen *screen) : nanogui::Window(screen, ""),
 	recordpopup->setLayout(new GroupLayout());
 	recordpopup->setTheme(screen->toolbuttheme);
 	recordpopup->setAnchorHeight(150);
-	auto itembutton = new Button(recordpopup, "Snapshot");
-	itembutton->setCallback([this](){
+	auto itembutton = new Button(recordpopup, "2D snapshot (.png)");
+	itembutton->setCallback([this,recordbutton]() {
 		screen_->activeCamera()->snapshot();
+		recordbutton->setPushed(false);
 	});
-	itembutton = new Button(recordpopup, "2D video recording");
-	itembutton->setFlags(Button::ToggleButton);
-	itembutton->setChangeCallback([this,recordbutton](bool state) {
+	itembutton = new Button(recordpopup, "Virtual camera recording (.ftl)");
+	itembutton->setCallback([this,recordbutton]() {
+		std::cout << "Toggling video recording in itembutton callback." << '\n';
 		screen_->activeCamera()->toggleVideoRecording();
-		if (state) {
-			recordbutton->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
-		} else {
+		recordbutton->setCallback([this,recordbutton]() {
+			std::cout << "Toggling video recording in recordbutton callback." << '\n';
+			screen_->activeCamera()->toggleVideoRecording();
+			recordbutton->setCallback([]() {});
 			recordbutton->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f));
-		}
+
+			// Prevents the popup from being opened, though it is shown while the button
+			// is being pressed.
+			recordbutton->setPushed(false);
+		});
+		recordbutton->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
+		recordbutton->setPushed(false);
 	});
-	itembutton = new Button(recordpopup, "Depth video recording");
-	itembutton->setFlags(Button::ToggleButton);
-	itembutton->setChangeCallback([this,recordbutton](bool state) {
+	itembutton = new Button(recordpopup, "3D scene recording (.ftl)");
+	itembutton->setCallback([this,recordbutton]() {
 		auto tag = screen_->activeCamera()->source()->get<std::string>("uri");
 		if (tag) {
 			auto tagvalue = tag.value();
 			auto configurables = ftl::config::findByTag(tagvalue);
 			if (configurables.size() > 0) {
 				ftl::Configurable *configurable = configurables[0];
-				if (state){
-					configurable->set("record", true);
-					recordbutton->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
-				} else {
-					recordbutton->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f));
+				configurable->set("record", true);
+				recordbutton->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
+				recordbutton->setCallback([this,recordbutton,configurable]() {
 					configurable->set("record", false);
-				}
+					recordbutton->setCallback([]() {});
+					recordbutton->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f));
+					recordbutton->setPushed(false);
+				});
 			}
 		}
-	});
-	itembutton = new Button(recordpopup, "3D scene recording");
-	itembutton->setFlags(Button::ToggleButton);
-	itembutton->setChangeCallback([this,recordbutton](bool state) {
-		if (state) {
-			std::cout << "Starting 3D scene recording." << '\n';
-		} else {
-			std::cout << "Finishing 3D scene recording." << '\n';
-		}
+		recordbutton->setPushed(false);
 	});
 	itembutton = new Button(recordpopup, "Detailed recording options");
 
diff --git a/applications/gui/src/screen.cpp b/applications/gui/src/screen.cpp
index eb3650f3f460437cc5d33120e1b7f00dbfced3cf..5e40949f28c2a5e78589313574a9b1ebe7dd2410 100644
--- a/applications/gui/src/screen.cpp
+++ b/applications/gui/src/screen.cpp
@@ -6,7 +6,6 @@
 #include <nanogui/window.h>
 #include <nanogui/layout.h>
 #include <nanogui/imageview.h>
-#include <nanogui/combobox.h>
 #include <nanogui/label.h>
 #include <nanogui/toolbutton.h>
 #include <nanogui/popupbutton.h>
diff --git a/applications/gui/src/src_window.cpp b/applications/gui/src/src_window.cpp
index b5eb141f72278ed986aac47b6bb3bd2feb7a7345..0126810a511b85a1168fe06c638651e533f11a0d 100644
--- a/applications/gui/src/src_window.cpp
+++ b/applications/gui/src/src_window.cpp
@@ -74,6 +74,14 @@ SourceWindow::SourceWindow(ftl::gui::Screen *screen)
 	_updateCameras(screen_->control()->getNet()->findAll<string>("list_streams"));
 }
 
+std::vector<ftl::gui::Camera*> SourceWindow::getCameras() {
+	auto cameras = std::vector<ftl::gui::Camera*>(cameras_.size());
+	for (const auto &kv : cameras_) {
+		cameras.push_back(kv.second);
+	}
+	return cameras;
+}
+
 void SourceWindow::_updateCameras(const vector<string> &netcams) {
 	for (auto s : netcams) {
 		if (cameras_.find(s) == cameras_.end()) {
diff --git a/applications/gui/src/src_window.hpp b/applications/gui/src/src_window.hpp
index b2fe8a9e0957f3345a719a0c37bac46bf473089c..dab3f5d4301de73d0dda2bbd32b321c3f796d160 100644
--- a/applications/gui/src/src_window.hpp
+++ b/applications/gui/src/src_window.hpp
@@ -25,7 +25,7 @@ class SourceWindow : public nanogui::Window {
 	explicit SourceWindow(ftl::gui::Screen *screen);
 	~SourceWindow();
 
-	const std::vector<ftl::gui::Camera*> &getCameras();
+	std::vector<ftl::gui::Camera*> getCameras();
 
 	virtual void draw(NVGcontext *ctx);