mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-23 22:55:58 +01:00
Allow the user to disallow a restore token
This commit is contained in:
parent
747988ed9d
commit
2c8eb43704
5 changed files with 89 additions and 39 deletions
|
@ -18,8 +18,8 @@
|
||||||
#include "mainpicker.h"
|
#include "mainpicker.h"
|
||||||
|
|
||||||
std::string execAndGet(const char* cmd) {
|
std::string execAndGet(const char* cmd) {
|
||||||
std::array<char, 128> buffer;
|
std::array<char, 128> buffer;
|
||||||
std::string result;
|
std::string result;
|
||||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
|
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
|
||||||
if (!pipe) {
|
if (!pipe) {
|
||||||
throw std::runtime_error("popen() failed!");
|
throw std::runtime_error("popen() failed!");
|
||||||
|
@ -30,12 +30,12 @@ std::string execAndGet(const char* cmd) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QApplication* pickerPtr = nullptr;
|
QApplication* pickerPtr = nullptr;
|
||||||
MainPicker* mainPickerPtr = nullptr;
|
MainPicker* mainPickerPtr = nullptr;
|
||||||
|
|
||||||
struct SWindowEntry {
|
struct SWindowEntry {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string clazz;
|
std::string clazz;
|
||||||
unsigned long long id = 0;
|
unsigned long long id = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,15 +50,15 @@ std::vector<SWindowEntry> getWindows(const char* env) {
|
||||||
while (!rolling.empty()) {
|
while (!rolling.empty()) {
|
||||||
// ID
|
// ID
|
||||||
const auto IDSEPPOS = rolling.find("[HC>]");
|
const auto IDSEPPOS = rolling.find("[HC>]");
|
||||||
const auto IDSTR = rolling.substr(0, IDSEPPOS);
|
const auto IDSTR = rolling.substr(0, IDSEPPOS);
|
||||||
|
|
||||||
// class
|
// class
|
||||||
const auto CLASSSEPPOS = rolling.find("[HT>]");
|
const auto CLASSSEPPOS = rolling.find("[HT>]");
|
||||||
const auto CLASSSTR = rolling.substr(IDSEPPOS + 5, CLASSSEPPOS - IDSEPPOS - 5);
|
const auto CLASSSTR = rolling.substr(IDSEPPOS + 5, CLASSSEPPOS - IDSEPPOS - 5);
|
||||||
|
|
||||||
// title
|
// title
|
||||||
const auto TITLESEPPOS = rolling.find("[HE>]");
|
const auto TITLESEPPOS = rolling.find("[HE>]");
|
||||||
const auto TITLESTR = rolling.substr(CLASSSEPPOS + 5, TITLESEPPOS - 5 - CLASSSEPPOS);
|
const auto TITLESTR = rolling.substr(CLASSSEPPOS + 5, TITLESEPPOS - 5 - CLASSSEPPOS);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result.push_back({TITLESTR, CLASSSTR, std::stoull(IDSTR)});
|
result.push_back({TITLESTR, CLASSSTR, std::stoull(IDSTR)});
|
||||||
|
@ -75,9 +75,9 @@ std::vector<SWindowEntry> getWindows(const char* env) {
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
qputenv("QT_LOGGING_RULES", "qml=false");
|
qputenv("QT_LOGGING_RULES", "qml=false");
|
||||||
|
|
||||||
const char* WINDOWLISTSTR = getenv("XDPH_WINDOW_SHARING_LIST");
|
const char* WINDOWLISTSTR = getenv("XDPH_WINDOW_SHARING_LIST");
|
||||||
|
|
||||||
const auto WINDOWLIST = getWindows(WINDOWLISTSTR);
|
const auto WINDOWLIST = getWindows(WINDOWLISTSTR);
|
||||||
|
|
||||||
QApplication picker(argc, argv);
|
QApplication picker(argc, argv);
|
||||||
pickerPtr = &picker;
|
pickerPtr = &picker;
|
||||||
|
@ -85,30 +85,37 @@ int main(int argc, char* argv[]) {
|
||||||
mainPickerPtr = &w;
|
mainPickerPtr = &w;
|
||||||
|
|
||||||
// get the tabwidget
|
// get the tabwidget
|
||||||
const auto TABWIDGET = (QTabWidget*)w.children()[1]->children()[0];
|
const auto TABWIDGET = (QTabWidget*)w.children()[1]->children()[0];
|
||||||
|
const auto ALLOWTOKENBUTTON = (QCheckBox*)w.children()[1]->children()[1];
|
||||||
|
|
||||||
const auto TAB1 = (QWidget*)TABWIDGET->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");
|
const auto SCREENS_SCROLL_AREA_CONTENTS =
|
||||||
|
(QWidget*)TAB1->findChild<QWidget*>("screens")->findChild<QScrollArea*>("scrollArea")->findChild<QWidget*>("scrollAreaWidgetContents");
|
||||||
|
|
||||||
// add all screens
|
// add all screens
|
||||||
const auto SCREENS = picker.screens();
|
const auto SCREENS = picker.screens();
|
||||||
|
|
||||||
constexpr int BUTTON_WIDTH = 441;
|
constexpr int BUTTON_WIDTH = 441;
|
||||||
constexpr int BUTTON_HEIGHT = 41;
|
constexpr int BUTTON_HEIGHT = 41;
|
||||||
constexpr int BUTTON_PAD = 4;
|
constexpr int BUTTON_PAD = 4;
|
||||||
|
|
||||||
for (int i = 0; i < SCREENS.size(); ++i) {
|
for (int i = 0; i < SCREENS.size(); ++i) {
|
||||||
const auto GEOMETRY = SCREENS[i]->geometry();
|
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() + ")");
|
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);
|
QPushButton* button = new QPushButton(text, (QWidget*)SCREENS_SCROLL_AREA_CONTENTS);
|
||||||
button->move(9, 5 + (BUTTON_HEIGHT + BUTTON_PAD) * i);
|
button->move(9, 5 + (BUTTON_HEIGHT + BUTTON_PAD) * i);
|
||||||
button->resize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
button->resize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
||||||
QObject::connect(button, &QPushButton::clicked, [=]() {
|
QObject::connect(button, &QPushButton::clicked, [=]() {
|
||||||
std::string ID = button->text().toStdString();
|
std::string ID = button->text().toStdString();
|
||||||
ID = ID.substr(ID.find_last_of('(') + 1);
|
ID = ID.substr(ID.find_last_of('(') + 1);
|
||||||
ID = ID.substr(0, ID.find_last_of(')'));
|
ID = ID.substr(0, ID.find_last_of(')'));
|
||||||
|
|
||||||
|
std::cout << (ALLOWTOKENBUTTON->isChecked() ? "r" : "");
|
||||||
|
std::cout << "/";
|
||||||
|
|
||||||
std::cout << "screen:" << ID << "\n";
|
std::cout << "screen:" << ID << "\n";
|
||||||
pickerPtr->quit();
|
pickerPtr->quit();
|
||||||
|
@ -119,12 +126,13 @@ int main(int argc, char* argv[]) {
|
||||||
SCREENS_SCROLL_AREA_CONTENTS->resize(SCREENS_SCROLL_AREA_CONTENTS->size().width(), 5 + (BUTTON_HEIGHT + BUTTON_PAD) * SCREENS.size());
|
SCREENS_SCROLL_AREA_CONTENTS->resize(SCREENS_SCROLL_AREA_CONTENTS->size().width(), 5 + (BUTTON_HEIGHT + BUTTON_PAD) * SCREENS.size());
|
||||||
|
|
||||||
// windows
|
// windows
|
||||||
const auto WINDOWS_SCROLL_AREA_CONTENTS = (QWidget*)TAB1->findChild<QWidget*>("windows")->findChild<QScrollArea*>("scrollArea_2")->findChild<QWidget*>("scrollAreaWidgetContents_2");
|
const auto WINDOWS_SCROLL_AREA_CONTENTS =
|
||||||
|
(QWidget*)TAB1->findChild<QWidget*>("windows")->findChild<QScrollArea*>("scrollArea_2")->findChild<QWidget*>("scrollAreaWidgetContents_2");
|
||||||
|
|
||||||
// loop over them
|
// loop over them
|
||||||
int windowIterator = 0;
|
int windowIterator = 0;
|
||||||
for (auto& window : WINDOWLIST) {
|
for (auto& window : WINDOWLIST) {
|
||||||
QString text = QString::fromStdString(window.clazz + ": " + window.name);
|
QString text = QString::fromStdString(window.clazz + ": " + window.name);
|
||||||
|
|
||||||
QPushButton* button = new QPushButton(text, (QWidget*)WINDOWS_SCROLL_AREA_CONTENTS);
|
QPushButton* button = new QPushButton(text, (QWidget*)WINDOWS_SCROLL_AREA_CONTENTS);
|
||||||
button->move(9, 5 + (BUTTON_HEIGHT + BUTTON_PAD) * windowIterator);
|
button->move(9, 5 + (BUTTON_HEIGHT + BUTTON_PAD) * windowIterator);
|
||||||
|
@ -133,6 +141,9 @@ int main(int argc, char* argv[]) {
|
||||||
mainPickerPtr->windowIDs[button] = window.id;
|
mainPickerPtr->windowIDs[button] = window.id;
|
||||||
|
|
||||||
QObject::connect(button, &QPushButton::clicked, [=]() {
|
QObject::connect(button, &QPushButton::clicked, [=]() {
|
||||||
|
std::cout << (ALLOWTOKENBUTTON->isChecked() ? "r" : "");
|
||||||
|
std::cout << "/";
|
||||||
|
|
||||||
std::cout << "window:" << mainPickerPtr->windowIDs[button] << "\n";
|
std::cout << "window:" << mainPickerPtr->windowIDs[button] << "\n";
|
||||||
pickerPtr->quit();
|
pickerPtr->quit();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -144,16 +155,16 @@ int main(int argc, char* argv[]) {
|
||||||
WINDOWS_SCROLL_AREA_CONTENTS->resize(WINDOWS_SCROLL_AREA_CONTENTS->size().width(), 5 + (BUTTON_HEIGHT + BUTTON_PAD) * windowIterator);
|
WINDOWS_SCROLL_AREA_CONTENTS->resize(WINDOWS_SCROLL_AREA_CONTENTS->size().width(), 5 + (BUTTON_HEIGHT + BUTTON_PAD) * windowIterator);
|
||||||
|
|
||||||
// lastly, region
|
// lastly, region
|
||||||
const auto REGION_OBJECT = (QWidget*)TAB1->findChild<QWidget*>("region");
|
const auto REGION_OBJECT = (QWidget*)TAB1->findChild<QWidget*>("region");
|
||||||
|
|
||||||
QString text = "Select region...";
|
QString text = "Select region...";
|
||||||
|
|
||||||
QPushButton* button = new QPushButton(text, (QWidget*)REGION_OBJECT);
|
QPushButton* button = new QPushButton(text, (QWidget*)REGION_OBJECT);
|
||||||
button->move(79, 80);
|
button->move(79, 80);
|
||||||
button->resize(321, 41);
|
button->resize(321, 41);
|
||||||
QObject::connect(button, &QPushButton::clicked, [=]() {
|
QObject::connect(button, &QPushButton::clicked, [=]() {
|
||||||
auto REGION = execAndGet("slurp -f \"%o %x %y %w %h\"");
|
auto REGION = execAndGet("slurp -f \"%o %x %y %w %h\"");
|
||||||
REGION = REGION.substr(0, REGION.length());
|
REGION = REGION.substr(0, REGION.length());
|
||||||
|
|
||||||
// now, get the screen
|
// now, get the screen
|
||||||
QScreen* pScreen = nullptr;
|
QScreen* pScreen = nullptr;
|
||||||
|
@ -179,15 +190,18 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
// get all the coords
|
// get all the coords
|
||||||
try {
|
try {
|
||||||
REGION = REGION.substr(REGION.find_first_of(' ') + 1);
|
REGION = REGION.substr(REGION.find_first_of(' ') + 1);
|
||||||
const auto X = std::stoi(REGION.substr(0, REGION.find_first_of(' ')));
|
const auto X = std::stoi(REGION.substr(0, REGION.find_first_of(' ')));
|
||||||
REGION = REGION.substr(REGION.find_first_of(' ') + 1);
|
REGION = REGION.substr(REGION.find_first_of(' ') + 1);
|
||||||
const auto Y = std::stoi(REGION.substr(0, REGION.find_first_of(' ')));
|
const auto Y = std::stoi(REGION.substr(0, REGION.find_first_of(' ')));
|
||||||
REGION = REGION.substr(REGION.find_first_of(' ') + 1);
|
REGION = REGION.substr(REGION.find_first_of(' ') + 1);
|
||||||
const auto W = std::stoi(REGION.substr(0, REGION.find_first_of(' ')));
|
const auto W = std::stoi(REGION.substr(0, REGION.find_first_of(' ')));
|
||||||
REGION = REGION.substr(REGION.find_first_of(' ') + 1);
|
REGION = REGION.substr(REGION.find_first_of(' ') + 1);
|
||||||
const auto H = std::stoi(REGION);
|
const auto H = std::stoi(REGION);
|
||||||
|
|
||||||
|
std::cout << (ALLOWTOKENBUTTON->isChecked() ? "r" : "");
|
||||||
|
std::cout << "/";
|
||||||
|
|
||||||
std::cout << "region:" << SCREEN_NAME << "@" << X - pScreen->geometry().x() << "," << Y - pScreen->geometry().y() << "," << W << "," << H << "\n";
|
std::cout << "region:" << SCREEN_NAME << "@" << X - pScreen->geometry().x() << "," << Y - pScreen->geometry().y() << "," << W << "," << H << "\n";
|
||||||
pickerPtr->quit();
|
pickerPtr->quit();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
<enum>QTabWidget::North</enum>
|
<enum>QTabWidget::North</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="screens">
|
<widget class="QWidget" name="screens">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
@ -78,9 +78,12 @@
|
||||||
<x>9</x>
|
<x>9</x>
|
||||||
<y>9</y>
|
<y>9</y>
|
||||||
<width>461</width>
|
<width>461</width>
|
||||||
<height>241</height>
|
<height>201</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
<property name="widgetResizable">
|
<property name="widgetResizable">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@ -115,9 +118,12 @@
|
||||||
<x>9</x>
|
<x>9</x>
|
||||||
<y>9</y>
|
<y>9</y>
|
||||||
<width>461</width>
|
<width>461</width>
|
||||||
<height>241</height>
|
<height>201</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
<property name="widgetResizable">
|
<property name="widgetResizable">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@ -148,6 +154,22 @@
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QCheckBox" name="checkBox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>340</x>
|
||||||
|
<y>256</y>
|
||||||
|
<width>140</width>
|
||||||
|
<height>21</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>By selecting this, the application will be given a restore token that it can use to skip prompting you next time. Only select if you trust the application.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Allow a restore token</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
|
|
|
@ -539,7 +539,7 @@ void CScreencopyPortal::onStart(sdbus::MethodCall& call) {
|
||||||
|
|
||||||
std::unordered_map<std::string, sdbus::Variant> options;
|
std::unordered_map<std::string, sdbus::Variant> options;
|
||||||
|
|
||||||
if (PSESSION->persistMode != 0) {
|
if (PSESSION->persistMode != 0 && PSESSION->selection.allowToken) {
|
||||||
// give them a token :)
|
// give them a token :)
|
||||||
std::unordered_map<std::string, sdbus::Variant> mapData;
|
std::unordered_map<std::string, sdbus::Variant> mapData;
|
||||||
|
|
||||||
|
@ -564,6 +564,8 @@ void CScreencopyPortal::onStart(sdbus::MethodCall& call) {
|
||||||
sdbus::Variant restoreData{mapData};
|
sdbus::Variant restoreData{mapData};
|
||||||
sdbus::Struct<std::string, uint32_t, sdbus::Variant> fullRestoreStruct{"hyprland", 3, restoreData};
|
sdbus::Struct<std::string, uint32_t, sdbus::Variant> fullRestoreStruct{"hyprland", 3, restoreData};
|
||||||
options["restore_data"] = sdbus::Variant{fullRestoreStruct};
|
options["restore_data"] = sdbus::Variant{fullRestoreStruct};
|
||||||
|
|
||||||
|
Debug::log(LOG, "[screencopy] Sent restore token to {}", PSESSION->sessionHandle.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t type = 0;
|
uint32_t type = 0;
|
||||||
|
|
|
@ -49,14 +49,25 @@ SSelectionData promptForScreencopySelection() {
|
||||||
|
|
||||||
Debug::log(LOG, "[sc] Selection: {}", RETVAL);
|
Debug::log(LOG, "[sc] Selection: {}", RETVAL);
|
||||||
|
|
||||||
if (RETVAL.find("screen:") == 0) {
|
const auto FLAGS = RETVAL.substr(0, RETVAL.find_first_of('/'));
|
||||||
|
const auto SEL = RETVAL.substr(RETVAL.find_first_of('/') + 1);
|
||||||
|
|
||||||
|
for (auto& flag : FLAGS) {
|
||||||
|
if (flag == 'r') {
|
||||||
|
data.allowToken = true;
|
||||||
|
} else {
|
||||||
|
Debug::log(LOG, "[screencopy] unknown flag from share-picker: {}", flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SEL.find("screen:") == 0) {
|
||||||
data.type = TYPE_OUTPUT;
|
data.type = TYPE_OUTPUT;
|
||||||
data.output = RETVAL.substr(7);
|
data.output = SEL.substr(7);
|
||||||
|
|
||||||
data.output.pop_back();
|
data.output.pop_back();
|
||||||
} else if (RETVAL.find("window:") == 0) {
|
} else if (SEL.find("window:") == 0) {
|
||||||
data.type = TYPE_WINDOW;
|
data.type = TYPE_WINDOW;
|
||||||
uint32_t handleLo = std::stoull(RETVAL.substr(7));
|
uint32_t handleLo = std::stoull(SEL.substr(7));
|
||||||
data.windowHandle = nullptr;
|
data.windowHandle = nullptr;
|
||||||
|
|
||||||
for (auto& e : g_pPortalManager->m_sHelpers.toplevel->m_vToplevels) {
|
for (auto& e : g_pPortalManager->m_sHelpers.toplevel->m_vToplevels) {
|
||||||
|
@ -68,8 +79,8 @@ SSelectionData promptForScreencopySelection() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (RETVAL.find("region:") == 0) {
|
} else if (SEL.find("region:") == 0) {
|
||||||
std::string running = RETVAL;
|
std::string running = SEL;
|
||||||
running = running.substr(7);
|
running = running.substr(7);
|
||||||
data.type = TYPE_GEOMETRY;
|
data.type = TYPE_GEOMETRY;
|
||||||
data.output = running.substr(0, running.find_first_of('@'));
|
data.output = running.substr(0, running.find_first_of('@'));
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct SSelectionData {
|
||||||
std::string output;
|
std::string output;
|
||||||
zwlr_foreign_toplevel_handle_v1* windowHandle = nullptr;
|
zwlr_foreign_toplevel_handle_v1* windowHandle = nullptr;
|
||||||
uint32_t x = 0, y = 0, w = 0, h = 0; // for TYPE_GEOMETRY
|
uint32_t x = 0, y = 0, w = 0, h = 0; // for TYPE_GEOMETRY
|
||||||
|
bool allowToken = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wl_buffer;
|
struct wl_buffer;
|
||||||
|
|
Loading…
Reference in a new issue