diff --git a/.gitignore b/.gitignore
index fc62187..b89059a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,3 +54,7 @@ dkms.conf
 # build folder
 build/
 build-*/
+
+.vscode/
+
+hyprland-share-picker/build/
\ No newline at end of file
diff --git a/README.md b/README.md
index 28abebb..3f50b6b 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,7 @@ Although `-wlr` **does** work with Hyprland, `-hyprland` offers more features.
 ```sh
 meson build
 ninja -C build
+cd hyprland-share-picker && make all && cd ..
 ```
 
 ## Installing
@@ -21,6 +22,7 @@ ninja -C build
 
 ```sh
 ninja -C build install
+sudo cp ./hyprland-share-picker/build/hyprland-share-picker /usr/bin
 ```
 
 ## License
diff --git a/contrib/systemd/xdg-desktop-portal-hyprland.service.in b/contrib/systemd/xdg-desktop-portal-hyprland.service.in
new file mode 100644
index 0000000..ecaec96
--- /dev/null
+++ b/contrib/systemd/xdg-desktop-portal-hyprland.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=Portal service (Hyprland implementation)
+PartOf=graphical-session.target
+After=graphical-session.target
+ConditionEnvironment=WAYLAND_DISPLAY
+
+[Service]
+Type=dbus
+BusName=org.freedesktop.impl.portal.desktop.hyprland
+ExecStart=@libexecdir@/xdg-desktop-portal-hyprland
+Restart=on-failure
diff --git a/contrib/systemd/xdg-desktop-portal-wlr.service.in b/contrib/systemd/xdg-desktop-portal-wlr.service.in
deleted file mode 100644
index 29a03f4..0000000
--- a/contrib/systemd/xdg-desktop-portal-wlr.service.in
+++ /dev/null
@@ -1,11 +0,0 @@
-[Unit]
-Description=Portal service (wlroots implementation)
-PartOf=graphical-session.target
-After=graphical-session.target
-ConditionEnvironment=WAYLAND_DISPLAY
-
-[Service]
-Type=dbus
-BusName=org.freedesktop.impl.portal.desktop.wlr
-ExecStart=@libexecdir@/xdg-desktop-portal-wlr
-Restart=on-failure
diff --git a/hyprland-share-picker/CMakeLists.txt b/hyprland-share-picker/CMakeLists.txt
new file mode 100644
index 0000000..8f5a4d8
--- /dev/null
+++ b/hyprland-share-picker/CMakeLists.txt
@@ -0,0 +1,61 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(hyprland-share-picker VERSION 0.1 LANGUAGES CXX)
+
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
+find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
+
+set(PROJECT_SOURCES
+        main.cpp
+        mainpicker.cpp
+        mainpicker.h
+        mainpicker.ui
+)
+
+if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
+    qt_add_executable(hyprland-share-picker
+        MANUAL_FINALIZATION
+        ${PROJECT_SOURCES}
+    )
+# Define target properties for Android with Qt 6 as:
+#    set_property(TARGET hyprland-share-picker APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
+#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
+# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
+else()
+    if(ANDROID)
+        add_library(hyprland-share-picker SHARED
+            ${PROJECT_SOURCES}
+        )
+# Define properties for Android with Qt 5 after find_package() calls as:
+#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
+    else()
+        add_executable(hyprland-share-picker
+            ${PROJECT_SOURCES}
+        )
+    endif()
+endif()
+
+target_link_libraries(hyprland-share-picker PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
+
+set_target_properties(hyprland-share-picker PROPERTIES
+    MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
+    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
+    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
+    MACOSX_BUNDLE TRUE
+    WIN32_EXECUTABLE TRUE
+)
+
+install(TARGETS hyprland-share-picker
+    BUNDLE DESTINATION .
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+if(QT_VERSION_MAJOR EQUAL 6)
+    qt_finalize_executable(hyprland-share-picker)
+endif()
diff --git a/hyprland-share-picker/Makefile b/hyprland-share-picker/Makefile
new file mode 100644
index 0000000..5dc3661
--- /dev/null
+++ b/hyprland-share-picker/Makefile
@@ -0,0 +1,4 @@
+
+all:
+	mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -H./ -B./build -G Ninja
+	cmake --build ./build --config Release --target all -j$(shell nproc)
\ No newline at end of file
diff --git a/hyprland-share-picker/main.cpp b/hyprland-share-picker/main.cpp
new file mode 100644
index 0000000..6225170
--- /dev/null
+++ b/hyprland-share-picker/main.cpp
@@ -0,0 +1,176 @@
+#include "mainpicker.h"
+
+#include <QApplication>
+#include <QScreen>
+#include <QWidget>
+#include <QTabWidget>
+#include <QPushButton>
+#include <QtWidgets>
+#include <QtDebug>
+#include <QObject>
+#include <QEvent>
+#include <string>
+#include <iostream>
+#include <cstdio>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <array>
+
+std::string execAndGet(const char* cmd) {
+    std::array<char, 128> buffer;
+    std::string result;
+    std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
+    if (!pipe) {
+        throw std::runtime_error("popen() failed!");
+    }
+    while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
+        result += buffer.data();
+    }
+    return result;
+}
+
+QApplication* pickerPtr = nullptr;
+
+int main(int argc, char *argv[]) {
+    qputenv("QT_LOGGING_RULES", "qml=false");
+    QApplication picker(argc, argv);
+    pickerPtr = &picker;
+    MainPicker w;
+
+    // get the tabwidget
+    const auto TABWIDGET = (QTabWidget*)w.children()[1]->children()[0];
+
+    const auto TAB1 = (QWidget*)TABWIDGET->children()[0];
+
+    const auto SCREENS_SCROLL_AREA_CONTENTS = (QWidget*)TAB1->findChild<QWidget*>("screens")->findChild<QScrollArea*>("scrollArea")->findChild<QWidget*>("scrollAreaWidgetContents");
+
+    // add all screens
+    const auto SCREENS = picker.screens();
+
+    constexpr int BUTTON_WIDTH  = 441;
+    constexpr int BUTTON_HEIGHT = 41;
+    constexpr int BUTTON_PAD    = 4;
+
+    for (int i = 0; i < SCREENS.size(); ++i) {
+        const auto GEOMETRY = SCREENS[i]->geometry();
+
+        QString text = QString::fromStdString(std::string("Screen " + std::to_string(i) + " at " + std::to_string(GEOMETRY.x()) + ", "
+                            + std::to_string(GEOMETRY.y()) + " (" + std::to_string(GEOMETRY.width()) + "x"
+                            + std::to_string(GEOMETRY.height()) + ") (") + SCREENS[i]->name().toStdString() + ")");
+        QPushButton* button = new QPushButton(text, (QWidget*)SCREENS_SCROLL_AREA_CONTENTS);
+        button->move(9, 5 + (BUTTON_HEIGHT + BUTTON_PAD) * i);
+        button->resize(BUTTON_WIDTH, BUTTON_HEIGHT);
+        QObject::connect(button, &QPushButton::clicked, [=] () {
+            std::string ID = button->text().toStdString();
+            ID = ID.substr(ID.find_last_of('(') + 1);
+            ID = ID.substr(0, ID.find_last_of(')'));
+
+            std::cout << "screen:" << ID << "\n";
+            pickerPtr->quit();
+        });
+    }
+
+    SCREENS_SCROLL_AREA_CONTENTS->resize(SCREENS_SCROLL_AREA_CONTENTS->size().width(), 5 + (BUTTON_HEIGHT + BUTTON_PAD) * SCREENS.size());
+
+    // windows
+    const auto WINDOWS_SCROLL_AREA_CONTENTS = (QWidget*)TAB1->findChild<QWidget*>("windows")->findChild<QScrollArea*>("scrollArea_2")->findChild<QWidget*>("scrollAreaWidgetContents_2");
+
+    // get all windows from hyprctl
+    std::string windowsList = execAndGet("hyprctl clients");
+
+    // loop over them
+    int windowIterator = 0;
+    while (windowsList.find("Window ") != std::string::npos) {
+        auto windowPropLen = windowsList.find("Window ", windowsList.find("\n\n") + 2);
+        if (windowPropLen == std::string::npos)
+            windowPropLen = windowsList.length();
+        const std::string windowProp = windowsList.substr(0, windowPropLen);
+        windowsList = windowsList.substr(windowPropLen);
+
+        // get window name
+        auto windowName = windowProp.substr(windowProp.find(" -> ") + 4);
+        windowName = windowName.substr(0, windowName.find_first_of('\n') - 1);
+
+        auto windowHandle = windowProp.substr(7, windowProp.find(" -> ") - 7);
+
+        QString text = QString::fromStdString("Window " + windowHandle + ": " + windowName);
+
+        QPushButton* button = new QPushButton(text, (QWidget*)WINDOWS_SCROLL_AREA_CONTENTS);
+        button->move(9, 5 + (BUTTON_HEIGHT + BUTTON_PAD) * windowIterator);
+        button->resize(BUTTON_WIDTH, BUTTON_HEIGHT);
+        QObject::connect(button, &QPushButton::clicked, [=] () {
+            std::string HANDLE = button->text().toStdString();
+            HANDLE = HANDLE.substr(7, HANDLE.find_first_of(':') - 7);
+
+            std::cout << "window:" << HANDLE << "\n";
+            pickerPtr->quit();
+        });
+
+        windowIterator++;
+    }
+
+    WINDOWS_SCROLL_AREA_CONTENTS->resize(WINDOWS_SCROLL_AREA_CONTENTS->size().width(), 5 + (BUTTON_HEIGHT + BUTTON_PAD) * windowIterator);
+
+    // lastly, region
+    const auto REGION_OBJECT = (QWidget*)TAB1->findChild<QWidget*>("region");
+
+    QString text = "Select region...";
+
+    QPushButton* button = new QPushButton(text, (QWidget*)REGION_OBJECT);
+    button->move(79, 80);
+    button->resize(321, 41);
+    QObject::connect(button, &QPushButton::clicked, [=] () {
+        auto REGION = execAndGet("slurp -f \"%o %x %y %w %h\"");
+        REGION = REGION.substr(0, REGION.length() - 1);
+
+        // now, get the screen
+        QScreen* pScreen = nullptr;
+        if (REGION.find_first_of(' ') == std::string::npos) {
+            std::cout << "error1\n";
+            pickerPtr->quit();
+            return 1;
+        }
+        const auto SCREEN_NAME = REGION.substr(0, REGION.find_first_of(' '));
+
+        for (auto& screen : SCREENS) {
+            if (screen->name().toStdString() == SCREEN_NAME) {
+                pScreen = screen;
+                break;
+            }
+        }
+
+        if (!pScreen) {
+            std::cout << "error2\n";
+            pickerPtr->quit();
+            return 1;
+        }
+
+        // get all the coords
+        try {
+            REGION = REGION.substr(REGION.find_first_of(' ') + 1);
+            const auto X = std::stoi(REGION.substr(0, REGION.find_first_of(' ')));
+            REGION = REGION.substr(REGION.find_first_of(' ') + 1);
+            const auto Y = std::stoi(REGION.substr(0, REGION.find_first_of(' ')));
+            REGION = REGION.substr(REGION.find_first_of(' ') + 1);
+            const auto W = std::stoi(REGION.substr(0, REGION.find_first_of(' ')));
+            REGION = REGION.substr(REGION.find_first_of(' ') + 1);
+            const auto H = std::stoi(REGION);
+
+            std::cout << "region:" << SCREEN_NAME << "@" << X - pScreen->geometry().x() << "," << Y - pScreen->geometry().y() << "," << W << "," << H << "\n";
+            pickerPtr->quit();
+            return 0;
+        } catch (...) {
+            std::cout << "error3\n";
+            pickerPtr->quit();
+            return 1;
+        }
+
+        std::cout << "error4\n";
+        pickerPtr->quit();
+        return 1;
+    });
+
+    w.show();
+    return picker.exec();
+}
diff --git a/hyprland-share-picker/mainpicker.cpp b/hyprland-share-picker/mainpicker.cpp
new file mode 100644
index 0000000..a09bb9e
--- /dev/null
+++ b/hyprland-share-picker/mainpicker.cpp
@@ -0,0 +1,19 @@
+#include "mainpicker.h"
+#include "./ui_mainpicker.h"
+#include <QDebug>
+
+MainPicker::MainPicker(QWidget *parent)
+    : QMainWindow(parent)
+    , ui(new Ui::MainPicker)
+{
+    ui->setupUi(this);
+}
+
+MainPicker::~MainPicker()
+{
+    delete ui;
+}
+
+void MainPicker::onMonitorButtonClicked(QObject* target, QEvent* event) {
+    qDebug() << "click";
+}
diff --git a/hyprland-share-picker/mainpicker.h b/hyprland-share-picker/mainpicker.h
new file mode 100644
index 0000000..1713646
--- /dev/null
+++ b/hyprland-share-picker/mainpicker.h
@@ -0,0 +1,25 @@
+#ifndef MAINPICKER_H
+#define MAINPICKER_H
+
+#include <QMainWindow>
+#include <QObject>
+#include <QEvent>
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class MainPicker; }
+QT_END_NAMESPACE
+
+class MainPicker : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    MainPicker(QWidget *parent = nullptr);
+    ~MainPicker();
+
+    void onMonitorButtonClicked(QObject* target, QEvent* event);
+
+private:
+    Ui::MainPicker *ui;
+};
+#endif // MAINPICKER_H
diff --git a/hyprland-share-picker/mainpicker.ui b/hyprland-share-picker/mainpicker.ui
new file mode 100644
index 0000000..c40a385
--- /dev/null
+++ b/hyprland-share-picker/mainpicker.ui
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainPicker</class>
+ <widget class="QMainWindow" name="MainPicker">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>500</width>
+    <height>290</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>500</width>
+    <height>290</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>500</width>
+    <height>290</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>MainPicker</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <property name="minimumSize">
+    <size>
+     <width>500</width>
+     <height>290</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>500</width>
+     <height>290</height>
+    </size>
+   </property>
+   <widget class="QTabWidget" name="tabWidget">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>0</y>
+      <width>500</width>
+      <height>290</height>
+     </rect>
+    </property>
+    <property name="minimumSize">
+     <size>
+      <width>500</width>
+      <height>290</height>
+     </size>
+    </property>
+    <property name="maximumSize">
+     <size>
+      <width>500</width>
+      <height>290</height>
+     </size>
+    </property>
+    <property name="toolTip">
+     <string/>
+    </property>
+    <property name="tabPosition">
+     <enum>QTabWidget::North</enum>
+    </property>
+    <property name="currentIndex">
+     <number>0</number>
+    </property>
+    <widget class="QWidget" name="screens">
+     <attribute name="title">
+      <string>Screen</string>
+     </attribute>
+     <widget class="QScrollArea" name="scrollArea">
+      <property name="geometry">
+       <rect>
+        <x>9</x>
+        <y>9</y>
+        <width>461</width>
+        <height>241</height>
+       </rect>
+      </property>
+      <property name="widgetResizable">
+       <bool>false</bool>
+      </property>
+      <widget class="QWidget" name="scrollAreaWidgetContents">
+       <property name="geometry">
+        <rect>
+         <x>0</x>
+         <y>0</y>
+         <width>459</width>
+         <height>239</height>
+        </rect>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>459</width>
+         <height>239</height>
+        </size>
+       </property>
+       <property name="focusPolicy">
+        <enum>Qt::WheelFocus</enum>
+       </property>
+      </widget>
+     </widget>
+    </widget>
+    <widget class="QWidget" name="windows">
+     <attribute name="title">
+      <string>Window</string>
+     </attribute>
+     <widget class="QScrollArea" name="scrollArea_2">
+      <property name="geometry">
+       <rect>
+        <x>9</x>
+        <y>9</y>
+        <width>461</width>
+        <height>241</height>
+       </rect>
+      </property>
+      <property name="widgetResizable">
+       <bool>false</bool>
+      </property>
+      <widget class="QWidget" name="scrollAreaWidgetContents_2">
+       <property name="geometry">
+        <rect>
+         <x>0</x>
+         <y>0</y>
+         <width>459</width>
+         <height>239</height>
+        </rect>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>459</width>
+         <height>239</height>
+        </size>
+       </property>
+       <property name="focusPolicy">
+        <enum>Qt::WheelFocus</enum>
+       </property>
+      </widget>
+     </widget>
+    </widget>
+    <widget class="QWidget" name="region">
+     <attribute name="title">
+      <string>Region</string>
+     </attribute>
+    </widget>
+   </widget>
+  </widget>
+ </widget>
+ <tabstops>
+  <tabstop>scrollArea</tabstop>
+  <tabstop>scrollArea_2</tabstop>
+  <tabstop>tabWidget</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/wlr.portal b/hyprland.portal
similarity index 50%
rename from wlr.portal
rename to hyprland.portal
index aa63335..7b4f95c 100644
--- a/wlr.portal
+++ b/hyprland.portal
@@ -1,4 +1,4 @@
 [portal]
-DBusName=org.freedesktop.impl.portal.desktop.wlr
+DBusName=org.freedesktop.impl.portal.desktop.hyprland
 Interfaces=org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.ScreenCast;
-UseIn=wlroots;sway;Wayfire;river;phosh;Hyprland;
+UseIn=Hyprland;
diff --git a/meson.build b/meson.build
index c1db66b..d1ee6ed 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project(
-	'xdg-desktop-portal-wlr',
+	'xdg-desktop-portal-hyprland',
 	'c',
 	version: '0.6.0',
 	license: 'MIT',
@@ -86,7 +86,7 @@ xdpw_files = files([
 ])
 
 executable(
-	'xdg-desktop-portal-wlr',
+	'xdg-desktop-portal-hyprland',
 	[xdpw_files, wl_proto_files],
 	dependencies: [
 		wayland_client,
@@ -111,7 +111,7 @@ conf_data.set('systemd_service', '')
 systemd = dependency('systemd', required: get_option('systemd'))
 
 if systemd.found()
-	systemd_service_file = 'xdg-desktop-portal-wlr.service'
+	systemd_service_file = 'xdg-desktop-portal-hyprland.service'
 	user_unit_dir = systemd.get_variable(pkgconfig: 'systemduserunitdir',
 		pkgconfig_define: ['prefix', get_option('prefix')])
 	conf_data.set('systemd_service', 'SystemdService=' + systemd_service_file)
@@ -126,33 +126,13 @@ endif
 
 configure_file(
 	configuration: conf_data,
-	input: 'org.freedesktop.impl.portal.desktop.wlr.service.in',
+	input: 'org.freedesktop.impl.portal.desktop.hyprland.service.in',
 	output: '@BASENAME@',
 	install_dir: join_paths(get_option('datadir'), 'dbus-1', 'services'),
 )
 
 install_data(
-	'wlr.portal',
+	'hyprland.portal',
 	install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal', 'portals'),
 )
 
-scdoc = dependency('scdoc', required: get_option('man-pages'), version: '>= 1.9.7', native: true)
-if scdoc.found()
-	man_pages = ['xdg-desktop-portal-wlr.5.scd']
-	foreach src : man_pages
-		topic = src.split('.')[0]
-		section = src.split('.')[1]
-		output = topic + '.' + section
-
-		custom_target(
-			output,
-			input: files(src),
-			output: output,
-			command: [
-				'sh', '-c', '@0@ < @INPUT@ > @1@'.format(scdoc.get_variable(pkgconfig: 'scdoc'), output)
-			],
-			install: true,
-			install_dir: join_paths(get_option('mandir'), 'man' + section),
-		)
-	endforeach
-endif
diff --git a/meson_options.txt b/meson_options.txt
index 77fa135..d7ae3ab 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,3 +1,2 @@
 option('sd-bus-provider', type: 'combo', choices: ['auto', 'libsystemd', 'libelogind', 'basu'], value: 'auto', description: 'Provider of the sd-bus library')
 option('systemd', type: 'feature', value: 'auto', description: 'Install systemd user service unit')
-option('man-pages', type: 'feature', value: 'auto', description: 'Generate and install man pages')
diff --git a/org.freedesktop.impl.portal.desktop.hyprland.service.in b/org.freedesktop.impl.portal.desktop.hyprland.service.in
new file mode 100644
index 0000000..cb1f305
--- /dev/null
+++ b/org.freedesktop.impl.portal.desktop.hyprland.service.in
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.freedesktop.impl.portal.desktop.hyprland
+Exec=@libexecdir@/xdg-desktop-portal-hyprland
+@systemd_service@
diff --git a/org.freedesktop.impl.portal.desktop.wlr.service.in b/org.freedesktop.impl.portal.desktop.wlr.service.in
deleted file mode 100644
index 2397e77..0000000
--- a/org.freedesktop.impl.portal.desktop.wlr.service.in
+++ /dev/null
@@ -1,4 +0,0 @@
-[D-BUS Service]
-Name=org.freedesktop.impl.portal.desktop.wlr
-Exec=@libexecdir@/xdg-desktop-portal-wlr
-@systemd_service@
diff --git a/src/screencast/wlr_screencast.c b/src/screencast/wlr_screencast.c
index 8d64553..cbf347d 100644
--- a/src/screencast/wlr_screencast.c
+++ b/src/screencast/wlr_screencast.c
@@ -333,202 +333,45 @@ static void wlr_init_xdg_outputs(struct xdpw_screencast_context *ctx) {
 	}
 }
 
-static pid_t spawn_chooser(char *cmd, int chooser_in[2], int chooser_out[2]) {
-	logprint(TRACE,
-			"exec chooser called: cmd %s, pipe chooser_in (%d,%d), pipe chooser_out (%d,%d)",
-			cmd, chooser_in[0], chooser_in[1], chooser_out[0], chooser_out[1]);
-	pid_t pid = fork();
-
-	if (pid < 0) {
-		perror("fork");
-		return pid;
-	} else if (pid == 0) {
-		close(chooser_in[1]);
-		close(chooser_out[0]);
-
-		dup2(chooser_in[0], STDIN_FILENO);
-		dup2(chooser_out[1], STDOUT_FILENO);
-		close(chooser_in[0]);
-		close(chooser_out[1]);
-
-		execl("/bin/sh", "/bin/sh", "-c", cmd, NULL);
-
-		perror("execl");
-		_exit(127);
-	}
-
-	close(chooser_in[0]);
-	close(chooser_out[1]);
-
-	return pid;
-}
-
-static bool wait_chooser(pid_t pid) {
-	int status;
-	if (waitpid(pid ,&status, 0) != -1 && WIFEXITED(status)) {
-		return WEXITSTATUS(status) != 127;
-	}
-	return false;
-}
-
-static bool wlr_output_chooser(struct xdpw_output_chooser *chooser,
-		struct wl_list *output_list, struct xdpw_wlr_output **output) {
-	logprint(DEBUG, "wlroots: output chooser called");
-	struct xdpw_wlr_output *out;
-	size_t name_size = 0;
-	char *name = NULL;
-	*output = NULL;
-
-	int chooser_in[2]; //p -> c
-	int chooser_out[2]; //c -> p
-
-	if (pipe(chooser_in) == -1) {
-		perror("pipe chooser_in");
-		logprint(ERROR, "Failed to open pipe chooser_in");
-		goto error_chooser_in;
-	}
-	if (pipe(chooser_out) == -1) {
-		perror("pipe chooser_out");
-		logprint(ERROR, "Failed to open pipe chooser_out");
-		goto error_chooser_out;
-	}
-
-	pid_t pid = spawn_chooser(chooser->cmd, chooser_in, chooser_out);
-	if (pid < 0) {
-		logprint(ERROR, "Failed to fork chooser");
-		goto error_fork;
-	}
-
-	switch (chooser->type) {
-	case XDPW_CHOOSER_DMENU:;
-		FILE *f = fdopen(chooser_in[1], "w");
-		if (f == NULL) {
-			perror("fdopen pipe chooser_in");
-			logprint(ERROR, "Failed to create stream writing to pipe chooser_in");
-			goto error_fork;
-		}
-		wl_list_for_each(out, output_list, link) {
-			fprintf(f, "%s\n", out->name);
-		}
-		fclose(f);
-		break;
-	default:
-		close(chooser_in[1]);
-	}
-
-	if (!wait_chooser(pid)) {
-		close(chooser_out[0]);
-		return false;
-	}
-
-	FILE *f = fdopen(chooser_out[0], "r");
-	if (f == NULL) {
-		perror("fdopen pipe chooser_out");
-		logprint(ERROR, "Failed to create stream reading from pipe chooser_out");
-		close(chooser_out[0]);
-		goto end;
-	}
-
-	ssize_t nread = getline(&name, &name_size, f);
-	fclose(f);
-	if (nread < 0) {
-		perror("getline failed");
-		goto end;
-	}
-
-	//Strip newline
-	char *p = strchr(name, '\n');
-	if (p != NULL) {
-		*p = '\0';
-	}
-
-	logprint(TRACE, "wlroots: output chooser %s selects output %s", chooser->cmd, name);
-	wl_list_for_each(out, output_list, link) {
-		if (strcmp(out->name, name) == 0) {
-			*output = out;
-			break;
-		}
-	}
-	free(name);
-
-end:
-	return true;
-
-error_fork:
-	close(chooser_out[0]);
-	close(chooser_out[1]);
-error_chooser_out:
-	close(chooser_in[0]);
-	close(chooser_in[1]);
-error_chooser_in:
-	*output = NULL;
-	return false;
-}
-
-static struct xdpw_wlr_output *wlr_output_chooser_default(struct wl_list *output_list) {
-	logprint(DEBUG, "wlroots: output chooser called");
-	struct xdpw_output_chooser default_chooser[] = {
-		{XDPW_CHOOSER_SIMPLE, "slurp -f %o -or"},
-		{XDPW_CHOOSER_DMENU, "wofi -d -n --prompt='Select the monitor to share:'"},
-		{XDPW_CHOOSER_DMENU, "bemenu --prompt='Select the monitor to share:'"},
-	};
-
-	size_t N = sizeof(default_chooser)/sizeof(default_chooser[0]);
-	struct xdpw_wlr_output *output = NULL;
-	bool ret;
-	for (size_t i = 0; i<N; i++) {
-		ret = wlr_output_chooser(&default_chooser[i], output_list, &output);
-		if (!ret) {
-			logprint(DEBUG, "wlroots: output chooser %s not found. Trying next one.",
-					default_chooser[i].cmd);
-			continue;
-		}
-		if (output != NULL) {
-			logprint(DEBUG, "wlroots: output chooser selects %s", output->name);
-		} else {
-			logprint(DEBUG, "wlroots: output chooser canceled");
-		}
-		return output;
-	}
-	return xdpw_wlr_output_first(output_list);
-}
-
 struct xdpw_wlr_output *xdpw_wlr_output_chooser(struct xdpw_screencast_context *ctx) {
-	switch (ctx->state->config->screencast_conf.chooser_type) {
-	case XDPW_CHOOSER_DEFAULT:
-		return wlr_output_chooser_default(&ctx->output_list);
-	case XDPW_CHOOSER_NONE:
-		if (ctx->state->config->screencast_conf.output_name) {
-			return xdpw_wlr_output_find_by_name(&ctx->output_list, ctx->state->config->screencast_conf.output_name);
-		} else {
-			return xdpw_wlr_output_first(&ctx->output_list);
-		}
-	case XDPW_CHOOSER_DMENU:
-	case XDPW_CHOOSER_SIMPLE:;
-		struct xdpw_wlr_output *output = NULL;
-		if (!ctx->state->config->screencast_conf.chooser_cmd) {
-			logprint(ERROR, "wlroots: no output chooser given");
-			goto end;
-		}
-		struct xdpw_output_chooser chooser = {
-			ctx->state->config->screencast_conf.chooser_type,
-			ctx->state->config->screencast_conf.chooser_cmd
-		};
-		logprint(DEBUG, "wlroots: output chooser %s (%d)", chooser.cmd, chooser.type);
-		bool ret = wlr_output_chooser(&chooser, &ctx->output_list, &output);
-		if (!ret) {
-			logprint(ERROR, "wlroots: output chooser %s failed", chooser.cmd);
-			goto end;
-		}
-		if (output) {
-			logprint(DEBUG, "wlroots: output chooser selects %s", output->name);
-		} else {
-			logprint(DEBUG, "wlroots: output chooser canceled");
-		}
-		return output;
+	char result[1024];
+    FILE *fp;
+	char buf[1024];
+
+    fp = popen("/usr/bin/hyprland-share-picker", "r");
+    if (fp == NULL) {
+        printf("Failed to run command\n");
+        exit(1);
+    }
+
+    while (fgets(buf, sizeof(buf), fp) != NULL) {
+        strcat(result, buf);
+    }
+
+    pclose(fp);
+
+	// great, let's parse it.
+	
+	// TODO: window & region
+	if (strncmp(result, "screen:", 7) == 0) {
+		// find
+		char* display_name = malloc(strlen(result) - 7);
+        strncpy(display_name, result + 7, strlen(result) - 8);
+		display_name[strlen(result) - 8] = 0;
+
+		struct xdpw_wlr_output* out;
+        wl_list_for_each(out, &ctx->output_list, link) {
+            if (strcmp(out->name, display_name) == 0) {
+				break;
+			}
+        }
+
+        free(display_name);
+
+		return out;
+    } else {
+		return NULL;
 	}
-end:
-	return NULL;
 }
 
 struct xdpw_wlr_output *xdpw_wlr_output_first(struct wl_list *output_list) {
diff --git a/xdg-desktop-portal-wlr.5.scd b/xdg-desktop-portal-wlr.5.scd
deleted file mode 100644
index 6cec968..0000000
--- a/xdg-desktop-portal-wlr.5.scd
+++ /dev/null
@@ -1,99 +0,0 @@
-xdg-desktop-portal-wlr(5)
-
-# NAME
-
-xdg-desktop-portal-wlr - an xdg-desktop-portal backend for wlroots
-
-# DESCRIPTION
-
-xdg-desktop-portal-wlr (or xdpw for short) allows applications to request
-screenshots and screencasts via xdg-desktop-portal in wlroots-based Wayland
-compositors.
-
-xdpw will try to load the configuration file from these locations:
-
-- $XDG_CONFIG_HOME/xdg-desktop-portal-wlr/$XDG_CURRENT_DESKTOP
-- $XDG_CONFIG_HOME/xdg-desktop-portal-wlr/config
-- /etc/xdg/xdg-desktop-portal-wlr/$XDG_CURRENT_DESKTOP
-- /etc/xdg/xdg-desktop-portal-wlr/config
-
-_$XDG_CONFIG_HOME_ defaults to _~/.config_.
-_$XDG_CURRENT_DESKTOP_ can be a colon separated list. Each element of that list will be tried.
-
-The configuration files use the INI file format. Example:
-
-```
-[screencast]
-output_name=HDMI-A-1
-max_fps=30
-exec_before=disable_notifications.sh
-exec_after=enable_notifications.sh
-chooser_type=simple
-chooser_cmd=slurp -f %o -or
-```
-
-# SCREENCAST OPTIONS
-
-These options need to be placed under the **[screencast]** section.
-
-**output_name** = _name_
-	Select which output will be screencast.
-
-	This option is used with **chooser_type** = none. The list of available outputs
-	can be obtained via **wayland-info**(1) (under the _zxdg_output_manager_v1_
-	section).
-
-**max_fps** = _limit_
-	Limit the number of frames per second to the provided rate.
-
-	This is useful to reduce CPU usage when capturing frames at the output's
-	refresh rate is unnecessary.
-
-**exec_before** = _command_
-	Execute _command_ before starting a screencast. The command will be executed within sh.
-
-**exec_after** = _command_
-	Execute _command_ after ending all screencasts. The command will be executed within sh.
-
-**chooser_cmd** = _command_
-	Run this command to select an output.
-
-	For more details see **OUTPUT CHOOSER**.
-
-**chooser_type** = _type_
-	Specifies the input send to the chooser.
-
-	The supported types are:
-	- default: xdpw will try to use the first chooser found in the list of hardcoded choosers
-	  (slurp, wofi, bemenu) and will fallback to an arbitrary output if none of those were found.
-	- none: xdpw will allow screencast either on the output given by **output_name**, or if empty
-	  an arbitrary output without further interaction.
-	- simple, dmenu: xdpw will launch the chooser given by **chooser_cmd**. For more details
-	  see **OUTPUT CHOOSER**.
-
-**force_mod_linear** = _bool_
-	Force buffers with implicit modifiers to be linear (experimental)
-
-	Setting this option to 1 will force xdpw to allocate dma-bufs with implicit modifier as linear.
-	This option shouldn't be required on single gpu setups, but can increase compatibility
-	especially on setups with multiple gpus.
-
-	This option is experimental and can be removed or replaced in future versions.
-
-## OUTPUT CHOOSER
-
-The chooser can be any program or script with the following behaviour:
-- It returns any error code except 127. The error code 127 is internally used to signal
-  that no command could be found and all output from it will be ignored.
-- It returns the name of a valid output on stdout as given by **wayland-info**(1).
-  Everything else will be handled as declined by the user.
-- To signal that the user has declined screencast, the chooser should exit without
-  anything on stdout.
-
-Supported types of choosers via the **chooser_type** option:
-- simple: the chooser is just called without anything further on stdin.
-- dmenu: the chooser receives a newline separated list (dmenu style) of outputs on stdin.
-
-# SEE ALSO
-
-**pipewire**(1)