Skip to content

Commit b8737c8

Browse files
committed
Some app launcher tweaks
1 parent 1d8d736 commit b8737c8

File tree

3 files changed

+101
-22
lines changed

3 files changed

+101
-22
lines changed

src/ipc.cpp

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,20 +120,10 @@ void WSS::IPC::Start() {
120120
Listen("appd-application-run", [this](Shell* shell, const IPCClientInfo* client, const json_object* payload) {
121121
std::string prefix = JSON_GET_STR(payload, "prefix");
122122
std::string appId = JSON_GET_STR(payload, "appId");
123+
WSS_DEBUG("Running application with ID: {} using prefix: {}", appId, prefix);
123124
shell->GetAppd().RunApplication(prefix, appId);
124125
});
125126

126-
Listen("monitor-info-request", [this](Shell* shell, const IPCClientInfo* client, const json_object* payload) {
127-
auto monitor = shell->GetWidget(client->widgetName)->GetMonitorInfo(client->monitorId);
128-
129-
json_object* response = json_object_new_object();
130-
json_object_object_add(response, "id", json_object_new_int(client->monitorId));
131-
json_object_object_add(response, "width", json_object_new_int(GetScreenWidth(client->monitorId)));
132-
json_object_object_add(response, "height", json_object_new_int(GetScreenHeight(client->monitorId)));
133-
Send(client->wsi, "monitor-info-response", response);
134-
json_object_put(response);
135-
});
136-
137127
Listen("appd-application-list-request", [this](Shell* shell, const IPCClientInfo* client, const json_object* payload) {
138128
json_object* response = json_object_new_array();
139129
for (const auto& [name, app] : shell->GetAppd().GetApplications()) {
@@ -150,6 +140,30 @@ void WSS::IPC::Start() {
150140
json_object_put(response);
151141
});
152142

143+
Listen("monitor-info-request", [this](Shell* shell, const IPCClientInfo* client, const json_object* payload) {
144+
auto monitor = shell->GetWidget(client->widgetName)->GetMonitorInfo(client->monitorId);
145+
146+
json_object* response = json_object_new_object();
147+
json_object_object_add(response, "id", json_object_new_int(client->monitorId));
148+
json_object_object_add(response, "width", json_object_new_int(GetScreenWidth(client->monitorId)));
149+
json_object_object_add(response, "height", json_object_new_int(GetScreenHeight(client->monitorId)));
150+
Send(client->wsi, "monitor-info-response", response);
151+
json_object_put(response);
152+
});
153+
154+
Listen("widget-set-keyboard-interactivity", [this](Shell* shell, const IPCClientInfo* client, const json_object* payload) {
155+
std::string widgetName = client->widgetName;
156+
int monitorId = client->monitorId;
157+
auto widget = shell->GetWidget(widgetName);
158+
if (!widget) {
159+
WSS_ERROR("Widget '{}' not found for setting keyboard interactivity.", widgetName);
160+
return;
161+
}
162+
163+
bool interactive = JSON_GET_BOOL(payload, "interactive");
164+
widget->SetKeyboardInteractivity(monitorId, interactive);
165+
});
166+
153167
m_MousePositionRunning = true;
154168
m_MousePositionThread = std::thread([this]() {
155169
try {

src/modules/appd.cpp

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,52 @@ void WSS::Appd::AddApplication(const std::string& name, const Application& app)
252252
SendAppIPC(app);
253253
}
254254

255+
std::string ReplaceDesktopEntryPlaceholders(const std::string& exec, const std::map<std::string, std::string>& context) {
256+
std::string result;
257+
size_t i = 0;
258+
259+
while (i < exec.size()) {
260+
if (exec[i] == '%' && i + 1 < exec.size()) {
261+
char next = exec[i + 1];
262+
std::string replacement;
263+
264+
switch (next) {
265+
case 'f':
266+
replacement = context.count("%f") ? context.at("%f") : "";
267+
break;
268+
case 'F':
269+
replacement = context.count("%F") ? context.at("%F") : "";
270+
break;
271+
case 'u':
272+
replacement = context.count("%u") ? context.at("%u") : "";
273+
break;
274+
case 'U':
275+
replacement = context.count("%U") ? context.at("%U") : "";
276+
break;
277+
case 'i':
278+
replacement = context.count("%i") ? context.at("%i") : "";
279+
break;
280+
case 'c':
281+
replacement = context.count("%c") ? context.at("%c") : "";
282+
break;
283+
case 'k':
284+
replacement = context.count("%k") ? context.at("%k") : "";
285+
break;
286+
default:
287+
replacement = "%" + std::string(1, next);
288+
break;
289+
}
290+
291+
result += replacement;
292+
i += 2;
293+
} else {
294+
result += exec[i++];
295+
}
296+
}
297+
298+
return result;
299+
}
300+
255301
void WSS::Appd::RunApplication(const std::string& prefix, const std::string& appId) {
256302
std::lock_guard lock(m_ApplicationsMutex);
257303
auto it = m_Applications.find(appId);
@@ -261,18 +307,19 @@ void WSS::Appd::RunApplication(const std::string& prefix, const std::string& app
261307
}
262308

263309
const Application& app = it->second;
264-
std::string command = prefix + " " + app.Exec;
265-
266-
int status = system(command.c_str());
267-
if (status != 0) {
268-
WSS_ERROR("Failed to run the application with status code: {}", status);
310+
std::string command =
311+
prefix + " " +
312+
ReplaceDesktopEntryPlaceholders(app.Exec, {{"%f", ""}, {"%F", ""}, {"%u", ""}, {"%U", ""}, {"%i", ""}, {"%c", ""}, {"%k", ""}});
313+
314+
// Run app through "hyprctl dispatch exec --"
315+
std::string fullCommand = "hyprctl dispatch exec -- " + command;
316+
WSS_DEBUG("Running application: {}", fullCommand);
317+
int result = system(fullCommand.c_str());
318+
if (result != 0) {
319+
WSS_ERROR("Failed to run application '{}': exit code {}", app.Name, result);
320+
} else {
321+
WSS_DEBUG("Application '{}' started successfully.", app.Name);
269322
}
270-
271-
json_object* payload = json_object_new_object();
272-
json_object_object_add(payload, "id", json_object_new_string(app.Id.c_str()));
273-
json_object_object_add(payload, "name", json_object_new_string(app.Name.c_str()));
274-
json_object_object_add(payload, "status", json_object_new_int(status));
275-
m_Shell->GetIPC().Broadcast("appd-application-result", payload);
276323
}
277324
void WSS::Appd::SendAppIPC(const Application& app) {
278325
json_object* payload = json_object_new_object();

src/widget.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,24 @@ class Widget {
309309
}
310310
}
311311

312+
void SetKeyboardInteractivity(const uint8_t monitorId, const bool interactive) const {
313+
if (auto* window = GetWindow(monitorId); window) {
314+
#ifndef WSS_USE_QT
315+
gtk_layer_set_keyboard_interactivity(window, interactive ? GTK_LAYER_SHELL_KEYBOARD_INTERACTIVITY_ON
316+
: GTK_LAYER_SHELL_KEYBOARD_INTERACTIVITY_OFF);
317+
#else
318+
auto* layer = LayerShellQt::Window::get(window->windowHandle());
319+
if (layer) {
320+
layer->setKeyboardInteractivity(interactive ? LayerShellQt::Window::KeyboardInteractivityOnDemand
321+
: LayerShellQt::Window::KeyboardInteractivityNone);
322+
window->update();
323+
} else {
324+
WSS_WARN("LayerShellQt::Window not found for monitor ID: {}", monitorId);
325+
}
326+
#endif
327+
}
328+
}
329+
312330
/**
313331
* Sets the exclusivity for the window on the specified monitor ID.
314332
* If the window is set to exclusive mode, it will prevent other windows from overlapping with

0 commit comments

Comments
 (0)