Skip to content

Commit

Permalink
Verbose output for linux/client
Browse files Browse the repository at this point in the history
  • Loading branch information
houmain committed Jan 24, 2021
1 parent 4d96cfb commit bd0d20c
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 12 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ if(NOT WIN32)
src/linux/client/Settings.h
src/linux/client/ipc.cpp
src/linux/client/ipc.h
src/linux/client/output.h
src/linux/client/main.cpp
)

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ The command line argument ```-u``` causes the configuration to be automatically

### Key names

The keys are named after their scancodes and not affected by the present keyboard layout.
The names have been chosen to match on what the [web browsers](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code) have agreed upon, so this [handy website](http://keycode.info/) can be used to get a key's name.
The keys are named after their scancodes and are not affected by the present keyboard layout.
The names have been chosen to match on what the [web browsers](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values) have agreed upon, so this [handy website](http://keycode.info/) can be used to get a key's name.
For convenience the letter and digits keys are also named ```A``` to ```Z``` and ```0``` to ```9```. The logical keys ```Shift```, ```Control``` and ```Meta``` are also defined (each matches the left and right modifier keys). There are also [virtual keys](#virtual-keys) for state switching and an [Any](#any-key) key.

### Input expressions
Expand Down Expand Up @@ -159,7 +159,7 @@ systemctl enable keymapperd

**Other Linux distributions:**

No packages are provided yet, please follow the instructions for [building manually](#Building).
No packages are provided yet, please follow the instructions for [building manually](#Building) or download a portable build from the [latest release](https://github.com/houmain/keymapper/releases/latest) page.

To try it out, simply create a [configuration](#configuration) file and start it using:
```
Expand Down
3 changes: 2 additions & 1 deletion src/linux/client/ConfigFile.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

#include "ConfigFile.h"
#include "config/ParseConfig.h"
#include "output.h"
#include <cstdio>
#include <fstream>
#include <unistd.h>
Expand Down Expand Up @@ -38,7 +39,7 @@ bool ConfigFile::update() {
m_config = parse(is);
}
catch (const std::exception& ex) {
std::fprintf(stderr, "%s\n", ex.what());
error("%s", ex.what());
return false;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/linux/client/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void print_help_message(const char* argv0) {
" -c, --config <path> configuration file.\n"
" -u, --update reload configuration file when it changes.\n"
" -v, --verbose enable verbose output.\n"
" -h, --help print this help.\n"
"\n"
"All Rights Reserved.\n"
"This program comes with absolutely no warranty.\n"
Expand Down
8 changes: 7 additions & 1 deletion src/linux/client/ipc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ int initialize_ipc(const char* fifo_filename) {
::signal(SIGPIPE, [](int) { g_pipe_broken = true; });
g_pipe_broken = false;

return ::open(fifo_filename, O_WRONLY);
for (;;) {
const auto fd = ::open(fifo_filename, O_WRONLY);
if (fd >= 0)
return fd;

::usleep(500 * 100);
}
}

void shutdown_ipc(int fd) {
Expand Down
69 changes: 62 additions & 7 deletions src/linux/client/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,36 @@
#include "FocusedWindow.h"
#include "Settings.h"
#include "ConfigFile.h"
#include "config/Config.h"
#include "output.h"
#include <string>
#include <cstdarg>
#include <unistd.h>

namespace {
const auto ipc_fifo_filename = "/tmp/keymapper";
const auto config_filename = get_home_directory() + "/.config/keymapper.conf";
const auto update_interval_ms = 50;
bool g_verbose_output = false;
}

void error(const char* format, ...) {
va_list args;
va_start(args, format);
std::vfprintf(stderr, format, args);
va_end(args);
std::fputc('\n', stderr);
}

void verbose(const char* format, ...) {
if (g_verbose_output) {
va_list args;
va_start(args, format);
std::vfprintf(stdout, format, args);
va_end(args);
std::fputc('\n', stdout);
std::fflush(stdout);
}
}

int main(int argc, char* argv[]) {
Expand All @@ -20,46 +43,78 @@ int main(int argc, char* argv[]) {
print_help_message(argv[0]);
return 1;
}
g_verbose_output = settings.verbose;

// load initial configuration
verbose("loading configuration file '%s'", settings.config_file_path.c_str());
auto config_file = ConfigFile(settings.config_file_path);
if (!config_file.update()) {
std::fprintf(stderr, "loading configuration failed\n");
error("loading configuration failed");
return 1;
}
for (;;) {
// initialize client/server IPC
verbose("connecting to keymapperd");
const auto ipc_fd = initialize_ipc(ipc_fifo_filename);
if (ipc_fd < 0) {
::sleep(1);
if (ipc_fd < 0)
continue;
}

// initialize focused window detection
verbose("initializing focused window detection");
auto focused_window = create_focused_window();
if (!focused_window) {
error("initializing focused window detection failed");
}

// send configuration
verbose("sending configuration to keymapperd");
if (send_config(ipc_fd, config_file.config())) {
verbose("entering update loop");

// main loop
auto active_override_set = -1;
for (;;) {
// update configuration, reset on success
if (settings.auto_update_config &&
config_file.update())
config_file.update()) {
verbose("configuration updated");
break;
}

if (is_pipe_broken((ipc_fd)))
if (is_pipe_broken((ipc_fd))) {
verbose("connection to keymapperd lost");
break;
}

// update active override set
if (focused_window && update_focused_window(*focused_window)) {
verbose("detected focused window changed:");
verbose(" class = '%s'", get_class(*focused_window).c_str());
verbose(" title = '%s'", get_title(*focused_window).c_str());

const auto override_set = find_context(
config_file.config(),
get_class(*focused_window),
get_title(*focused_window));

if (active_override_set != override_set) {
if (override_set >= 0) {
verbose("sending 'active context #%i' to keymapperd:", override_set + 1);
const auto& context = config_file.config().contexts[override_set];
if (!context.window_class_filter.empty())
verbose(" class filter = '%s'", context.window_class_filter.c_str());
if (!context.window_title_filter.empty())
verbose(" title filter = '%s'", context.window_title_filter.c_str());
}
else {
verbose("sending 'no active context' to keymapperd");
}

active_override_set = override_set;
if (!send_active_override_set(ipc_fd, active_override_set))
if (!send_active_override_set(ipc_fd, active_override_set)) {
verbose("connection to keymapperd lost");
break;
}
}
}
usleep(update_interval_ms * 1000);
Expand Down
4 changes: 4 additions & 0 deletions src/linux/client/output.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

void error(const char* format, ...);
void verbose(const char* format, ...);

0 comments on commit bd0d20c

Please sign in to comment.