Skip to content

Commit c9dc770

Browse files
authored
Use compose key instead of unicode input (#1)
1 parent 8fafe2e commit c9dc770

File tree

2 files changed

+55
-35
lines changed

2 files changed

+55
-35
lines changed

README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ If you're interested in getting yourself an Atreus62 keyboards, it can be purcha
99

1010
This is my custom layout which is based on the US keyboard layout with some extra modifications for the Swedish characters `åäö`. It consists of three layers where some special keys are accessible while holding the `FN` key.
1111

12-
Input of Swedish characters under US layout is achieved with the unicode input mode that is available in Linux via (the `ctrl` + `shift` + `u`) key combination. You can read more about this at the [QMKs Unicode section](https://beta.docs.qmk.fm/using-qmk/software-features/feature_unicode#input-modes).
13-
14-
_This mode is not accesible under Windows, and therefore this layout might not work as expected for those users._
15-
16-
Some applications behave unexpectedly when trying to input characters this way, resulting in some weird behaviour. To circumvent this, one workaround is to temporarily change the keyboard layout to Swedish in your OS. If you know a better way, please consider creating a PR.
12+
Input of Swedish characters under US layout is achieved with the usage of `compose` key. You can read more about this at the [Arch wiki](https://wiki.archlinux.org/title/Xorg/Keyboard_configuration#Configuring_compose_key).
1713

1814
## Installation
1915

zapling/keymap.c

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ enum custom_keys {
1313
KEY_EUR
1414
};
1515

16-
// Custom unicode characters
17-
const char LOWER_A_DIACRITIC[] = "0x00e5"; // å
18-
const char UPPER_A_DIACRITIC[] = "0x00c5"; // Å
16+
// Custom keys with compose-key instructions
17+
const char LOWER_A_DIACRITIC[] = "oa"; // å
18+
const char UPPER_A_DIACRITIC[] = "oA"; // Å
1919

20-
const char LOWER_A_DIAERESIS[] = "0x00e4"; // ä
21-
const char UPPER_A_DIAERESIS[] = "0x00c4"; // Ä
20+
const char LOWER_A_DIAERESIS[] = "\"a"; // ä
21+
const char UPPER_A_DIAERESIS[] = "\"A"; // Ä
2222

23-
const char LOWER_O_DIAERESIS[] = "0x00f6"; // ö
24-
const char UPPER_O_DIAERESIS[] = "0x00d6"; // Ö
23+
const char LOWER_O_DIAERESIS[] = "\"o"; // ö
24+
const char UPPER_O_DIAERESIS[] = "\"O"; // Ö
2525

26-
const char EURO_SIGN[] = "0x20ac"; // €
26+
const char EURO_SIGN[] = "=e"; // €
2727

2828
/**
2929
* Return true if the shift modifier pressed
@@ -35,23 +35,47 @@ bool is_shift_pressed(void) {
3535
return false;
3636
}
3737

38-
/**
39-
* Print a custom unicode character
40-
* Uses the linux unicode input mode in order to convert the unicode to a real character.
41-
* This might not always work, depending on the application.
42-
*
43-
* Uses the function 'send_string' in lowercase that allows for a char param.
44-
*/
45-
void print_unicode_char(const char* chars) {
46-
SEND_STRING(
47-
SS_DOWN(X_LCTL)
48-
SS_DOWN(X_LSFT)
49-
"u"
50-
SS_UP(X_LCTL)
51-
SS_UP(X_LSFT)
52-
);
53-
send_string(chars);
54-
SEND_STRING(SS_TAP(X_ENT));
38+
struct Shift_States {
39+
bool LeftShift;
40+
bool RightShift;
41+
};
42+
43+
struct Shift_States get_shift_states(void) {
44+
struct Shift_States state = {
45+
keyboard_report->mods & MOD_BIT(KC_LSFT),
46+
keyboard_report->mods & MOD_BIT(KC_RSFT)
47+
};
48+
return state;
49+
}
50+
51+
/*
52+
* Uses compose key to get characters that are not usally accessable under US layout.
53+
* Relieas on that 'X_APP' aka Menu button is set as the compose key in OS.
54+
* See https://wiki.archlinux.org/title/Xorg/Keyboard_configuration#Configuring_compose_key
55+
*
56+
* Will release all shift modifiers temporarily and return it's state when done.
57+
*/
58+
void compose_character(const char* chars) {
59+
struct Shift_States state = get_shift_states();
60+
61+
// release shift modifiers
62+
if (state.LeftShift == true) {
63+
SEND_STRING(SS_UP(X_LSFT));
64+
}
65+
if (state.RightShift == true) {
66+
SEND_STRING(SS_UP(X_RSFT));
67+
}
68+
69+
SEND_STRING(SS_TAP(X_APP));
70+
send_string(chars);
71+
72+
// return shift modifiers
73+
if (state.LeftShift == true) {
74+
SEND_STRING(SS_DOWN(X_LSFT));
75+
}
76+
if (state.RightShift == true) {
77+
SEND_STRING(SS_DOWN(X_RSFT));
78+
}
5579
}
5680

5781
/**
@@ -61,25 +85,25 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
6185
switch (keycode) {
6286
case KC_A_DIACRITIC: // å key
6387
if (record->event.pressed) {
64-
is_shift_pressed() ? print_unicode_char(UPPER_A_DIACRITIC) : print_unicode_char(LOWER_A_DIACRITIC);
88+
is_shift_pressed() ? compose_character(UPPER_A_DIACRITIC) : compose_character(LOWER_A_DIACRITIC);
6589
}
6690
break;
6791

6892
case KC_A_DIAERESIS: // ä key
6993
if (record->event.pressed) {
70-
is_shift_pressed() ? print_unicode_char(UPPER_A_DIAERESIS) : print_unicode_char(LOWER_A_DIAERESIS);
94+
is_shift_pressed() ? compose_character(UPPER_A_DIAERESIS) : compose_character(LOWER_A_DIAERESIS);
7195
}
7296
break;
7397

7498
case KC_O_DIAERESIS: // ö key
7599
if (record->event.pressed) {
76-
is_shift_pressed() ? print_unicode_char(UPPER_O_DIAERESIS) : print_unicode_char(LOWER_O_DIAERESIS);
100+
is_shift_pressed() ? compose_character(UPPER_O_DIAERESIS) : compose_character(LOWER_O_DIAERESIS);
77101
}
78102
break;
79103

80104
case KEY_EUR: // €
81105
if (record->event.pressed) {
82-
print_unicode_char(EURO_SIGN);
106+
compose_character(EURO_SIGN);
83107
}
84108
}
85109
return true;
@@ -112,4 +136,4 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
112136
TO(0), TO(0), TO(0), TO(0), TO(0), TO(0), TO(0), TO(0), TO(0), TO(0), TO(0), TO(0),
113137
TO(0), TO(0), TO(0), TO(0), TO(0), TO(0), RESET, RESET, TO(0), TO(0), TO(0), TO(0), TO(0), TO(0)
114138
)
115-
};
139+
};

0 commit comments

Comments
 (0)