Skip to content

Instantly share code, notes, and snippets.

@jamadagni
Last active December 25, 2018 12:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamadagni/afe3848e1e5f95343e8e84fb6c60f4e7 to your computer and use it in GitHub Desktop.
Save jamadagni/afe3848e1e5f95343e8e84fb6c60f4e7 to your computer and use it in GitHub Desktop.
// -*- mode: c++ -*-
// Copyright 2016 Keyboardio, inc. <jesse@keyboard.io>
// See "LICENSE" for license details
#include "Kaleidoscope.h"
#include "Kaleidoscope-NumPad.h"
#include "Kaleidoscope-MouseKeys.h"
#include "Kaleidoscope-Qukeys.h"
#include "Kaleidoscope-OneShot.h"
#include "Kaleidoscope-Macros.h"
#include "Kaleidoscope-StickyMouseButtons.h"
#include "Kaleidoscope-LEDControl.h"
#include "Kaleidoscope-LEDEffect-SolidColor.h"
#include "Kaleidoscope-LEDEffect-Rainbow-Plus.h"
#include "Kaleidoscope-LEDEffect-Breathe.h"
#include "Kaleidoscope-LED-ActiveModColor.h"
#include "Kaleidoscope-HostPowerManagement.h"
static kaleidoscope::LEDSolidColor LEDSolidYellow(130, 100, 0);
enum { L_TEXT, L_NUMPAD, L_NAV, L_FN, L_APPS };
enum {
// keyboard controls
M_LED_OFF, M_MOUSE_SPEED_CHANGE, M_STICKY_LMB,
// window controls
M_SHUTDOWN, M_WIN_TO_DESKTOP_MENU,
M_APPSWITCH, M_APPSWITCH_REV,
M_MV_WIN_TO_SCRN_1, M_MV_WIN_TO_SCRN_2,
// password
M_PWD_DEFAULT, M_PWD_REPO,
// navigation/function shortcuts
M_ZOOM_IN, M_ZOOM_OUT,
M_DEL_TO_HOME, M_DEL_TO_END,
M_WHEEL_LEFT, M_WHEEL_RIGHT, // for now at least for Inkscape, since Key_mouseScrollL, Key_mouseScrollR aren't working
// misc
M_ALIGN_HV, M_COPY_TAB_ADDR,
};
#define OSM_LEVEL3 OSM(RightAlt)
#define KEY_LEVEL4 LSHIFT(Key_RightAlt)
#define KEY_GO_TOP LCTRL(Key_Home)
#define KEY_GO_BTM LCTRL(Key_End)
#define KEY_GO_WORD_LT LCTRL(Key_LeftArrow)
#define KEY_GO_WORD_RT LCTRL(Key_RightArrow)
#define KEY_GO_VIEW_PREV LALT(Key_LeftArrow)
#define KEY_GO_VIEW_NEXT LALT(Key_RightArrow)
#define KEY_GO_VIEW_UP LALT(Key_UpArrow)
#define KEY_GO_VIEW_HOME LALT(Key_Home)
#define KEY_GO_TAB_LT LCTRL(Key_PageUp)
#define KEY_GO_TAB_RT LCTRL(Key_PageDown)
#define KEY_GO_DESKTOP_LT LCTRL(LSHIFT(Key_PageUp))
#define KEY_GO_DESKTOP_RT LCTRL(LSHIFT(Key_PageDown))
#define KEY_SCRL_UP LCTRL(Key_UpArrow)
#define KEY_SCRL_DN LCTRL(Key_DownArrow)
#define KEY_WINDOW_MAXIMIZE LGUI(Key_PageUp)
#define KEY_WINDOW_MINIMIZE LGUI(Key_PageDown)
#define KEY_WINDOW_OPACITY_UP LCTRL(LALT(Key_End))
#define KEY_WINDOW_OPACITY_DN LCTRL(LALT(Key_Home))
#define KEY_LINE_MOVE_UP LCTRL(LALT(Key_UpArrow))
#define KEY_LINE_MOVE_DN LCTRL(LALT(Key_DownArrow))
#define KEY_LINE_DUP_UP LCTRL(LSHIFT(Key_UpArrow))
#define KEY_LINE_DUP_DN LCTRL(LSHIFT(Key_DownArrow))
#define KEY_ALIGN_V LCTRL(LALT(Key_B))
#define KEY_ALIGN_H LCTRL(LALT(Key_D))
#define KEY_WIN_CLOSE LALT(Key_F4)
// only for Kate
#define KEY_REPLACE LALT(Key_R)
#define KEY_FIND_NEXT Key_F3
#define KEY_FIND_PREV LSHIFT(Key_F3)
#define ESC_ROW_COL 0, 6
#define F12_ROW_COL 0, 9
#define BACKTAB_ROW_COL 2, 6
#define CAPSLOCK_ROW_COL 2, 6 // it overlaps with the above but in a diff layer
/* This comment temporarily turns off astyle's indent enforcement
* so we can make the keymaps actually resemble the physical key layout better
*/
// *INDENT-OFF*
/*
Layer template:
[LAYER_ENUM_NAME] = KEYMAP_STACKED
(XXX, XXX, XXX, XXX, XXX, XXX, ___, // r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6,
XXX, XXX, XXX, XXX, XXX, XXX, ___, // r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6,
XXX, XXX, XXX, XXX, XXX, XXX, // r2c0, r2c1, r2c2, r2c3, r2c4, r2c5,
XXX, XXX, XXX, XXX, XXX, XXX, ___, // r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r2c6,
___, ___, ___, ___, // r0c7, r1c7, r2c7, r3c7,
___, // r3c6,
___, XXX, XXX, XXX, XXX, XXX, XXX, // r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15,
___, XXX, XXX, XXX, XXX, XXX, XXX, // r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15,
XXX, XXX, XXX, XXX, XXX, XXX, // r2c10, r2c11, r2c12, r2c13, r2c14, r2c15,
___, XXX, XXX, XXX, XXX, XXX, XXX, // r2c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15,
___, ___, ___, ___, // r3c8, r2c8, r1c8, r0c8,
___), // r3c9,
*/
KEYMAPS(
[L_TEXT] = KEYMAP_STACKED
(Key_Backtick, Key_1, Key_2, Key_3, Key_4, Key_5, Key_Escape,
Key_Backslash, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_Minus, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_LeftBracket, Key_Z, Key_X, Key_C, Key_V, Key_B, LSHIFT(Key_Tab),
OSM_LEVEL3, Key_Backspace, Key_Delete, OSL(L_APPS),
ShiftToLayer(L_NAV),
Key_F12, Key_6, Key_7, Key_8, Key_9, Key_0, Key_KeypadEnter,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
LCTRL(Key_LeftShift), Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_RightBracket,
OSM(LeftAlt), OSM(LeftShift), Key_Spacebar, OSM(LeftControl),
ShiftToLayer(L_FN)),
[L_NUMPAD] = KEYMAP_STACKED
// the r0c6 key of this layer (last of the first line after this comment) should be kept transparent
// so long as it is used as a qukey for temporarily accessing this layer
(XXX, XXX, XXX, LCTRL(Key_S), XXX, XXX, ___,
XXX, XXX, Key_Home, Key_UpArrow, Key_End, Key_PageUp, ___,
XXX, LCTRL(LSHIFT(Key_Z)), Key_LeftArrow, Key_DownArrow, Key_RightArrow, Key_PageDown,
XXX, LCTRL(Key_Z), LCTRL(Key_X), XXX, LCTRL(Key_V), LCTRL(Key_B), ___,
XXX, ___, ___, ___,
___,
XXX, Key_KeypadDivide, Key_Keypad7, Key_Keypad8, Key_Keypad9, XXX, XXX,
___, Key_KeypadMultiply, Key_Keypad4, Key_Keypad5, Key_Keypad6, XXX, Key_KeypadEquals,
Key_KeypadAdd, Key_Keypad1, Key_Keypad2, Key_Keypad3, Key_KeypadLeftParen, Key_KeypadRightParen,
UnlockLayer(L_NUMPAD), Key_KeypadSubtract, Key_Keypad0, XXX, Key_KeypadDot, XXX, XXX,
___, XXX, ___, ___,
___),
[L_NAV] = KEYMAP_STACKED
(XXX, Key_mouseUpL, Key_mouseUpR, M(M_MOUSE_SPEED_CHANGE), Key_mouseWarpNW, Key_mouseWarpNE, Key_mouseWarpEnd,
M(M_ZOOM_IN), Key_mouseDnL, Key_mouseDnR, Key_mouseUp, Key_mouseWarpSW, Key_mouseWarpSE, M(M_APPSWITCH),
M(M_ZOOM_OUT), XXX, Key_mouseL, Key_mouseDn, Key_mouseR, Key_mouseScrollUp,
XXX, XXX, XXX, M(M_WHEEL_LEFT), M(M_WHEEL_RIGHT), Key_mouseScrollDn, M(M_APPSWITCH_REV),
LCTRL(Key_LeftShift), XXX, XXX, LALT(Key_LeftShift),
___,
KEY_GO_DESKTOP_LT, KEY_GO_TOP, KEY_GO_VIEW_PREV, KEY_GO_VIEW_UP, KEY_GO_VIEW_NEXT, KEY_GO_VIEW_HOME, XXX,
KEY_GO_DESKTOP_RT, Key_PageUp, KEY_GO_WORD_LT, Key_UpArrow, KEY_GO_WORD_RT, KEY_SCRL_UP, KEY_GO_TAB_LT,
Key_PageDown, Key_LeftArrow, Key_DownArrow, Key_RightArrow, KEY_SCRL_DN, KEY_GO_TAB_RT,
Key_mouseBtnR, KEY_GO_BTM, Key_Home, Key_End, XXX, XXX, XXX,
___, ___, Key_mouseBtnL, ___,
XXX),
[L_FN] = KEYMAP_STACKED
(System_Sleep, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, M(M_WIN_TO_DESKTOP_MENU),
XXX, XXX, M(M_LED_OFF), Key_LEDEffectNext, XXX, XXX, Key_Insert,
M(M_SHUTDOWN), XXX, Consumer_Mute, Consumer_VolumeDecrement, Consumer_VolumeIncrement, Consumer_PlaySlashPause,
KEY_WIN_CLOSE, XXX, XXX, XXX, XXX, XXX, Key_CapsLock,
KEY_FIND_PREV, KEY_FIND_NEXT, KEY_REPLACE, M(M_COPY_TAB_ADDR),
XXX,
M(M_PWD_REPO), Key_F6, Key_F7, Key_F8, Key_F9, Key_F10, Key_F11,
M(M_PWD_DEFAULT), KEY_WINDOW_MAXIMIZE, KEY_LINE_DUP_UP, KEY_LINE_MOVE_UP, KEY_ALIGN_V, KEY_WINDOW_OPACITY_UP, M(M_MV_WIN_TO_SCRN_1),
KEY_WINDOW_MINIMIZE, KEY_LINE_DUP_DN, KEY_LINE_MOVE_DN, M(M_ALIGN_HV), KEY_WINDOW_OPACITY_DN, M(M_MV_WIN_TO_SCRN_2),
LockLayer(L_NUMPAD), XXX, M(M_DEL_TO_HOME), M(M_DEL_TO_END), KEY_ALIGN_H, XXX, Key_PrintScreen,
___, ___, M(M_STICKY_LMB), ___,
___),
#define M_S_(X) LSHIFT(Key_ ## X)
#define M_A_(X) LALT(Key_ ## X)
#define M_C_(X) LCTRL(Key_ ## X)
#define M_A_S_(X) LALT(LSHIFT(Key_ ## X))
#define M_C_S_(X) LCTRL(LSHIFT(Key_ ## X))
[L_APPS] = KEYMAP_STACKED
(XXX, M_C_(F13), M_C_(F14), M_C_(F15), M_C_(F16), M_C_(F17), XXX,
XXX, M_A_(F13), M_A_(F14), M_A_(F15), M_A_(F16), M_A_(F17), XXX,
XXX, Key_F13 , Key_F14 , Key_F15 , Key_F16 , Key_F17 ,
XXX, XXX , XXX , M_C_(F18), M_A_(F18), Key_F18 , XXX,
XXX, XXX, XXX, XXX,
XXX,
XXX, M_C_S_(F13), M_C_S_(F14), M_C_S_(F15), M_C_S_(F16), M_C_S_(F17), XXX,
XXX, M_A_S_(F13), M_A_S_(F14), M_A_S_(F15), M_A_S_(F16), M_A_S_(F17), XXX,
M_S_(F13), M_S_(F14), M_S_(F15), M_S_(F16), M_S_(F17), XXX,
XXX, M_S_(F18), M_A_S_(F18), M_C_S_(F18), XXX , XXX , XXX,
XXX, XXX, XXX, XXX,
XXX),
) // KEYMAPS
/* Re-enable astyle's indent enforcement */
// *INDENT-ON*
const macro_t *appSwitch(uint8_t macroIndex, uint8_t keyState)
{
static const macro_t *const macroHoldAltTapTab = MACRO(Dc(LeftAlt), Tc(Tab));
static const macro_t *const macroHoldAltTapBackTab = MACRO(Dc(LeftAlt), Dc(LeftShift), Tc(Tab), Uc(LeftShift));
static const macro_t *const macroHoldAlt = MACRO(Dc(LeftAlt));
static const macro_t *const macroReleaseAlt = MACRO(Uc(LeftAlt));
static uint16_t timer;
const macro_t * macroSwitch = (macroIndex == M_APPSWITCH) ?
macroHoldAltTapTab : macroHoldAltTapBackTab;
uint16_t now = Kaleidoscope.millisAtCycleStart();
if (keyToggledOn(keyState))
{
timer = now;
return macroSwitch;
}
else if (keyIsPressed(keyState))
{
#define MILLISECONDS_TO_MOVE_TO_NEXT_APP 1000
if (now - timer > MILLISECONDS_TO_MOVE_TO_NEXT_APP)
{
timer = now;
return macroSwitch;
}
}
else if (keyToggledOff(keyState))
{
return macroReleaseAlt;
}
return macroHoldAlt;
}
#define MOUSE_SPEED_FAST 15
#define MOUSE_SPEED_SLOW 5
#define WHEEL_SPEED_FAST 5
#define WHEEL_SPEED_SLOW 1
#define PRESS(X) handleKeyswitchEvent(X, Macros.row, Macros.col, IS_PRESSED)
const macro_t * macroAction(uint8_t macroIndex, uint8_t keyState)
{
switch (macroIndex)
{
// keyboard controls
case M_LED_OFF:
if (keyToggledOn(keyState))
LEDOff.activate();
break;
case M_MOUSE_SPEED_CHANGE:
if (keyToggledOn(keyState))
{
MouseKeys.speed = (MouseKeys.speed == MOUSE_SPEED_FAST) ? MOUSE_SPEED_SLOW : MOUSE_SPEED_FAST;
MouseKeys.wheelSpeed = (MouseKeys.wheelSpeed == WHEEL_SPEED_FAST) ? WHEEL_SPEED_SLOW : WHEEL_SPEED_FAST;
}
break;
case M_STICKY_LMB:
if (keyToggledOn(keyState))
StickyMouseButtons.toggleSticky(STICKY_MOUSE_BUTTON_LEFT);
break;
// window controls
case M_SHUTDOWN:
return MACRODOWN(I(25), D(LeftAlt), T(F1), U(LeftAlt), T(LeftArrow), T(UpArrow), T(Enter));
case M_WIN_TO_DESKTOP_MENU:
return MACRODOWN(I(25), D(LeftAlt), T(F3), U(LeftAlt), T(DownArrow), T(RightArrow));
case M_APPSWITCH:
case M_APPSWITCH_REV:
return appSwitch(macroIndex, keyState);
break;
case M_MV_WIN_TO_SCRN_1:
return MACRODOWN(I(25), D(LeftAlt), T(F3), U(LeftAlt), T(DownArrow), T(DownArrow), T(RightArrow), T(Enter));
case M_MV_WIN_TO_SCRN_2:
return MACRODOWN(I(25), D(LeftAlt), T(F3), U(LeftAlt), T(DownArrow), T(DownArrow), T(RightArrow), T(DownArrow), T(Enter));
// mouse/cursor related
case M_ZOOM_IN:
return MACRODOWN(D(LeftControl), T(mouseScrollUp), U(LeftControl));
case M_ZOOM_OUT:
return MACRODOWN(D(LeftControl), T(mouseScrollDn), U(LeftControl));
case M_DEL_TO_HOME:
return MACRODOWN(D(LeftShift), T(Home), U(LeftShift), T(Delete));
case M_DEL_TO_END:
return MACRODOWN(D(LeftShift), T(End), U(LeftShift), T(Delete));
case M_WHEEL_LEFT:
// if (keyIsPressed(keyState)) // note “is pressed”
return MACRODOWN(D(LeftShift), T(mouseScrollUp), U(LeftShift)); // currently doesn't work as “is pressed”
// {
// PRESS(Key_LeftShift); PRESS(Key_mouseScrollUp);
// }
break;
case M_WHEEL_RIGHT:
// if (keyIsPressed(keyState)) // note “is pressed”
return MACRODOWN(D(LeftShift), T(mouseScrollDn), U(LeftShift)); // currently doesn't work as “is pressed”
// {
// PRESS(Key_LeftShift); PRESS(Key_mouseScrollDn);
// }
break;
// misc
case M_ALIGN_HV:
return MACRODOWN(D(LeftControl), D(LeftAlt), T(B), U(LeftControl), U(LeftAlt), // ctrl-alt-V
D(LeftControl), D(LeftAlt), T(D), U(LeftControl), U(LeftAlt) // ctrl-alt-H
);
case M_COPY_TAB_ADDR:
return MACRODOWN(I(25), // without this it doesn't copy as it the actual selection seems to need time
D(LeftAlt), T(W), U(LeftAlt), // alt-D
D(LeftControl), T(V), U(LeftControl)); // ctrl-C
}
return MACRO_NONE;
}
namespace kaleidoscope
{
class MyLEDCapsLock : public kaleidoscope::Plugin
{
public:
MyLEDCapsLock() {}
EventHandlerResult beforeReportingState()
{
bool capsState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_CAPS_LOCK);
if (capsState && Layer.top() == L_TEXT)
::LEDControl.setCrgbAt(CAPSLOCK_ROW_COL, breath_compute(lock_hue));
else
::LEDControl.refreshAt(CAPSLOCK_ROW_COL);
return EventHandlerResult::OK;
}
uint8_t lock_hue;
};
}
kaleidoscope::MyLEDCapsLock MyLEDCapsLock;
KALEIDOSCOPE_INIT_PLUGINS
(
NumPad,
MouseKeys,
Qukeys,
OneShot,
Macros,
StickyMouseButtons,
LEDControl,
LEDOff,
LEDSolidYellow,
LEDBreatheEffect,
LEDRainbow,
LEDRainbowWave,
LEDRainbowCheckerboardSubtle,
LEDRainbowCheckerboard,
ActiveModColorEffect,
MyLEDCapsLock,
HostPowerManagement
);
void setup()
{
Kaleidoscope.setup();
MouseKeys.speed = MOUSE_SPEED_FAST;
MouseKeys.wheelSpeed = WHEEL_SPEED_FAST;
QUKEYS(
kaleidoscope::Qukey(L_TEXT, ESC_ROW_COL, ShiftToLayer(L_NUMPAD)), // LED key
kaleidoscope::Qukey(L_TEXT, F12_ROW_COL, Key_PcApplication), // Any key
kaleidoscope::Qukey(L_TEXT, BACKTAB_ROW_COL, KEY_LEVEL4), // Esc key
)
OneShot.time_out = 1000; // milliseconds
OneShot.double_tap_time_out = 500;
OneShot.disableStickabilityForModifiers();
OneShot.disableStickabilityForLayers();
LEDRainbow.hue_update_interval = 96;
// One breathe cycle is 4096 ms. One hue cycle has to move through 256 values
// every hue_update_interval ms. It will take 256 × hue_update_interval ms to complete.
// To have it complete on par with ‘n’ breathe cycles, one should set
// n × 4096 = 256 × hue_update_interval ⟹ hue_update_interval = n × 16.
LEDRainbow.saturation = 192;
// LEDRainbow.breathe = true;
LEDRainbowWave.hue_steps = -1;
// LEDRainbowWave.breathe = true;
LEDBreatheEffect.hue = 33; // Yellow to match solid colour above
ActiveModColorEffect.sticky_color = CRGB(0, 255, 255); // Cyan
NumPad.numPadLayer = L_NUMPAD;
NumPad.color = CRGB(0, 87, 174); // Oxygen Sky Blue 4
NumPad.lock_hue = 85; // Green
MyLEDCapsLock.lock_hue = 85; // Green
LEDSolidYellow.activate();
}
//
// REST OF THE FILE ARE INTERNALS YOU DON'T NEED TO TOUCH
//
void loop()
{
Kaleidoscope.loop();
}
void toggleLedsOnSuspendResume(kaleidoscope::HostPowerManagement::Event event)
{
switch (event)
{
case kaleidoscope::HostPowerManagement::Suspend:
LEDControl.paused = true;
LEDControl.set_all_leds_to({0, 0, 0});
LEDControl.syncLeds();
break;
case kaleidoscope::HostPowerManagement::Resume:
LEDControl.paused = false;
LEDControl.refreshAll();
break;
case kaleidoscope::HostPowerManagement::Sleep:
break;
}
}
void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event event)
{
toggleLedsOnSuspendResume(event);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment