Files
gKeyMapper/shared/mapping.h

73 lines
2.6 KiB
C
Raw Normal View History

2026-10-17 03:53:51 +02:00
// gKeyMapper - the mappings file format, shared by GUI and daemon.
//
// File format (one line per G key):
// # gKeyMapper mappings (G1..G9)
// G1=key:ctrl+c,ctrl+v
// G2=command:/usr/bin/firefox
// G3=disabled:
2026-10-18 16:59:51 +02:00
// G4=keyhold:ctrl+w (held down while G4 is held down)
2026-10-17 03:53:51 +02:00
#ifndef GKEYMAPPER_MAPPING_H
#define GKEYMAPPER_MAPPING_H
#include <functional>
#include <string>
#include <vector>
namespace gkeymapper {
constexpr int kNumKeys = 9; // G1..G9
2026-10-18 16:59:51 +02:00
// KeyHold keeps its keys down until the G key is released; the others fire once
// on the press. The order is not part of the file format (the tokens are), but
// keep it stable: the GUI maps dropdown indices explicitly.
enum class ActionType { Disabled, Key, Command, KeyHold };
2026-10-17 03:53:51 +02:00
struct Mapping {
ActionType type = ActionType::Disabled;
std::string target;
};
// One entry per G key; index 0 -> G1.
struct MappingSet {
std::vector<Mapping> keys;
};
const char* action_type_token(ActionType type);
ActionType action_type_from_token(const std::string& token);
// Serialize to / parse from the text representation. parse_mappings always
// returns exactly kNumKeys entries (missing ones default to Disabled).
std::string format_mappings(const MappingSet& set);
MappingSet parse_mappings(const std::string& text);
bool load_mappings_file(const std::string& path, MappingSet& out);
bool save_mappings_file(const std::string& path, const MappingSet& set);
// Default config file: ~/.config/gKeyMapper/mappings.conf.
std::string default_config_path();
// One step of a "ctrl+c" shortcut, ready to be replayed via uinput.
struct ShortcutStep {
unsigned modifiers = 0; // ModifierBit mask
std::string key_name; // canonical key name (layout independent)
int linux_key = -1; // resolved input code, -1 if unresolved
};
// Resolves a canonical key name to an input code for the keyboard layout in
// use. The default (empty) resolver uses linux_key_code(), i.e. the
// layout-independent US key positions.
using KeyResolver = std::function<int(const std::string& name)>;
// Parse "ctrl+c,ctrl+v" into individual steps. Returns false if the text is
// empty or contains an unknown key name.
bool parse_shortcut(const std::string& text, std::vector<ShortcutStep>& out,
const KeyResolver& resolve = KeyResolver());
// Formats one step ("ctrl+shift+t") from a ModifierBit mask and a base key
// name. The modifier order is fixed: ctrl, alt, shift, super, altgr.
std::string format_shortcut_step(unsigned modifiers, const std::string& key_name);
} // namespace gkeymapper
#endif // GKEYMAPPER_MAPPING_H