Vitepress conversion of docs. (#23795)
parent
395766657f
commit
6ef9717288
|
@ -7,20 +7,26 @@ on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
- vitepress
|
||||||
paths:
|
paths:
|
||||||
|
- 'builddefs/docsgen/**'
|
||||||
- 'tmk_core/**'
|
- 'tmk_core/**'
|
||||||
- 'quantum/**'
|
- 'quantum/**'
|
||||||
- 'platforms/**'
|
- 'platforms/**'
|
||||||
- 'docs/**'
|
- 'docs/**'
|
||||||
- '.github/workflows/docs.yml'
|
- '.github/workflows/docs.yml'
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
generate:
|
generate:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/qmk/qmk_cli
|
container: ghcr.io/qmk/qmk_cli
|
||||||
|
|
||||||
# protect against those who develop with their fork on master
|
# protect against those who develop with their fork on master
|
||||||
if: github.repository == 'qmk/qmk_firmware'
|
if: github.repository == 'qmk/qmk_firmware' || (github.repository == 'tzarc/qmk_firmware' && github.ref == 'refs/heads/vitepress')
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
@ -29,18 +35,51 @@ jobs:
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
apt-get update && apt-get install -y rsync nodejs npm doxygen
|
apt-get update && apt-get install -y rsync doxygen curl
|
||||||
|
# install nvm
|
||||||
|
touch $HOME/.bashrc
|
||||||
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||||
|
|
||||||
|
- name: Install node
|
||||||
|
run: |
|
||||||
|
source $HOME/.bashrc
|
||||||
|
nvm install 20
|
||||||
|
nvm use 20
|
||||||
|
corepack enable
|
||||||
npm install -g moxygen
|
npm install -g moxygen
|
||||||
|
|
||||||
- name: Build docs
|
- name: Build docs
|
||||||
run: |
|
run: |
|
||||||
|
source $HOME/.bashrc
|
||||||
|
nvm use 20
|
||||||
qmk --verbose generate-docs
|
qmk --verbose generate-docs
|
||||||
|
touch '.build/docs/.nojekyll'
|
||||||
|
|
||||||
|
- name: Set CNAME
|
||||||
|
if: github.repository == 'qmk/qmk_firmware'
|
||||||
|
run: |
|
||||||
|
# Override target CNAME
|
||||||
|
echo 'docs.qmk.fm' > .build/docs/CNAME
|
||||||
|
|
||||||
|
- name: Override CNAME
|
||||||
|
if: github.repository == 'tzarc/qmk_firmware'
|
||||||
|
run: |
|
||||||
|
# Temporarily override target CNAME during development
|
||||||
|
echo 'vitepress.qmk.fm' > .build/docs/CNAME
|
||||||
|
|
||||||
- name: Deploy
|
- name: Deploy
|
||||||
|
if: github.repository == 'qmk/qmk_firmware'
|
||||||
uses: JamesIves/github-pages-deploy-action@v4.6.1
|
uses: JamesIves/github-pages-deploy-action@v4.6.1
|
||||||
with:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
BASE_BRANCH: master
|
branch: gh-pages
|
||||||
BRANCH: gh-pages
|
folder: .build/docs
|
||||||
FOLDER: .build/docs
|
git-config-name: QMK Bot
|
||||||
GIT_CONFIG_EMAIL: hello@qmk.fm
|
git-config-email: hello@qmk.fm
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
if: github.repository == 'tzarc/qmk_firmware'
|
||||||
|
uses: JamesIves/github-pages-deploy-action@v4.6.1
|
||||||
|
with:
|
||||||
|
branch: gh-pages
|
||||||
|
folder: .build/docs
|
||||||
|
|
70
Doxyfile
70
Doxyfile
|
@ -21,7 +21,7 @@ DOXYFILE_ENCODING = UTF-8
|
||||||
PROJECT_NAME = "QMK Firmware"
|
PROJECT_NAME = "QMK Firmware"
|
||||||
PROJECT_NUMBER = https://github.com/qmk/qmk_firmware
|
PROJECT_NUMBER = https://github.com/qmk/qmk_firmware
|
||||||
PROJECT_BRIEF = "Keyboard controller firmware for Atmel AVR and ARM USB families"
|
PROJECT_BRIEF = "Keyboard controller firmware for Atmel AVR and ARM USB families"
|
||||||
OUTPUT_DIRECTORY = .build/doxygen
|
OUTPUT_DIRECTORY = .build/docs/static/doxygen
|
||||||
ALLOW_UNICODE_NAMES = NO
|
ALLOW_UNICODE_NAMES = NO
|
||||||
OUTPUT_LANGUAGE = English
|
OUTPUT_LANGUAGE = English
|
||||||
BRIEF_MEMBER_DESC = YES
|
BRIEF_MEMBER_DESC = YES
|
||||||
|
@ -40,8 +40,8 @@ ABBREVIATE_BRIEF = "The $name class" \
|
||||||
ALWAYS_DETAILED_SEC = NO
|
ALWAYS_DETAILED_SEC = NO
|
||||||
INLINE_INHERITED_MEMB = NO
|
INLINE_INHERITED_MEMB = NO
|
||||||
FULL_PATH_NAMES = YES
|
FULL_PATH_NAMES = YES
|
||||||
STRIP_FROM_PATH =
|
STRIP_FROM_PATH =
|
||||||
STRIP_FROM_INC_PATH =
|
STRIP_FROM_INC_PATH =
|
||||||
SHORT_NAMES = NO
|
SHORT_NAMES = NO
|
||||||
JAVADOC_AUTOBRIEF = NO
|
JAVADOC_AUTOBRIEF = NO
|
||||||
QT_AUTOBRIEF = NO
|
QT_AUTOBRIEF = NO
|
||||||
|
@ -49,13 +49,13 @@ MULTILINE_CPP_IS_BRIEF = NO
|
||||||
INHERIT_DOCS = YES
|
INHERIT_DOCS = YES
|
||||||
SEPARATE_MEMBER_PAGES = NO
|
SEPARATE_MEMBER_PAGES = NO
|
||||||
TAB_SIZE = 4
|
TAB_SIZE = 4
|
||||||
ALIASES =
|
ALIASES =
|
||||||
TCL_SUBST =
|
TCL_SUBST =
|
||||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||||
OPTIMIZE_OUTPUT_JAVA = NO
|
OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
OPTIMIZE_FOR_FORTRAN = NO
|
OPTIMIZE_FOR_FORTRAN = NO
|
||||||
OPTIMIZE_OUTPUT_VHDL = NO
|
OPTIMIZE_OUTPUT_VHDL = NO
|
||||||
EXTENSION_MAPPING =
|
EXTENSION_MAPPING =
|
||||||
MARKDOWN_SUPPORT = YES
|
MARKDOWN_SUPPORT = YES
|
||||||
TOC_INCLUDE_HEADINGS = 2
|
TOC_INCLUDE_HEADINGS = 2
|
||||||
AUTOLINK_SUPPORT = YES
|
AUTOLINK_SUPPORT = YES
|
||||||
|
@ -104,14 +104,14 @@ GENERATE_TODOLIST = YES
|
||||||
GENERATE_TESTLIST = YES
|
GENERATE_TESTLIST = YES
|
||||||
GENERATE_BUGLIST = YES
|
GENERATE_BUGLIST = YES
|
||||||
GENERATE_DEPRECATEDLIST= YES
|
GENERATE_DEPRECATEDLIST= YES
|
||||||
ENABLED_SECTIONS =
|
ENABLED_SECTIONS =
|
||||||
MAX_INITIALIZER_LINES = 30
|
MAX_INITIALIZER_LINES = 30
|
||||||
SHOW_USED_FILES = YES
|
SHOW_USED_FILES = YES
|
||||||
SHOW_FILES = YES
|
SHOW_FILES = YES
|
||||||
SHOW_NAMESPACES = YES
|
SHOW_NAMESPACES = YES
|
||||||
FILE_VERSION_FILTER =
|
FILE_VERSION_FILTER =
|
||||||
LAYOUT_FILE =
|
LAYOUT_FILE =
|
||||||
CITE_BIB_FILES =
|
CITE_BIB_FILES =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to warning and progress messages
|
# Configuration options related to warning and progress messages
|
||||||
|
@ -124,7 +124,7 @@ WARN_IF_DOC_ERROR = YES
|
||||||
WARN_NO_PARAMDOC = NO
|
WARN_NO_PARAMDOC = NO
|
||||||
WARN_AS_ERROR = NO
|
WARN_AS_ERROR = NO
|
||||||
WARN_FORMAT = "$file:$line: $text"
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
WARN_LOGFILE =
|
WARN_LOGFILE =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the input files
|
# Configuration options related to the input files
|
||||||
|
@ -143,19 +143,19 @@ FILE_PATTERNS = *.c \
|
||||||
*.hpp \
|
*.hpp \
|
||||||
*.h++
|
*.h++
|
||||||
RECURSIVE = YES
|
RECURSIVE = YES
|
||||||
EXCLUDE =
|
EXCLUDE =
|
||||||
EXCLUDE_SYMLINKS = NO
|
EXCLUDE_SYMLINKS = NO
|
||||||
EXCLUDE_PATTERNS = */protocol/arm_atsam/*
|
EXCLUDE_PATTERNS = */protocol/arm_atsam/*
|
||||||
EXCLUDE_SYMBOLS =
|
EXCLUDE_SYMBOLS =
|
||||||
EXAMPLE_PATH =
|
EXAMPLE_PATH =
|
||||||
EXAMPLE_PATTERNS = *
|
EXAMPLE_PATTERNS = *
|
||||||
EXAMPLE_RECURSIVE = NO
|
EXAMPLE_RECURSIVE = NO
|
||||||
IMAGE_PATH =
|
IMAGE_PATH =
|
||||||
INPUT_FILTER =
|
INPUT_FILTER =
|
||||||
FILTER_PATTERNS =
|
FILTER_PATTERNS =
|
||||||
FILTER_SOURCE_FILES = NO
|
FILTER_SOURCE_FILES = NO
|
||||||
FILTER_SOURCE_PATTERNS =
|
FILTER_SOURCE_PATTERNS =
|
||||||
USE_MDFILE_AS_MAINPAGE =
|
USE_MDFILE_AS_MAINPAGE =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to source browsing
|
# Configuration options related to source browsing
|
||||||
|
@ -177,7 +177,7 @@ VERBATIM_HEADERS = YES
|
||||||
|
|
||||||
ALPHABETICAL_INDEX = YES
|
ALPHABETICAL_INDEX = YES
|
||||||
COLS_IN_ALPHA_INDEX = 5
|
COLS_IN_ALPHA_INDEX = 5
|
||||||
IGNORE_PREFIX =
|
IGNORE_PREFIX =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to disabled outputs
|
# Configuration options related to disabled outputs
|
||||||
|
@ -207,18 +207,18 @@ ENABLE_PREPROCESSING = YES
|
||||||
MACRO_EXPANSION = NO
|
MACRO_EXPANSION = NO
|
||||||
EXPAND_ONLY_PREDEF = NO
|
EXPAND_ONLY_PREDEF = NO
|
||||||
SEARCH_INCLUDES = YES
|
SEARCH_INCLUDES = YES
|
||||||
INCLUDE_PATH =
|
INCLUDE_PATH =
|
||||||
INCLUDE_FILE_PATTERNS =
|
INCLUDE_FILE_PATTERNS =
|
||||||
PREDEFINED = __DOXYGEN__ PROGMEM
|
PREDEFINED = __DOXYGEN__ PROGMEM
|
||||||
EXPAND_AS_DEFINED =
|
EXPAND_AS_DEFINED =
|
||||||
SKIP_FUNCTION_MACROS = YES
|
SKIP_FUNCTION_MACROS = YES
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to external references
|
# Configuration options related to external references
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
TAGFILES =
|
TAGFILES =
|
||||||
GENERATE_TAGFILE =
|
GENERATE_TAGFILE =
|
||||||
ALLEXTERNALS = NO
|
ALLEXTERNALS = NO
|
||||||
EXTERNAL_GROUPS = YES
|
EXTERNAL_GROUPS = YES
|
||||||
EXTERNAL_PAGES = YES
|
EXTERNAL_PAGES = YES
|
||||||
|
@ -229,14 +229,14 @@ PERL_PATH = /usr/bin/perl
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
CLASS_DIAGRAMS = YES
|
CLASS_DIAGRAMS = YES
|
||||||
MSCGEN_PATH =
|
MSCGEN_PATH =
|
||||||
DIA_PATH =
|
DIA_PATH =
|
||||||
HIDE_UNDOC_RELATIONS = YES
|
HIDE_UNDOC_RELATIONS = YES
|
||||||
HAVE_DOT = NO
|
HAVE_DOT = NO
|
||||||
DOT_NUM_THREADS = 0
|
DOT_NUM_THREADS = 0
|
||||||
DOT_FONTNAME = Helvetica
|
DOT_FONTNAME = Helvetica
|
||||||
DOT_FONTSIZE = 10
|
DOT_FONTSIZE = 10
|
||||||
DOT_FONTPATH =
|
DOT_FONTPATH =
|
||||||
CLASS_GRAPH = YES
|
CLASS_GRAPH = YES
|
||||||
COLLABORATION_GRAPH = YES
|
COLLABORATION_GRAPH = YES
|
||||||
GROUP_GRAPHS = YES
|
GROUP_GRAPHS = YES
|
||||||
|
@ -251,13 +251,13 @@ GRAPHICAL_HIERARCHY = YES
|
||||||
DIRECTORY_GRAPH = YES
|
DIRECTORY_GRAPH = YES
|
||||||
DOT_IMAGE_FORMAT = png
|
DOT_IMAGE_FORMAT = png
|
||||||
INTERACTIVE_SVG = NO
|
INTERACTIVE_SVG = NO
|
||||||
DOT_PATH =
|
DOT_PATH =
|
||||||
DOTFILE_DIRS =
|
DOTFILE_DIRS =
|
||||||
MSCFILE_DIRS =
|
MSCFILE_DIRS =
|
||||||
DIAFILE_DIRS =
|
DIAFILE_DIRS =
|
||||||
PLANTUML_JAR_PATH =
|
PLANTUML_JAR_PATH =
|
||||||
PLANTUML_CFG_FILE =
|
PLANTUML_CFG_FILE =
|
||||||
PLANTUML_INCLUDE_PATH =
|
PLANTUML_INCLUDE_PATH =
|
||||||
DOT_GRAPH_MAX_NODES = 50
|
DOT_GRAPH_MAX_NODES = 50
|
||||||
MAX_DOT_GRAPH_DEPTH = 0
|
MAX_DOT_GRAPH_DEPTH = 0
|
||||||
DOT_TRANSPARENT = NO
|
DOT_TRANSPARENT = NO
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
node_modules
|
||||||
|
.vitepress/cache
|
||||||
|
.vitepress/.temp
|
||||||
|
.vitepress/dist
|
||||||
|
docs
|
|
@ -0,0 +1,51 @@
|
||||||
|
import { defineConfig } from "vitepress";
|
||||||
|
import { tabsMarkdownPlugin } from "vitepress-plugin-tabs";
|
||||||
|
import sidebar from "../../../docs/_sidebar.json";
|
||||||
|
|
||||||
|
// https://vitepress.dev/reference/site-config
|
||||||
|
export default defineConfig(({ mode }) => {
|
||||||
|
const prod = mode === "production";
|
||||||
|
return {
|
||||||
|
title: "QMK Firmware",
|
||||||
|
description: "Documentation for QMK Firmware",
|
||||||
|
|
||||||
|
srcDir: prod ? "docs" : "../../docs",
|
||||||
|
outDir: "../../.build/docs",
|
||||||
|
cleanUrls: true,
|
||||||
|
|
||||||
|
markdown: {
|
||||||
|
config(md) {
|
||||||
|
md.use(tabsMarkdownPlugin);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
vite: {
|
||||||
|
resolve: {
|
||||||
|
preserveSymlinks: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
themeConfig: {
|
||||||
|
// https://vitepress.dev/reference/default-theme-config
|
||||||
|
logo: {
|
||||||
|
light: "/badge-community-light.svg",
|
||||||
|
dark: "/badge-community-dark.svg",
|
||||||
|
},
|
||||||
|
siteTitle: false,
|
||||||
|
|
||||||
|
nav: [{ text: "Home", link: "./" }],
|
||||||
|
|
||||||
|
search: {
|
||||||
|
provider: "local",
|
||||||
|
},
|
||||||
|
|
||||||
|
sidebar: sidebar,
|
||||||
|
|
||||||
|
socialLinks: [
|
||||||
|
{ icon: { svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50px" height="50px"><path d="M 29 3 C 28.0625 3 27.164063 3.382813 26.5 4 C 25.835938 4.617188 25.363281 5.433594 25 6.40625 C 24.355469 8.140625 24.085938 10.394531 24.03125 13.03125 C 19.234375 13.179688 14.820313 14.421875 11.28125 16.46875 C 10.214844 15.46875 8.855469 14.96875 7.5 14.96875 C 6.089844 14.96875 4.675781 15.511719 3.59375 16.59375 C 1.425781 18.761719 1.425781 22.238281 3.59375 24.40625 L 3.84375 24.65625 C 3.3125 26.035156 3 27.488281 3 29 C 3 33.527344 5.566406 37.585938 9.5625 40.4375 C 13.558594 43.289063 19.007813 45 25 45 C 30.992188 45 36.441406 43.289063 40.4375 40.4375 C 44.433594 37.585938 47 33.527344 47 29 C 47 27.488281 46.6875 26.035156 46.15625 24.65625 L 46.40625 24.40625 C 48.574219 22.238281 48.574219 18.761719 46.40625 16.59375 C 45.324219 15.511719 43.910156 14.96875 42.5 14.96875 C 41.144531 14.96875 39.785156 15.46875 38.71875 16.46875 C 35.195313 14.433594 30.800781 13.191406 26.03125 13.03125 C 26.09375 10.546875 26.363281 8.46875 26.875 7.09375 C 27.164063 6.316406 27.527344 5.757813 27.875 5.4375 C 28.222656 5.117188 28.539063 5 29 5 C 29.460938 5 29.683594 5.125 30.03125 5.40625 C 30.378906 5.6875 30.785156 6.148438 31.3125 6.6875 C 32.253906 7.652344 33.695313 8.714844 36.09375 8.9375 C 36.539063 11.238281 38.574219 13 41 13 C 43.75 13 46 10.75 46 8 C 46 5.25 43.75 3 41 3 C 38.605469 3 36.574219 4.710938 36.09375 6.96875 C 34.3125 6.796875 33.527344 6.109375 32.75 5.3125 C 32.300781 4.851563 31.886719 4.3125 31.3125 3.84375 C 30.738281 3.375 29.9375 3 29 3 Z M 41 5 C 42.667969 5 44 6.332031 44 8 C 44 9.667969 42.667969 11 41 11 C 39.332031 11 38 9.667969 38 8 C 38 6.332031 39.332031 5 41 5 Z M 25 15 C 30.609375 15 35.675781 16.613281 39.28125 19.1875 C 42.886719 21.761719 45 25.226563 45 29 C 45 32.773438 42.886719 36.238281 39.28125 38.8125 C 35.675781 41.386719 30.609375 43 25 43 C 19.390625 43 14.324219 41.386719 10.71875 38.8125 C 7.113281 36.238281 5 32.773438 5 29 C 5 25.226563 7.113281 21.761719 10.71875 19.1875 C 14.324219 16.613281 19.390625 15 25 15 Z M 7.5 16.9375 C 8.203125 16.9375 8.914063 17.148438 9.53125 17.59375 C 7.527344 19.03125 5.886719 20.769531 4.75 22.71875 C 3.582031 21.296875 3.660156 19.339844 5 18 C 5.714844 17.285156 6.609375 16.9375 7.5 16.9375 Z M 42.5 16.9375 C 43.390625 16.9375 44.285156 17.285156 45 18 C 46.339844 19.339844 46.417969 21.296875 45.25 22.71875 C 44.113281 20.769531 42.472656 19.03125 40.46875 17.59375 C 41.085938 17.148438 41.796875 16.9375 42.5 16.9375 Z M 17 22 C 14.800781 22 13 23.800781 13 26 C 13 28.199219 14.800781 30 17 30 C 19.199219 30 21 28.199219 21 26 C 21 23.800781 19.199219 22 17 22 Z M 33 22 C 30.800781 22 29 23.800781 29 26 C 29 28.199219 30.800781 30 33 30 C 35.199219 30 37 28.199219 37 26 C 37 23.800781 35.199219 22 33 22 Z M 17 24 C 18.117188 24 19 24.882813 19 26 C 19 27.117188 18.117188 28 17 28 C 15.882813 28 15 27.117188 15 26 C 15 24.882813 15.882813 24 17 24 Z M 33 24 C 34.117188 24 35 24.882813 35 26 C 35 27.117188 34.117188 28 33 28 C 31.882813 28 31 27.117188 31 26 C 31 24.882813 31.882813 24 33 24 Z M 34.15625 33.84375 C 34.101563 33.851563 34.050781 33.859375 34 33.875 C 33.683594 33.9375 33.417969 34.144531 33.28125 34.4375 C 33.28125 34.4375 32.757813 35.164063 31.4375 36 C 30.117188 36.835938 28.058594 37.6875 25 37.6875 C 21.941406 37.6875 19.882813 36.835938 18.5625 36 C 17.242188 35.164063 16.71875 34.4375 16.71875 34.4375 C 16.492188 34.082031 16.066406 33.90625 15.65625 34 C 15.332031 34.082031 15.070313 34.316406 14.957031 34.632813 C 14.84375 34.945313 14.894531 35.292969 15.09375 35.5625 C 15.09375 35.5625 15.863281 36.671875 17.46875 37.6875 C 19.074219 38.703125 21.558594 39.6875 25 39.6875 C 28.441406 39.6875 30.925781 38.703125 32.53125 37.6875 C 34.136719 36.671875 34.90625 35.5625 34.90625 35.5625 C 35.207031 35.273438 35.296875 34.824219 35.128906 34.441406 C 34.960938 34.058594 34.574219 33.820313 34.15625 33.84375 Z"/></svg>' }, link: "https://reddit.com/r/olkb" },
|
||||||
|
{ icon: "discord", link: "https://discord.gg/qmk" },
|
||||||
|
{ icon: "github", link: "https://github.com/qmk/qmk_firmware" },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
|
@ -0,0 +1,18 @@
|
||||||
|
<script setup>
|
||||||
|
import DefaultTheme from 'vitepress/theme'
|
||||||
|
import { useRouter } from 'vitepress'
|
||||||
|
import { onBeforeMount } from 'vue';
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
if (window.location.href.includes('/#/')) {
|
||||||
|
const newUrl = window.location.href.replace(/\/#\//, '/').replace(/\?id=/, '#');
|
||||||
|
window.history.replaceState({}, '', newUrl);
|
||||||
|
await router.go(newUrl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DefaultTheme.Layout/>
|
||||||
|
</template>
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* Override <kbd> as vitepress doesn't put them with borders */
|
||||||
|
kbd {
|
||||||
|
border: 1px solid var(--vp-c-text-1);
|
||||||
|
border-radius: 0.6em;
|
||||||
|
margin: 0.2em;
|
||||||
|
padding: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--vp-nav-logo-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
padding-bottom: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPNavBarTitle.has-sidebar .title {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import type { Theme } from 'vitepress'
|
||||||
|
import DefaultTheme from 'vitepress/theme'
|
||||||
|
import { enhanceAppWithTabs } from 'vitepress-plugin-tabs/client'
|
||||||
|
import QMKLayout from './QMKLayout.vue'
|
||||||
|
import './custom.css'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: DefaultTheme,
|
||||||
|
Layout: QMKLayout,
|
||||||
|
enhanceApp({ app }) {
|
||||||
|
enhanceAppWithTabs(app)
|
||||||
|
}
|
||||||
|
} satisfies Theme
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
|
||||||
|
yarn install
|
||||||
|
[[ -e docs ]] || ln -sf ../../docs docs
|
||||||
|
DEBUG='vitepress:*,vite:*' yarn run docs:build
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"license": "GPL-2.0-or-later",
|
||||||
|
"devDependencies": {
|
||||||
|
"vite": "^5.2.10",
|
||||||
|
"vitepress": "^1.1.0",
|
||||||
|
"vitepress-plugin-tabs": "^0.5.0",
|
||||||
|
"vue": "^3.4.24"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"docs:dev": "vitepress dev --host 0.0.0.0",
|
||||||
|
"docs:build": "vitepress build",
|
||||||
|
"docs:preview": "vitepress preview --host 0.0.0.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
|
||||||
|
yarn install
|
||||||
|
DEBUG='vitepress:*,vite:*' yarn run docs:dev
|
|
@ -0,0 +1,797 @@
|
||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@algolia/autocomplete-core@1.9.3":
|
||||||
|
version "1.9.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz#1d56482a768c33aae0868c8533049e02e8961be7"
|
||||||
|
integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/autocomplete-plugin-algolia-insights" "1.9.3"
|
||||||
|
"@algolia/autocomplete-shared" "1.9.3"
|
||||||
|
|
||||||
|
"@algolia/autocomplete-plugin-algolia-insights@1.9.3":
|
||||||
|
version "1.9.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz#9b7f8641052c8ead6d66c1623d444cbe19dde587"
|
||||||
|
integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/autocomplete-shared" "1.9.3"
|
||||||
|
|
||||||
|
"@algolia/autocomplete-preset-algolia@1.9.3":
|
||||||
|
version "1.9.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz#64cca4a4304cfcad2cf730e83067e0c1b2f485da"
|
||||||
|
integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/autocomplete-shared" "1.9.3"
|
||||||
|
|
||||||
|
"@algolia/autocomplete-shared@1.9.3":
|
||||||
|
version "1.9.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz#2e22e830d36f0a9cf2c0ccd3c7f6d59435b77dfa"
|
||||||
|
integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==
|
||||||
|
|
||||||
|
"@algolia/cache-browser-local-storage@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.23.3.tgz#0cc26b96085e1115dac5fcb9d826651ba57faabc"
|
||||||
|
integrity sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/cache-common" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/cache-common@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.23.3.tgz#3bec79092d512a96c9bfbdeec7cff4ad36367166"
|
||||||
|
integrity sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A==
|
||||||
|
|
||||||
|
"@algolia/cache-in-memory@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.23.3.tgz#3945f87cd21ffa2bec23890c85305b6b11192423"
|
||||||
|
integrity sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/cache-common" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/client-account@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.23.3.tgz#8751bbf636e6741c95e7c778488dee3ee430ac6f"
|
||||||
|
integrity sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/client-common" "4.23.3"
|
||||||
|
"@algolia/client-search" "4.23.3"
|
||||||
|
"@algolia/transporter" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/client-analytics@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.23.3.tgz#f88710885278fe6fb6964384af59004a5a6f161d"
|
||||||
|
integrity sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/client-common" "4.23.3"
|
||||||
|
"@algolia/client-search" "4.23.3"
|
||||||
|
"@algolia/requester-common" "4.23.3"
|
||||||
|
"@algolia/transporter" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/client-common@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.23.3.tgz#891116aa0db75055a7ecc107649f7f0965774704"
|
||||||
|
integrity sha512-l6EiPxdAlg8CYhroqS5ybfIczsGUIAC47slLPOMDeKSVXYG1n0qGiz4RjAHLw2aD0xzh2EXZ7aRguPfz7UKDKw==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/requester-common" "4.23.3"
|
||||||
|
"@algolia/transporter" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/client-personalization@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.23.3.tgz#35fa8e5699b0295fbc400a8eb211dc711e5909db"
|
||||||
|
integrity sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/client-common" "4.23.3"
|
||||||
|
"@algolia/requester-common" "4.23.3"
|
||||||
|
"@algolia/transporter" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/client-search@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.23.3.tgz#a3486e6af13a231ec4ab43a915a1f318787b937f"
|
||||||
|
integrity sha512-P4VAKFHqU0wx9O+q29Q8YVuaowaZ5EM77rxfmGnkHUJggh28useXQdopokgwMeYw2XUht49WX5RcTQ40rZIabw==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/client-common" "4.23.3"
|
||||||
|
"@algolia/requester-common" "4.23.3"
|
||||||
|
"@algolia/transporter" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/logger-common@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.23.3.tgz#35c6d833cbf41e853a4f36ba37c6e5864920bfe9"
|
||||||
|
integrity sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g==
|
||||||
|
|
||||||
|
"@algolia/logger-console@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.23.3.tgz#30f916781826c4db5f51fcd9a8a264a06e136985"
|
||||||
|
integrity sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/logger-common" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/recommend@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-4.23.3.tgz#53d4f194d22d9c72dc05f3f7514c5878f87c5890"
|
||||||
|
integrity sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/cache-browser-local-storage" "4.23.3"
|
||||||
|
"@algolia/cache-common" "4.23.3"
|
||||||
|
"@algolia/cache-in-memory" "4.23.3"
|
||||||
|
"@algolia/client-common" "4.23.3"
|
||||||
|
"@algolia/client-search" "4.23.3"
|
||||||
|
"@algolia/logger-common" "4.23.3"
|
||||||
|
"@algolia/logger-console" "4.23.3"
|
||||||
|
"@algolia/requester-browser-xhr" "4.23.3"
|
||||||
|
"@algolia/requester-common" "4.23.3"
|
||||||
|
"@algolia/requester-node-http" "4.23.3"
|
||||||
|
"@algolia/transporter" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/requester-browser-xhr@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.3.tgz#9e47e76f60d540acc8b27b4ebc7a80d1b41938b9"
|
||||||
|
integrity sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/requester-common" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/requester-common@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.23.3.tgz#7dbae896e41adfaaf1d1fa5f317f83a99afb04b3"
|
||||||
|
integrity sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw==
|
||||||
|
|
||||||
|
"@algolia/requester-node-http@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.23.3.tgz#c9f94a5cb96a15f48cea338ab6ef16bbd0ff989f"
|
||||||
|
integrity sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/requester-common" "4.23.3"
|
||||||
|
|
||||||
|
"@algolia/transporter@4.23.3":
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.23.3.tgz#545b045b67db3850ddf0bbecbc6c84ff1f3398b7"
|
||||||
|
integrity sha512-Wjl5gttqnf/gQKJA+dafnD0Y6Yw97yvfY8R9h0dQltX1GXTgNs1zWgvtWW0tHl1EgMdhAyw189uWiZMnL3QebQ==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/cache-common" "4.23.3"
|
||||||
|
"@algolia/logger-common" "4.23.3"
|
||||||
|
"@algolia/requester-common" "4.23.3"
|
||||||
|
|
||||||
|
"@babel/parser@^7.24.4":
|
||||||
|
version "7.24.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.4.tgz#234487a110d89ad5a3ed4a8a566c36b9453e8c88"
|
||||||
|
integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==
|
||||||
|
|
||||||
|
"@docsearch/css@3.6.0", "@docsearch/css@^3.6.0":
|
||||||
|
version "3.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.6.0.tgz#0e9f56f704b3a34d044d15fd9962ebc1536ba4fb"
|
||||||
|
integrity sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==
|
||||||
|
|
||||||
|
"@docsearch/js@^3.6.0":
|
||||||
|
version "3.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@docsearch/js/-/js-3.6.0.tgz#f9e46943449b9092d874944f7a80bcc071004cfb"
|
||||||
|
integrity sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ==
|
||||||
|
dependencies:
|
||||||
|
"@docsearch/react" "3.6.0"
|
||||||
|
preact "^10.0.0"
|
||||||
|
|
||||||
|
"@docsearch/react@3.6.0":
|
||||||
|
version "3.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.6.0.tgz#b4f25228ecb7fc473741aefac592121e86dd2958"
|
||||||
|
integrity sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/autocomplete-core" "1.9.3"
|
||||||
|
"@algolia/autocomplete-preset-algolia" "1.9.3"
|
||||||
|
"@docsearch/css" "3.6.0"
|
||||||
|
algoliasearch "^4.19.1"
|
||||||
|
|
||||||
|
"@esbuild/aix-ppc64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537"
|
||||||
|
integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==
|
||||||
|
|
||||||
|
"@esbuild/android-arm64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9"
|
||||||
|
integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==
|
||||||
|
|
||||||
|
"@esbuild/android-arm@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995"
|
||||||
|
integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==
|
||||||
|
|
||||||
|
"@esbuild/android-x64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98"
|
||||||
|
integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==
|
||||||
|
|
||||||
|
"@esbuild/darwin-arm64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb"
|
||||||
|
integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==
|
||||||
|
|
||||||
|
"@esbuild/darwin-x64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0"
|
||||||
|
integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==
|
||||||
|
|
||||||
|
"@esbuild/freebsd-arm64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911"
|
||||||
|
integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==
|
||||||
|
|
||||||
|
"@esbuild/freebsd-x64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c"
|
||||||
|
integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==
|
||||||
|
|
||||||
|
"@esbuild/linux-arm64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5"
|
||||||
|
integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==
|
||||||
|
|
||||||
|
"@esbuild/linux-arm@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c"
|
||||||
|
integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==
|
||||||
|
|
||||||
|
"@esbuild/linux-ia32@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa"
|
||||||
|
integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==
|
||||||
|
|
||||||
|
"@esbuild/linux-loong64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5"
|
||||||
|
integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==
|
||||||
|
|
||||||
|
"@esbuild/linux-mips64el@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa"
|
||||||
|
integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==
|
||||||
|
|
||||||
|
"@esbuild/linux-ppc64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20"
|
||||||
|
integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==
|
||||||
|
|
||||||
|
"@esbuild/linux-riscv64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300"
|
||||||
|
integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==
|
||||||
|
|
||||||
|
"@esbuild/linux-s390x@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685"
|
||||||
|
integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==
|
||||||
|
|
||||||
|
"@esbuild/linux-x64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff"
|
||||||
|
integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==
|
||||||
|
|
||||||
|
"@esbuild/netbsd-x64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6"
|
||||||
|
integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==
|
||||||
|
|
||||||
|
"@esbuild/openbsd-x64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf"
|
||||||
|
integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==
|
||||||
|
|
||||||
|
"@esbuild/sunos-x64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f"
|
||||||
|
integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==
|
||||||
|
|
||||||
|
"@esbuild/win32-arm64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90"
|
||||||
|
integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==
|
||||||
|
|
||||||
|
"@esbuild/win32-ia32@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23"
|
||||||
|
integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==
|
||||||
|
|
||||||
|
"@esbuild/win32-x64@0.20.2":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc"
|
||||||
|
integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==
|
||||||
|
|
||||||
|
"@jridgewell/sourcemap-codec@^1.4.15":
|
||||||
|
version "1.4.15"
|
||||||
|
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
|
||||||
|
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm-eabi@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.4.tgz#5e8930291f1e5ead7fb1171d53ba5c87718de062"
|
||||||
|
integrity sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q==
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm64@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.4.tgz#ffb84f1359c04ec8a022a97110e18a5600f5f638"
|
||||||
|
integrity sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w==
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-arm64@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz#b2fcee8d4806a0b1b9185ac038cc428ddedce9f4"
|
||||||
|
integrity sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw==
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-x64@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.4.tgz#fcb25ccbaa3dd33a6490e9d1c64bab2e0e16b932"
|
||||||
|
integrity sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-gnueabihf@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.4.tgz#40d46bdfe667e5eca31bf40047460e326d2e26bb"
|
||||||
|
integrity sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-musleabihf@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.4.tgz#7741df2448c11c56588b50835dbfe91b1a10b375"
|
||||||
|
integrity sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-gnu@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.4.tgz#0a23b02d2933e4c4872ad18d879890b6a4a295df"
|
||||||
|
integrity sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-musl@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.4.tgz#e37ef259358aa886cc07d782220a4fb83c1e6970"
|
||||||
|
integrity sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-powerpc64le-gnu@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.4.tgz#8c69218b6de05ee2ba211664a2d2ac1e54e43f94"
|
||||||
|
integrity sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-gnu@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.4.tgz#d32727dab8f538d9a4a7c03bcf58c436aecd0139"
|
||||||
|
integrity sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-s390x-gnu@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.4.tgz#d46097246a187d99fc9451fe8393b7155b47c5ec"
|
||||||
|
integrity sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-gnu@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz#6356c5a03a4afb1c3057490fc51b4764e109dbc7"
|
||||||
|
integrity sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-musl@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.4.tgz#03a5831a9c0d05877b94653b5ddd3020d3c6fb06"
|
||||||
|
integrity sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-arm64-msvc@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.4.tgz#6cc0db57750376b9303bdb6f5482af8974fcae35"
|
||||||
|
integrity sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-ia32-msvc@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.4.tgz#aea0b7e492bd9ed46971cb80bc34f1eb14e07789"
|
||||||
|
integrity sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-msvc@4.16.4":
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.4.tgz#c09ad9a132ccb5a67c4f211d909323ab1294f95f"
|
||||||
|
integrity sha512-YunpoOAyGLDseanENHmbFvQSfVL5BxW3k7hhy0eN4rb3gS/ct75dVD0EXOWIqFT/nE8XYW6LP6vz6ctKRi0k9A==
|
||||||
|
|
||||||
|
"@shikijs/core@1.3.0", "@shikijs/core@^1.3.0":
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.3.0.tgz#5b93b51ddb8def1e3a1543107f9b5b0540f716f6"
|
||||||
|
integrity sha512-7fedsBfuILDTBmrYZNFI8B6ATTxhQAasUHllHmjvSZPnoq4bULWoTpHwmuQvZ8Aq03/tAa2IGo6RXqWtHdWaCA==
|
||||||
|
|
||||||
|
"@shikijs/transformers@^1.3.0":
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@shikijs/transformers/-/transformers-1.3.0.tgz#b03c5733ef61e25e4f53666bf11889f8876f34e9"
|
||||||
|
integrity sha512-3mlpg2I9CjhjE96dEWQOGeCWoPcyTov3s4aAsHmgvnTHa8MBknEnCQy8/xivJPSpD+olqOqIEoHnLfbNJK29AA==
|
||||||
|
dependencies:
|
||||||
|
shiki "1.3.0"
|
||||||
|
|
||||||
|
"@types/estree@1.0.5":
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
|
||||||
|
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
|
||||||
|
|
||||||
|
"@types/linkify-it@*":
|
||||||
|
version "3.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.5.tgz#1e78a3ac2428e6d7e6c05c1665c242023a4601d8"
|
||||||
|
integrity sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==
|
||||||
|
|
||||||
|
"@types/markdown-it@^14.0.1":
|
||||||
|
version "14.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.0.1.tgz#3d3fdf9dba83b69edececc070d39ec72b84270a7"
|
||||||
|
integrity sha512-6WfOG3jXR78DW8L5cTYCVVGAsIFZskRHCDo5tbqa+qtKVt4oDRVH7hyIWu1SpDQJlmIoEivNQZ5h+AGAOrgOtQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/linkify-it" "*"
|
||||||
|
"@types/mdurl" "*"
|
||||||
|
|
||||||
|
"@types/mdurl@*":
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.5.tgz#3e0d2db570e9fb6ccb2dc8fde0be1d79ac810d39"
|
||||||
|
integrity sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==
|
||||||
|
|
||||||
|
"@types/web-bluetooth@^0.0.20":
|
||||||
|
version "0.0.20"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597"
|
||||||
|
integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==
|
||||||
|
|
||||||
|
"@vitejs/plugin-vue@^5.0.4":
|
||||||
|
version "5.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz#508d6a0f2440f86945835d903fcc0d95d1bb8a37"
|
||||||
|
integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==
|
||||||
|
|
||||||
|
"@vue/compiler-core@3.4.24":
|
||||||
|
version "3.4.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.24.tgz#6b4a5ffddcd874a692f2acfa68981201bcd7096b"
|
||||||
|
integrity sha512-vbW/tgbwJYj62N/Ww99x0zhFTkZDTcGh3uwJEuadZ/nF9/xuFMC4693P9r+3sxGXISABpDKvffY5ApH9pmdd1A==
|
||||||
|
dependencies:
|
||||||
|
"@babel/parser" "^7.24.4"
|
||||||
|
"@vue/shared" "3.4.24"
|
||||||
|
entities "^4.5.0"
|
||||||
|
estree-walker "^2.0.2"
|
||||||
|
source-map-js "^1.2.0"
|
||||||
|
|
||||||
|
"@vue/compiler-dom@3.4.24":
|
||||||
|
version "3.4.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.24.tgz#b7335a49f095b6d35e48b6f7be8da513c1fa52b8"
|
||||||
|
integrity sha512-4XgABML/4cNndVsQndG6BbGN7+EoisDwi3oXNovqL/4jdNhwvP8/rfRMTb6FxkxIxUUtg6AI1/qZvwfSjxJiWA==
|
||||||
|
dependencies:
|
||||||
|
"@vue/compiler-core" "3.4.24"
|
||||||
|
"@vue/shared" "3.4.24"
|
||||||
|
|
||||||
|
"@vue/compiler-sfc@3.4.24":
|
||||||
|
version "3.4.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.24.tgz#2872e353147ce2a145169a33ddd4d68dc95c3a18"
|
||||||
|
integrity sha512-nRAlJUK02FTWfA2nuvNBAqsDZuERGFgxZ8sGH62XgFSvMxO2URblzulExsmj4gFZ8e+VAyDooU9oAoXfEDNxTA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/parser" "^7.24.4"
|
||||||
|
"@vue/compiler-core" "3.4.24"
|
||||||
|
"@vue/compiler-dom" "3.4.24"
|
||||||
|
"@vue/compiler-ssr" "3.4.24"
|
||||||
|
"@vue/shared" "3.4.24"
|
||||||
|
estree-walker "^2.0.2"
|
||||||
|
magic-string "^0.30.10"
|
||||||
|
postcss "^8.4.38"
|
||||||
|
source-map-js "^1.2.0"
|
||||||
|
|
||||||
|
"@vue/compiler-ssr@3.4.24":
|
||||||
|
version "3.4.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.24.tgz#0d11fe54dabd17cbd6393a16bf7f785da1cfab46"
|
||||||
|
integrity sha512-ZsAtr4fhaUFnVcDqwW3bYCSDwq+9Gk69q2r/7dAHDrOMw41kylaMgOP4zRnn6GIEJkQznKgrMOGPMFnLB52RbQ==
|
||||||
|
dependencies:
|
||||||
|
"@vue/compiler-dom" "3.4.24"
|
||||||
|
"@vue/shared" "3.4.24"
|
||||||
|
|
||||||
|
"@vue/devtools-api@^7.0.27":
|
||||||
|
version "7.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.1.2.tgz#8808b0f008842b756bf1e9c30788837abb62ab3a"
|
||||||
|
integrity sha512-AKd49cN3BdRgttmX5Aw8op7sx6jmaPwaILcDjaa05UKc1yIHDYST7P8yGZs6zd2pKFETAQz40gmyG7+b57slsQ==
|
||||||
|
dependencies:
|
||||||
|
"@vue/devtools-kit" "^7.1.2"
|
||||||
|
|
||||||
|
"@vue/devtools-kit@^7.1.2":
|
||||||
|
version "7.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.1.2.tgz#dfb7306edf895dadc556dd5f0c516809c2f94826"
|
||||||
|
integrity sha512-UTrcUSOhlI9eXqbPMHUWwA6NQiiPT3onzXsVk2JHGR8ZFFSkzsWTTpHyVA1woG8zvgu2HNV/wigW2k87p858zw==
|
||||||
|
dependencies:
|
||||||
|
"@vue/devtools-shared" "^7.1.2"
|
||||||
|
hookable "^5.5.3"
|
||||||
|
mitt "^3.0.1"
|
||||||
|
perfect-debounce "^1.0.0"
|
||||||
|
speakingurl "^14.0.1"
|
||||||
|
|
||||||
|
"@vue/devtools-shared@^7.1.2":
|
||||||
|
version "7.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.1.2.tgz#7b1c1de10bab4756f271c377370a62833b4ee94b"
|
||||||
|
integrity sha512-r9cUf93VMhKSsxF2/cBbf6Lm1nRBx+r1pRuji5CiAf3JIPYPOjeEqJ13OuwP1fauYh1tyBFcCxt3eJPvHT59gg==
|
||||||
|
dependencies:
|
||||||
|
rfdc "^1.3.1"
|
||||||
|
|
||||||
|
"@vue/reactivity@3.4.24":
|
||||||
|
version "3.4.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.24.tgz#150584316ca2acc4ed19a24f9f29863c3a17a7b2"
|
||||||
|
integrity sha512-nup3fSYg4i4LtNvu9slF/HF/0dkMQYfepUdORBcMSsankzRPzE7ypAFurpwyRBfU1i7Dn1kcwpYsE1wETSh91g==
|
||||||
|
dependencies:
|
||||||
|
"@vue/shared" "3.4.24"
|
||||||
|
|
||||||
|
"@vue/runtime-core@3.4.24":
|
||||||
|
version "3.4.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.24.tgz#066c544dc59a07a96c12874a57b750c239124874"
|
||||||
|
integrity sha512-c7iMfj6cJMeAG3s5yOn9Rc5D9e2/wIuaozmGf/ICGCY3KV5H7mbTVdvEkd4ZshTq7RUZqj2k7LMJWVx+EBiY1g==
|
||||||
|
dependencies:
|
||||||
|
"@vue/reactivity" "3.4.24"
|
||||||
|
"@vue/shared" "3.4.24"
|
||||||
|
|
||||||
|
"@vue/runtime-dom@3.4.24":
|
||||||
|
version "3.4.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.24.tgz#4f8e7acbe1e8ffa7c55af1366e4438729ebe9b20"
|
||||||
|
integrity sha512-uXKzuh/Emfad2Y7Qm0ABsLZZV6H3mAJ5ZVqmAOlrNQRf+T5mxpPGZBfec1hkP41t6h6FwF6RSGCs/gd8WbuySQ==
|
||||||
|
dependencies:
|
||||||
|
"@vue/runtime-core" "3.4.24"
|
||||||
|
"@vue/shared" "3.4.24"
|
||||||
|
csstype "^3.1.3"
|
||||||
|
|
||||||
|
"@vue/server-renderer@3.4.24":
|
||||||
|
version "3.4.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.24.tgz#80dd546f8d6a9f5c4f8b68083fe9cc2d62299332"
|
||||||
|
integrity sha512-H+DLK4sQF6sRgzKyofmlEVBIV/9KrQU6HIV7nt6yIwSGGKvSwlV8pqJlebUKLpbXaNHugdSfAbP6YmXF69lxow==
|
||||||
|
dependencies:
|
||||||
|
"@vue/compiler-ssr" "3.4.24"
|
||||||
|
"@vue/shared" "3.4.24"
|
||||||
|
|
||||||
|
"@vue/shared@3.4.24":
|
||||||
|
version "3.4.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.24.tgz#278ac71f492b392b9b17fe8fc7d324db1a8842db"
|
||||||
|
integrity sha512-BW4tajrJBM9AGAknnyEw5tO2xTmnqgup0VTnDAMcxYmqOX0RG0b9aSUGAbEKolD91tdwpA6oCwbltoJoNzpItw==
|
||||||
|
|
||||||
|
"@vueuse/core@10.9.0", "@vueuse/core@^10.9.0":
|
||||||
|
version "10.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.9.0.tgz#7d779a95cf0189de176fee63cee4ba44b3c85d64"
|
||||||
|
integrity sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==
|
||||||
|
dependencies:
|
||||||
|
"@types/web-bluetooth" "^0.0.20"
|
||||||
|
"@vueuse/metadata" "10.9.0"
|
||||||
|
"@vueuse/shared" "10.9.0"
|
||||||
|
vue-demi ">=0.14.7"
|
||||||
|
|
||||||
|
"@vueuse/integrations@^10.9.0":
|
||||||
|
version "10.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.9.0.tgz#2b1a9556215ad3c1f96d39cbfbef102cf6e0ec05"
|
||||||
|
integrity sha512-acK+A01AYdWSvL4BZmCoJAcyHJ6EqhmkQEXbQLwev1MY7NBnS+hcEMx/BzVoR9zKI+UqEPMD9u6PsyAuiTRT4Q==
|
||||||
|
dependencies:
|
||||||
|
"@vueuse/core" "10.9.0"
|
||||||
|
"@vueuse/shared" "10.9.0"
|
||||||
|
vue-demi ">=0.14.7"
|
||||||
|
|
||||||
|
"@vueuse/metadata@10.9.0":
|
||||||
|
version "10.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.9.0.tgz#769a1a9db65daac15cf98084cbf7819ed3758620"
|
||||||
|
integrity sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==
|
||||||
|
|
||||||
|
"@vueuse/shared@10.9.0":
|
||||||
|
version "10.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.9.0.tgz#13af2a348de15d07b7be2fd0c7fc9853a69d8fe0"
|
||||||
|
integrity sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==
|
||||||
|
dependencies:
|
||||||
|
vue-demi ">=0.14.7"
|
||||||
|
|
||||||
|
algoliasearch@^4.19.1:
|
||||||
|
version "4.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.23.3.tgz#e09011d0a3b0651444916a3e6bbcba064ec44b60"
|
||||||
|
integrity sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg==
|
||||||
|
dependencies:
|
||||||
|
"@algolia/cache-browser-local-storage" "4.23.3"
|
||||||
|
"@algolia/cache-common" "4.23.3"
|
||||||
|
"@algolia/cache-in-memory" "4.23.3"
|
||||||
|
"@algolia/client-account" "4.23.3"
|
||||||
|
"@algolia/client-analytics" "4.23.3"
|
||||||
|
"@algolia/client-common" "4.23.3"
|
||||||
|
"@algolia/client-personalization" "4.23.3"
|
||||||
|
"@algolia/client-search" "4.23.3"
|
||||||
|
"@algolia/logger-common" "4.23.3"
|
||||||
|
"@algolia/logger-console" "4.23.3"
|
||||||
|
"@algolia/recommend" "4.23.3"
|
||||||
|
"@algolia/requester-browser-xhr" "4.23.3"
|
||||||
|
"@algolia/requester-common" "4.23.3"
|
||||||
|
"@algolia/requester-node-http" "4.23.3"
|
||||||
|
"@algolia/transporter" "4.23.3"
|
||||||
|
|
||||||
|
csstype@^3.1.3:
|
||||||
|
version "3.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
|
||||||
|
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
|
||||||
|
|
||||||
|
entities@^4.5.0:
|
||||||
|
version "4.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
|
||||||
|
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
||||||
|
|
||||||
|
esbuild@^0.20.1:
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1"
|
||||||
|
integrity sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==
|
||||||
|
optionalDependencies:
|
||||||
|
"@esbuild/aix-ppc64" "0.20.2"
|
||||||
|
"@esbuild/android-arm" "0.20.2"
|
||||||
|
"@esbuild/android-arm64" "0.20.2"
|
||||||
|
"@esbuild/android-x64" "0.20.2"
|
||||||
|
"@esbuild/darwin-arm64" "0.20.2"
|
||||||
|
"@esbuild/darwin-x64" "0.20.2"
|
||||||
|
"@esbuild/freebsd-arm64" "0.20.2"
|
||||||
|
"@esbuild/freebsd-x64" "0.20.2"
|
||||||
|
"@esbuild/linux-arm" "0.20.2"
|
||||||
|
"@esbuild/linux-arm64" "0.20.2"
|
||||||
|
"@esbuild/linux-ia32" "0.20.2"
|
||||||
|
"@esbuild/linux-loong64" "0.20.2"
|
||||||
|
"@esbuild/linux-mips64el" "0.20.2"
|
||||||
|
"@esbuild/linux-ppc64" "0.20.2"
|
||||||
|
"@esbuild/linux-riscv64" "0.20.2"
|
||||||
|
"@esbuild/linux-s390x" "0.20.2"
|
||||||
|
"@esbuild/linux-x64" "0.20.2"
|
||||||
|
"@esbuild/netbsd-x64" "0.20.2"
|
||||||
|
"@esbuild/openbsd-x64" "0.20.2"
|
||||||
|
"@esbuild/sunos-x64" "0.20.2"
|
||||||
|
"@esbuild/win32-arm64" "0.20.2"
|
||||||
|
"@esbuild/win32-ia32" "0.20.2"
|
||||||
|
"@esbuild/win32-x64" "0.20.2"
|
||||||
|
|
||||||
|
estree-walker@^2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||||
|
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
||||||
|
|
||||||
|
focus-trap@^7.5.4:
|
||||||
|
version "7.5.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.5.4.tgz#6c4e342fe1dae6add9c2aa332a6e7a0bbd495ba2"
|
||||||
|
integrity sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==
|
||||||
|
dependencies:
|
||||||
|
tabbable "^6.2.0"
|
||||||
|
|
||||||
|
fsevents@~2.3.2, fsevents@~2.3.3:
|
||||||
|
version "2.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
||||||
|
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||||
|
|
||||||
|
hookable@^5.5.3:
|
||||||
|
version "5.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/hookable/-/hookable-5.5.3.tgz#6cfc358984a1ef991e2518cb9ed4a778bbd3215d"
|
||||||
|
integrity sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==
|
||||||
|
|
||||||
|
magic-string@^0.30.10:
|
||||||
|
version "0.30.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e"
|
||||||
|
integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==
|
||||||
|
dependencies:
|
||||||
|
"@jridgewell/sourcemap-codec" "^1.4.15"
|
||||||
|
|
||||||
|
mark.js@8.11.1:
|
||||||
|
version "8.11.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5"
|
||||||
|
integrity sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==
|
||||||
|
|
||||||
|
minisearch@^6.3.0:
|
||||||
|
version "6.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-6.3.0.tgz#985a2f1ca3c73c2d65af94f0616bfe57164b0b6b"
|
||||||
|
integrity sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==
|
||||||
|
|
||||||
|
mitt@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1"
|
||||||
|
integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==
|
||||||
|
|
||||||
|
nanoid@^3.3.7:
|
||||||
|
version "3.3.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
|
||||||
|
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
|
||||||
|
|
||||||
|
perfect-debounce@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a"
|
||||||
|
integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==
|
||||||
|
|
||||||
|
picocolors@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||||
|
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||||
|
|
||||||
|
postcss@^8.4.38:
|
||||||
|
version "8.4.38"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e"
|
||||||
|
integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==
|
||||||
|
dependencies:
|
||||||
|
nanoid "^3.3.7"
|
||||||
|
picocolors "^1.0.0"
|
||||||
|
source-map-js "^1.2.0"
|
||||||
|
|
||||||
|
preact@^10.0.0:
|
||||||
|
version "10.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/preact/-/preact-10.20.2.tgz#0b343299a8c020562311cc25db93b3d832ec5e71"
|
||||||
|
integrity sha512-S1d1ernz3KQ+Y2awUxKakpfOg2CEmJmwOP+6igPx6dgr6pgDvenqYviyokWso2rhHvGtTlWWnJDa7RaPbQerTg==
|
||||||
|
|
||||||
|
rfdc@^1.3.1:
|
||||||
|
version "1.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f"
|
||||||
|
integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==
|
||||||
|
|
||||||
|
rollup@^4.13.0:
|
||||||
|
version "4.16.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.16.4.tgz#fe328eb41293f20c9593a095ec23bdc4b5d93317"
|
||||||
|
integrity sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA==
|
||||||
|
dependencies:
|
||||||
|
"@types/estree" "1.0.5"
|
||||||
|
optionalDependencies:
|
||||||
|
"@rollup/rollup-android-arm-eabi" "4.16.4"
|
||||||
|
"@rollup/rollup-android-arm64" "4.16.4"
|
||||||
|
"@rollup/rollup-darwin-arm64" "4.16.4"
|
||||||
|
"@rollup/rollup-darwin-x64" "4.16.4"
|
||||||
|
"@rollup/rollup-linux-arm-gnueabihf" "4.16.4"
|
||||||
|
"@rollup/rollup-linux-arm-musleabihf" "4.16.4"
|
||||||
|
"@rollup/rollup-linux-arm64-gnu" "4.16.4"
|
||||||
|
"@rollup/rollup-linux-arm64-musl" "4.16.4"
|
||||||
|
"@rollup/rollup-linux-powerpc64le-gnu" "4.16.4"
|
||||||
|
"@rollup/rollup-linux-riscv64-gnu" "4.16.4"
|
||||||
|
"@rollup/rollup-linux-s390x-gnu" "4.16.4"
|
||||||
|
"@rollup/rollup-linux-x64-gnu" "4.16.4"
|
||||||
|
"@rollup/rollup-linux-x64-musl" "4.16.4"
|
||||||
|
"@rollup/rollup-win32-arm64-msvc" "4.16.4"
|
||||||
|
"@rollup/rollup-win32-ia32-msvc" "4.16.4"
|
||||||
|
"@rollup/rollup-win32-x64-msvc" "4.16.4"
|
||||||
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
|
shiki@1.3.0, shiki@^1.3.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.3.0.tgz#3eda35cb49f6f0a98525e9da48fc072e6c655a3f"
|
||||||
|
integrity sha512-9aNdQy/etMXctnPzsje1h1XIGm9YfRcSksKOGqZWXA/qP9G18/8fpz5Bjpma8bOgz3tqIpjERAd6/lLjFyzoww==
|
||||||
|
dependencies:
|
||||||
|
"@shikijs/core" "1.3.0"
|
||||||
|
|
||||||
|
source-map-js@^1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
|
||||||
|
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
|
||||||
|
|
||||||
|
speakingurl@^14.0.1:
|
||||||
|
version "14.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/speakingurl/-/speakingurl-14.0.1.tgz#f37ec8ddc4ab98e9600c1c9ec324a8c48d772a53"
|
||||||
|
integrity sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==
|
||||||
|
|
||||||
|
tabbable@^6.2.0:
|
||||||
|
version "6.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
|
||||||
|
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
|
||||||
|
|
||||||
|
vite@^5.2.10, vite@^5.2.9:
|
||||||
|
version "5.2.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.10.tgz#2ac927c91e99d51b376a5c73c0e4b059705f5bd7"
|
||||||
|
integrity sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==
|
||||||
|
dependencies:
|
||||||
|
esbuild "^0.20.1"
|
||||||
|
postcss "^8.4.38"
|
||||||
|
rollup "^4.13.0"
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents "~2.3.3"
|
||||||
|
|
||||||
|
vitepress-plugin-tabs@^0.5.0:
|
||||||
|
version "0.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vitepress-plugin-tabs/-/vitepress-plugin-tabs-0.5.0.tgz#2b193a72ed36b9fcd63e3907d3044fe7b6cf3e4e"
|
||||||
|
integrity sha512-SIhFWwGsUkTByfc2b279ray/E0Jt8vDTsM1LiHxmCOBAEMmvzIBZSuYYT1DpdDTiS3SuJieBheJkYnwCq/yD9A==
|
||||||
|
|
||||||
|
vitepress@^1.1.0:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.1.3.tgz#ded22392f5274680aaba8bb81dd4fb1c4741c02e"
|
||||||
|
integrity sha512-hGrIYN0w9IHWs0NQSnlMjKV/v/HLfD+Ywv5QdvCSkiT32mpNOOwUrZjnqZv/JL/WBPpUc94eghTUvmipxw0xrA==
|
||||||
|
dependencies:
|
||||||
|
"@docsearch/css" "^3.6.0"
|
||||||
|
"@docsearch/js" "^3.6.0"
|
||||||
|
"@shikijs/core" "^1.3.0"
|
||||||
|
"@shikijs/transformers" "^1.3.0"
|
||||||
|
"@types/markdown-it" "^14.0.1"
|
||||||
|
"@vitejs/plugin-vue" "^5.0.4"
|
||||||
|
"@vue/devtools-api" "^7.0.27"
|
||||||
|
"@vueuse/core" "^10.9.0"
|
||||||
|
"@vueuse/integrations" "^10.9.0"
|
||||||
|
focus-trap "^7.5.4"
|
||||||
|
mark.js "8.11.1"
|
||||||
|
minisearch "^6.3.0"
|
||||||
|
shiki "^1.3.0"
|
||||||
|
vite "^5.2.9"
|
||||||
|
vue "^3.4.23"
|
||||||
|
|
||||||
|
vue-demi@>=0.14.7:
|
||||||
|
version "0.14.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.7.tgz#8317536b3ef74c5b09f268f7782e70194567d8f2"
|
||||||
|
integrity sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==
|
||||||
|
|
||||||
|
vue@^3.4.23, vue@^3.4.24:
|
||||||
|
version "3.4.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.24.tgz#f269549939a6c092480f018aa0bd886ba64f4c6f"
|
||||||
|
integrity sha512-NPdx7dLGyHmKHGRRU5bMRYVE+rechR+KDU5R2tSTNG36PuMwbfAJ+amEvOAw7BPfZp5sQulNELSLm5YUkau+Sg==
|
||||||
|
dependencies:
|
||||||
|
"@vue/compiler-dom" "3.4.24"
|
||||||
|
"@vue/compiler-sfc" "3.4.24"
|
||||||
|
"@vue/runtime-dom" "3.4.24"
|
||||||
|
"@vue/server-renderer" "3.4.24"
|
||||||
|
"@vue/shared" "3.4.24"
|
|
@ -1 +0,0 @@
|
||||||
docs.qmk.fm
|
|
|
@ -20,7 +20,7 @@ This document marks the inaugural Breaking Change merge. A list of changes follo
|
||||||
|
|
||||||
* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()`
|
* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()`
|
||||||
* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity
|
* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity
|
||||||
* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features
|
* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](../custom_quantum_functions) and [macro](../feature_macros) features
|
||||||
|
|
||||||
## Update Atreus to current code conventions
|
## Update Atreus to current code conventions
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ This document marks the inaugural Breaking Change merge. A list of changes follo
|
||||||
|
|
||||||
* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()`
|
* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()`
|
||||||
* All keymaps using these actions have had the relevant `KC_FN*` keys replaced with the equivalent `BL_*` keys
|
* All keymaps using these actions have had the relevant `KC_FN*` keys replaced with the equivalent `BL_*` keys
|
||||||
* If you currently use `KC_FN*` you will need to replace `fn_actions` with the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features
|
* If you currently use `KC_FN*` you will need to replace `fn_actions` with the [custom keycode](../custom_quantum_functions) and [macro](../feature_macros) features
|
||||||
|
|
||||||
## Remove `KC_DELT` alias in favor of `KC_DEL`
|
## Remove `KC_DELT` alias in favor of `KC_DEL`
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ Four times a year QMK runs a process for merging Breaking Changes. A Breaking Ch
|
||||||
|
|
||||||
* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()`
|
* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()`
|
||||||
* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity
|
* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity
|
||||||
* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features
|
* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](../custom_quantum_functions) and [macro](../feature_macros) features
|
||||||
|
|
||||||
|
|
||||||
## Moving backlight keycode handling to `process_keycode/`
|
## Moving backlight keycode handling to `process_keycode/`
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps.
|
Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps.
|
||||||
|
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Relocated Keyboards :id=relocated-keyboards
|
### Relocated Keyboards {#relocated-keyboards}
|
||||||
|
|
||||||
#### The Key Company project consolidation ([#9547](https://github.com/qmk/qmk_firmware/pull/9547))
|
#### The Key Company project consolidation ([#9547](https://github.com/qmk/qmk_firmware/pull/9547))
|
||||||
#### relocating boards by flehrad to flehrad/ folder ([#9635](https://github.com/qmk/qmk_firmware/pull/9635))
|
#### relocating boards by flehrad to flehrad/ folder ([#9635](https://github.com/qmk/qmk_firmware/pull/9635))
|
||||||
|
@ -24,7 +24,7 @@ handwired/numbrero | flehrad/numbrero
|
||||||
snagpad | flehrad/snagpad
|
snagpad | flehrad/snagpad
|
||||||
handwired/tradestation | flehrad/tradestation
|
handwired/tradestation | flehrad/tradestation
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=keyboard-updates
|
### Updated Keyboard Codebases {#keyboard-updates}
|
||||||
|
|
||||||
#### Keebio RGB wiring update ([#7754](https://github.com/qmk/qmk_firmware/pull/7754))
|
#### Keebio RGB wiring update ([#7754](https://github.com/qmk/qmk_firmware/pull/7754))
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ This change affects:
|
||||||
* Quefrency rev1
|
* Quefrency rev1
|
||||||
* Viterbi, revs. 1 and 2
|
* Viterbi, revs. 1 and 2
|
||||||
|
|
||||||
### Changes to Core Functionality :id=core-updates
|
### Changes to Core Functionality {#core-updates}
|
||||||
|
|
||||||
* Bigger Combo index ([#9318](https://github.com/qmk/qmk_firmware/pull/9318))
|
* Bigger Combo index ([#9318](https://github.com/qmk/qmk_firmware/pull/9318))
|
||||||
|
|
||||||
|
@ -58,14 +58,14 @@ Any fork that uses `process_combo_event` needs to update the function's first ar
|
||||||
* New function: `void process_combo_event(uint16_t combo_index, bool pressed)`
|
* New function: `void process_combo_event(uint16_t combo_index, bool pressed)`
|
||||||
|
|
||||||
|
|
||||||
## Core Changes :id=core-changes
|
## Core Changes {#core-changes}
|
||||||
|
|
||||||
### Fixes :id=core-fixes
|
### Fixes {#core-fixes}
|
||||||
|
|
||||||
* Mousekeys: scrolling acceleration is no longer coupled to mouse movement acceleration ([#9174](https://github.com/qmk/qmk_firmware/pull/9174))
|
* Mousekeys: scrolling acceleration is no longer coupled to mouse movement acceleration ([#9174](https://github.com/qmk/qmk_firmware/pull/9174))
|
||||||
* Keymap Extras: correctly assign Question Mark in Czech layout ([#9987](https://github.com/qmk/qmk_firmware/pull/9987))
|
* Keymap Extras: correctly assign Question Mark in Czech layout ([#9987](https://github.com/qmk/qmk_firmware/pull/9987))
|
||||||
|
|
||||||
### Additions and Enhancements :id=core-additions
|
### Additions and Enhancements {#core-additions}
|
||||||
|
|
||||||
* allow for WS2812 PWM to work on DMAMUX-capable devices ([#9471](https://github.com/qmk/qmk_firmware/pull/9471))
|
* allow for WS2812 PWM to work on DMAMUX-capable devices ([#9471](https://github.com/qmk/qmk_firmware/pull/9471))
|
||||||
* Newer STM32 MCUs have a DMAMUX peripheral, which allows mapping of DMAs to different DMA streams, rather than hard-defining the target streams in silicon.
|
* Newer STM32 MCUs have a DMAMUX peripheral, which allows mapping of DMAs to different DMA streams, rather than hard-defining the target streams in silicon.
|
||||||
|
@ -109,7 +109,7 @@ Any fork that uses `process_combo_event` needs to update the function's first ar
|
||||||
* The K-Type has been refactored to use QMK's native matrix scanning routine, and now has partial support for the RGB Matrix feature.
|
* The K-Type has been refactored to use QMK's native matrix scanning routine, and now has partial support for the RGB Matrix feature.
|
||||||
* Joysticks can now be used without defining analog pins ([#10169](https://github.com/qmk/qmk_firmware/pull/10169))
|
* Joysticks can now be used without defining analog pins ([#10169](https://github.com/qmk/qmk_firmware/pull/10169))
|
||||||
|
|
||||||
### Clean-ups and Optimizations :id=core-optimizations
|
### Clean-ups and Optimizations {#core-optimizations}
|
||||||
|
|
||||||
* iWRAP protocol removed ([#9284](https://github.com/qmk/qmk_firmware/pull/9284))
|
* iWRAP protocol removed ([#9284](https://github.com/qmk/qmk_firmware/pull/9284))
|
||||||
* work begun for consolidation of ChibiOS platform files ([#8327](https://github.com/qmk/qmk_firmware/pull/8327) and [#9315](https://github.com/qmk/qmk_firmware/pull/9315))
|
* work begun for consolidation of ChibiOS platform files ([#8327](https://github.com/qmk/qmk_firmware/pull/8327) and [#9315](https://github.com/qmk/qmk_firmware/pull/9315))
|
||||||
|
@ -140,7 +140,7 @@ Any fork that uses `process_combo_event` needs to update the function's first ar
|
||||||
* remove support for Adafruit EZ Key Bluetooth controller ([#10103](https://github.com/qmk/qmk_firmware/pull/10103))
|
* remove support for Adafruit EZ Key Bluetooth controller ([#10103](https://github.com/qmk/qmk_firmware/pull/10103))
|
||||||
|
|
||||||
|
|
||||||
## QMK Infrastructure and Internals :id=qmk-internals
|
## QMK Infrastructure and Internals {#qmk-internals}
|
||||||
|
|
||||||
* Attempt to fix CI for non-master branches. ([#9308](https://github.com/qmk/qmk_firmware/pull/9308))
|
* Attempt to fix CI for non-master branches. ([#9308](https://github.com/qmk/qmk_firmware/pull/9308))
|
||||||
* Actually fetch the branch we're attempting to compare against.
|
* Actually fetch the branch we're attempting to compare against.
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps.
|
Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps.
|
||||||
|
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Relocated Keyboards :id=relocated-keyboards
|
### Relocated Keyboards {#relocated-keyboards}
|
||||||
|
|
||||||
#### Reduce Helix keyboard build variation ([#8669](https://github.com/qmk/qmk_firmware/pull/8669))
|
#### Reduce Helix keyboard build variation ([#8669](https://github.com/qmk/qmk_firmware/pull/8669))
|
||||||
|
|
||||||
|
@ -88,21 +88,21 @@ The Valor and Dawn60 keyboards by Xelus22 both now require their revisions to be
|
||||||
| xelus/valor | xelus/valor/rev1 |
|
| xelus/valor | xelus/valor/rev1 |
|
||||||
|
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=keyboard-updates
|
### Updated Keyboard Codebases {#keyboard-updates}
|
||||||
|
|
||||||
#### AEboards EXT65 Refactor ([#10820](https://github.com/qmk/qmk_firmware/pull/10820))
|
#### AEboards EXT65 Refactor ([#10820](https://github.com/qmk/qmk_firmware/pull/10820))
|
||||||
|
|
||||||
The EXT65 codebase has been reworked so keymaps can be used with either revision.
|
The EXT65 codebase has been reworked so keymaps can be used with either revision.
|
||||||
|
|
||||||
|
|
||||||
## Core Changes :id=core-changes
|
## Core Changes {#core-changes}
|
||||||
|
|
||||||
### Fixes :id=core-fixes
|
### Fixes {#core-fixes}
|
||||||
|
|
||||||
* Reconnect the USB if users wake up a computer from the keyboard to restore the USB state ([#10088](https://github.com/qmk/qmk_firmware/pull/10088))
|
* Reconnect the USB if users wake up a computer from the keyboard to restore the USB state ([#10088](https://github.com/qmk/qmk_firmware/pull/10088))
|
||||||
* Fix cursor position bug in oled_write_raw functions ([#10800](https://github.com/qmk/qmk_firmware/pull/10800))
|
* Fix cursor position bug in oled_write_raw functions ([#10800](https://github.com/qmk/qmk_firmware/pull/10800))
|
||||||
|
|
||||||
### Additions and Enhancements :id=core-additions
|
### Additions and Enhancements {#core-additions}
|
||||||
|
|
||||||
* Allow MATRIX_ROWS to be greater than 32 ([#10183](https://github.com/qmk/qmk_firmware/pull/10183))
|
* Allow MATRIX_ROWS to be greater than 32 ([#10183](https://github.com/qmk/qmk_firmware/pull/10183))
|
||||||
* Add support for soft serial to ATmega32U2 ([#10204](https://github.com/qmk/qmk_firmware/pull/10204))
|
* Add support for soft serial to ATmega32U2 ([#10204](https://github.com/qmk/qmk_firmware/pull/10204))
|
||||||
|
@ -119,7 +119,7 @@ The EXT65 codebase has been reworked so keymaps can be used with either revision
|
||||||
* Add AT90USB support for serial.c ([#10706](https://github.com/qmk/qmk_firmware/pull/10706))
|
* Add AT90USB support for serial.c ([#10706](https://github.com/qmk/qmk_firmware/pull/10706))
|
||||||
* Auto shift: support repeats and early registration (#9826)
|
* Auto shift: support repeats and early registration (#9826)
|
||||||
|
|
||||||
### Clean-ups and Optimizations :id=core-optimizations
|
### Clean-ups and Optimizations {#core-optimizations}
|
||||||
|
|
||||||
* Haptic and solenoid cleanup ([#9700](https://github.com/qmk/qmk_firmware/pull/9700))
|
* Haptic and solenoid cleanup ([#9700](https://github.com/qmk/qmk_firmware/pull/9700))
|
||||||
* XD75 cleanup ([#10524](https://github.com/qmk/qmk_firmware/pull/10524))
|
* XD75 cleanup ([#10524](https://github.com/qmk/qmk_firmware/pull/10524))
|
||||||
|
@ -129,7 +129,7 @@ The EXT65 codebase has been reworked so keymaps can be used with either revision
|
||||||
* Remove references to HD44780 ([#10735](https://github.com/qmk/qmk_firmware/pull/10735))
|
* Remove references to HD44780 ([#10735](https://github.com/qmk/qmk_firmware/pull/10735))
|
||||||
|
|
||||||
|
|
||||||
## QMK Infrastructure and Internals :id=qmk-internals
|
## QMK Infrastructure and Internals {#qmk-internals}
|
||||||
|
|
||||||
* Add ability to build a subset of all keyboards based on platform. ([#10420](https://github.com/qmk/qmk_firmware/pull/10420))
|
* Add ability to build a subset of all keyboards based on platform. ([#10420](https://github.com/qmk/qmk_firmware/pull/10420))
|
||||||
* Initialise EEPROM drivers at startup, instead of upon first execution ([#10438](https://github.com/qmk/qmk_firmware/pull/10438))
|
* Initialise EEPROM drivers at startup, instead of upon first execution ([#10438](https://github.com/qmk/qmk_firmware/pull/10438))
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
# QMK Breaking Changes - 2021 May 29 Changelog
|
# QMK Breaking Changes - 2021 May 29 Changelog
|
||||||
|
|
||||||
## Notable Changes :id=notable-changes
|
## Notable Changes {#notable-changes}
|
||||||
|
|
||||||
### RGB Matrix support for split common ([#11055](https://github.com/qmk/qmk_firmware/pull/11055)) :id=rgb-matrix-split-common
|
### RGB Matrix support for split common ([#11055](https://github.com/qmk/qmk_firmware/pull/11055)) {#rgb-matrix-split-common}
|
||||||
|
|
||||||
Split boards can now use RGB Matrix without defining a custom matrix.
|
Split boards can now use RGB Matrix without defining a custom matrix.
|
||||||
|
|
||||||
### Teensy 3.6 support ([#12258](https://github.com/qmk/qmk_firmware/pull/12258)) :id=teensy-3-6-support
|
### Teensy 3.6 support ([#12258](https://github.com/qmk/qmk_firmware/pull/12258)) {#teensy-3-6-support}
|
||||||
|
|
||||||
Added support for MK66F18 (Teensy 3.6) microcontroller.
|
Added support for MK66F18 (Teensy 3.6) microcontroller.
|
||||||
|
|
||||||
### New command: qmk console ([#12828](https://github.com/qmk/qmk_firmware/pull/12828)) :id=new-command-qmk-console
|
### New command: qmk console ([#12828](https://github.com/qmk/qmk_firmware/pull/12828)) {#new-command-qmk-console}
|
||||||
|
|
||||||
A new `qmk console` command has been added for attaching to your keyboard's console. It operates similiarly to QMK Toolbox by allowing you to connect to one or more keyboard consoles to display debugging messages.
|
A new `qmk console` command has been added for attaching to your keyboard's console. It operates similiarly to QMK Toolbox by allowing you to connect to one or more keyboard consoles to display debugging messages.
|
||||||
|
|
||||||
### Improved command: qmk config :id=improve-command-qmk-config
|
### Improved command: qmk config {#improve-command-qmk-config}
|
||||||
|
|
||||||
We've updated the `qmk config` command to show only the configuration items you have actually set. You can now display (almost) all of the available configuration options, along with their default values, using `qmk config -a`.
|
We've updated the `qmk config` command to show only the configuration items you have actually set. You can now display (almost) all of the available configuration options, along with their default values, using `qmk config -a`.
|
||||||
|
|
||||||
### LED Matrix Improvements ([#12509](https://github.com/qmk/qmk_firmware/pull/12509), [#12580](https://github.com/qmk/qmk_firmware/pull/12580), [#12588](https://github.com/qmk/qmk_firmware/pull/12588), [#12633](https://github.com/qmk/qmk_firmware/pull/12633), [#12651](https://github.com/qmk/qmk_firmware/pull/12651), [#12685](https://github.com/qmk/qmk_firmware/pull/12685)) :id=led-matrix-improvements
|
### LED Matrix Improvements ([#12509](https://github.com/qmk/qmk_firmware/pull/12509), [#12580](https://github.com/qmk/qmk_firmware/pull/12580), [#12588](https://github.com/qmk/qmk_firmware/pull/12588), [#12633](https://github.com/qmk/qmk_firmware/pull/12633), [#12651](https://github.com/qmk/qmk_firmware/pull/12651), [#12685](https://github.com/qmk/qmk_firmware/pull/12685)) {#led-matrix-improvements}
|
||||||
|
|
||||||
LED Matrix has been improved with effects, CIE1931 curves, and a task system.
|
LED Matrix has been improved with effects, CIE1931 curves, and a task system.
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
* Durgod keyboard refactor in preparation for adding additional durgod keyboards ([#11978](https://github.com/qmk/qmk_firmware/pull/11978))
|
* Durgod keyboard refactor in preparation for adding additional durgod keyboards ([#11978](https://github.com/qmk/qmk_firmware/pull/11978))
|
||||||
* Updated Function96 with V2 files and removed chconf.h and halconf.h ([#12613](https://github.com/qmk/qmk_firmware/pull/12613))
|
* Updated Function96 with V2 files and removed chconf.h and halconf.h ([#12613](https://github.com/qmk/qmk_firmware/pull/12613))
|
||||||
|
@ -52,7 +52,7 @@ The codebase for the [Durgod K320](https://github.com/qmk/qmk_firmware/tree/0.13
|
||||||
|
|
||||||
Additionally, the `crkbd/rev1/legacy` keyboard has been removed.
|
Additionally, the `crkbd/rev1/legacy` keyboard has been removed.
|
||||||
|
|
||||||
### Bootmagic Deprecation and Refactor ([#12172](https://github.com/qmk/qmk_firmware/pull/12172)) :id=bootmagic-deprecation-and-refactor
|
### Bootmagic Deprecation and Refactor ([#12172](https://github.com/qmk/qmk_firmware/pull/12172)) {#bootmagic-deprecation-and-refactor}
|
||||||
|
|
||||||
QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
|
QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
|
||||||
|
|
||||||
|
@ -68,11 +68,11 @@ This is the current planned roadmap for the behavior of `BOOTMAGIC_ENABLE`:
|
||||||
- From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` – setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail.
|
- From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` – setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail.
|
||||||
- From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` – setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail.
|
- From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` – setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail.
|
||||||
|
|
||||||
### Removal of LAYOUT_kc ([#12160](https://github.com/qmk/qmk_firmware/pull/12160)) :id=removal-of-layout-kc
|
### Removal of LAYOUT_kc ([#12160](https://github.com/qmk/qmk_firmware/pull/12160)) {#removal-of-layout-kc}
|
||||||
|
|
||||||
We've removed support for `LAYOUT_kc` macros, if your keymap uses one you will need to update it use a regular `LAYOUT` macro.
|
We've removed support for `LAYOUT_kc` macros, if your keymap uses one you will need to update it use a regular `LAYOUT` macro.
|
||||||
|
|
||||||
### Encoder callbacks are now boolean ([#12805](https://github.com/qmk/qmk_firmware/pull/12805), [#12985](https://github.com/qmk/qmk_firmware/pull/12985)) :id=encoder-callback-boolean
|
### Encoder callbacks are now boolean ([#12805](https://github.com/qmk/qmk_firmware/pull/12805), [#12985](https://github.com/qmk/qmk_firmware/pull/12985)) {#encoder-callback-boolean}
|
||||||
|
|
||||||
To allow for keyboards to override (or not) keymap level code the `encoder_update_kb` function has been changed from `void` to `bool`. You will need to update your function definition to reflect this and ensure that you return a `true` or `false` value.
|
To allow for keyboards to override (or not) keymap level code the `encoder_update_kb` function has been changed from `void` to `bool`. You will need to update your function definition to reflect this and ensure that you return a `true` or `false` value.
|
||||||
|
|
||||||
|
@ -127,9 +127,9 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Core Changes :id=core-changes
|
## Core Changes {#core-changes}
|
||||||
|
|
||||||
### Fixes :id=core-fixes
|
### Fixes {#core-fixes}
|
||||||
|
|
||||||
* Fix connection issue in split keyboards when slave and OLED display are connected via I2C (fixes #9335) ([#11487](https://github.com/qmk/qmk_firmware/pull/11487))
|
* Fix connection issue in split keyboards when slave and OLED display are connected via I2C (fixes #9335) ([#11487](https://github.com/qmk/qmk_firmware/pull/11487))
|
||||||
* Terrazzo: Fix wrong LED Matrix function names ([#12561](https://github.com/qmk/qmk_firmware/pull/12561))
|
* Terrazzo: Fix wrong LED Matrix function names ([#12561](https://github.com/qmk/qmk_firmware/pull/12561))
|
||||||
|
@ -147,7 +147,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||||
* [Keyboard] Fix Terrazzo build failure ([#12977](https://github.com/qmk/qmk_firmware/pull/12977))
|
* [Keyboard] Fix Terrazzo build failure ([#12977](https://github.com/qmk/qmk_firmware/pull/12977))
|
||||||
* Do not hard set config in CPTC files ([#11864](https://github.com/qmk/qmk_firmware/pull/11864))
|
* Do not hard set config in CPTC files ([#11864](https://github.com/qmk/qmk_firmware/pull/11864))
|
||||||
|
|
||||||
### Additions and Enhancements :id=core-additions
|
### Additions and Enhancements {#core-additions}
|
||||||
|
|
||||||
* ARM - Refactor SLEEP_LED to support more platforms ([#8403](https://github.com/qmk/qmk_firmware/pull/8403))
|
* ARM - Refactor SLEEP_LED to support more platforms ([#8403](https://github.com/qmk/qmk_firmware/pull/8403))
|
||||||
* Add ability to toggle One Shot functionality ([#4198](https://github.com/qmk/qmk_firmware/pull/4198))
|
* Add ability to toggle One Shot functionality ([#4198](https://github.com/qmk/qmk_firmware/pull/4198))
|
||||||
|
@ -193,7 +193,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||||
* Backlight: add defines for default level and breathing state ([#12560](https://github.com/qmk/qmk_firmware/pull/12560), [#13024](https://github.com/qmk/qmk_firmware/pull/13024))
|
* Backlight: add defines for default level and breathing state ([#12560](https://github.com/qmk/qmk_firmware/pull/12560), [#13024](https://github.com/qmk/qmk_firmware/pull/13024))
|
||||||
* Add dire message about LUFA mass storage bootloader ([#13014](https://github.com/qmk/qmk_firmware/pull/13014))
|
* Add dire message about LUFA mass storage bootloader ([#13014](https://github.com/qmk/qmk_firmware/pull/13014))
|
||||||
|
|
||||||
### Clean-ups and Optimizations :id=core-optimizations
|
### Clean-ups and Optimizations {#core-optimizations}
|
||||||
|
|
||||||
* Overhaul bootmagic logic to have single entrypoint ([#8532](https://github.com/qmk/qmk_firmware/pull/8532))
|
* Overhaul bootmagic logic to have single entrypoint ([#8532](https://github.com/qmk/qmk_firmware/pull/8532))
|
||||||
* Refactor of USB code within split_common ([#11890](https://github.com/qmk/qmk_firmware/pull/11890))
|
* Refactor of USB code within split_common ([#11890](https://github.com/qmk/qmk_firmware/pull/11890))
|
||||||
|
@ -218,7 +218,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||||
* Deprecate `send_unicode_hex_string()` ([#12602](https://github.com/qmk/qmk_firmware/pull/12602))
|
* Deprecate `send_unicode_hex_string()` ([#12602](https://github.com/qmk/qmk_firmware/pull/12602))
|
||||||
* [Keyboard] Remove redundant legacy and common headers for crkbd ([#13023](https://github.com/qmk/qmk_firmware/pull/13023))
|
* [Keyboard] Remove redundant legacy and common headers for crkbd ([#13023](https://github.com/qmk/qmk_firmware/pull/13023))
|
||||||
|
|
||||||
### QMK Infrastructure and Internals :id=qmk-internals
|
### QMK Infrastructure and Internals {#qmk-internals}
|
||||||
|
|
||||||
* trivial change to trigger api update ([`b15288fb87`](https://github.com/qmk/qmk_firmware/commit/b15288fb87))
|
* trivial change to trigger api update ([`b15288fb87`](https://github.com/qmk/qmk_firmware/commit/b15288fb87))
|
||||||
* fix some references to bin/qmk that slipped in ([#12832](https://github.com/qmk/qmk_firmware/pull/12832))
|
* fix some references to bin/qmk that slipped in ([#12832](https://github.com/qmk/qmk_firmware/pull/12832))
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
# QMK Breaking Changes - 2021 August 28 Changelog
|
# QMK Breaking Changes - 2021 August 28 Changelog
|
||||||
|
|
||||||
## Notable Features :id=notable-features
|
## Notable Features {#notable-features}
|
||||||
|
|
||||||
### Combo processing improvements ([#8591](https://github.com/qmk/qmk_firmware/pull/8591)) :id=combo-processing-improvements
|
### Combo processing improvements ([#8591](https://github.com/qmk/qmk_firmware/pull/8591)) {#combo-processing-improvements}
|
||||||
|
|
||||||
Combo processing has been reordered with respect to keypress handling, allowing for much better compatibility with mod taps.
|
Combo processing has been reordered with respect to keypress handling, allowing for much better compatibility with mod taps.
|
||||||
|
|
||||||
It is also now possible to define combos that have keys overlapping with other combos, triggering only one. For example, a combo of `A`, `B` can coexist with a longer combo of `A`, `B`, `C` -- previous functionality would trigger both combos if all three keys were pressed.
|
It is also now possible to define combos that have keys overlapping with other combos, triggering only one. For example, a combo of `A`, `B` can coexist with a longer combo of `A`, `B`, `C` -- previous functionality would trigger both combos if all three keys were pressed.
|
||||||
|
|
||||||
### Key Overrides ([#11422](https://github.com/qmk/qmk_firmware/pull/11422)) :id=key-overrides
|
### Key Overrides ([#11422](https://github.com/qmk/qmk_firmware/pull/11422)) {#key-overrides}
|
||||||
|
|
||||||
QMK now has a new feature: [key overrides](https://docs.qmk.fm/#/feature_key_overrides). This feature allows for overriding the output of key combinations involving modifiers. As an example, pressing <kbd>Shift+2</kbd> normally results in an <kbd>@</kbd> on US-ANSI keyboard layouts -- the new key overrides allow for adding similar functionality, but for any <kbd>modifier + key</kbd> press.
|
QMK now has a new feature: [key overrides](../feature_key_overrides). This feature allows for overriding the output of key combinations involving modifiers. As an example, pressing <kbd>Shift+2</kbd> normally results in an <kbd>@</kbd> on US-ANSI keyboard layouts -- the new key overrides allow for adding similar functionality, but for any <kbd>modifier + key</kbd> press.
|
||||||
|
|
||||||
To illustrate, it's now possible to use the key overrides feature to translate <kbd>Shift + Backspace</kbd> into <kbd>Delete</kbd> -- an often-requested example of where this functionality comes in handy.
|
To illustrate, it's now possible to use the key overrides feature to translate <kbd>Shift + Backspace</kbd> into <kbd>Delete</kbd> -- an often-requested example of where this functionality comes in handy.
|
||||||
|
|
||||||
There's far more to describe that what lives in this changelog, so head over to the [key overrides documentation](https://docs.qmk.fm/#/feature_key_overrides) for more examples and info.
|
There's far more to describe that what lives in this changelog, so head over to the [key overrides documentation](../feature_key_overrides) for more examples and info.
|
||||||
|
|
||||||
### Digitizer support ([#12851](https://github.com/qmk/qmk_firmware/pull/12851))
|
### Digitizer support ([#12851](https://github.com/qmk/qmk_firmware/pull/12851))
|
||||||
|
|
||||||
QMK gained the ability to pretend to be a digitizer device -- much like a tablet device. A mouse uses delta-coordinates -- move up, move right -- but a digitizer works with absolute coordinates -- top left, bottom right.
|
QMK gained the ability to pretend to be a digitizer device -- much like a tablet device. A mouse uses delta-coordinates -- move up, move right -- but a digitizer works with absolute coordinates -- top left, bottom right.
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
The following keyboards have had their source moved within QMK:
|
The following keyboards have had their source moved within QMK:
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ xd84pro | xiudi/xd84pro
|
||||||
xd87 | xiudi/xd87
|
xd87 | xiudi/xd87
|
||||||
xd96 | xiudi/xd96
|
xd96 | xiudi/xd96
|
||||||
|
|
||||||
### Bootmagic Full Removal ([#13846](https://github.com/qmk/qmk_firmware/pull/13846)) :id=bootmagic-full-removal
|
### Bootmagic Full Removal ([#13846](https://github.com/qmk/qmk_firmware/pull/13846)) {#bootmagic-full-removal}
|
||||||
|
|
||||||
As noted during last breaking changes cycle, QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
|
As noted during last breaking changes cycle, QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ This is the current roadmap for the behavior of `BOOTMAGIC_ENABLE`:
|
||||||
- (now) From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` – setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail.
|
- (now) From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` – setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail.
|
||||||
- (next) From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` – setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail.
|
- (next) From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` – setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail.
|
||||||
|
|
||||||
### DIP switch callbacks are now boolean ([#13399](https://github.com/qmk/qmk_firmware/pull/13399)) :id=dip-switch-boolean
|
### DIP switch callbacks are now boolean ([#13399](https://github.com/qmk/qmk_firmware/pull/13399)) {#dip-switch-boolean}
|
||||||
|
|
||||||
To match the encoder change last breaking changes cycle, DIP switch callbacks now return `bool`, too.
|
To match the encoder change last breaking changes cycle, DIP switch callbacks now return `bool`, too.
|
||||||
|
|
||||||
|
@ -149,9 +149,9 @@ bool dip_switch_update_mask_user(uint32_t state) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Notable core changes :id=notable-core
|
## Notable core changes {#notable-core}
|
||||||
|
|
||||||
### Split transport improvements :id=split-transport-improvements
|
### Split transport improvements {#split-transport-improvements}
|
||||||
|
|
||||||
Split keyboards gained a significant amount of improvements during this breaking changes cycle, specifically:
|
Split keyboards gained a significant amount of improvements during this breaking changes cycle, specifically:
|
||||||
|
|
||||||
|
@ -160,9 +160,11 @@ Split keyboards gained a significant amount of improvements during this breaking
|
||||||
* Make solo half of split keyboards (more) usable. ([#13523](https://github.com/qmk/qmk_firmware/pull/13523)) -- allows the slave to be disconnected, enabling one-handed use.
|
* Make solo half of split keyboards (more) usable. ([#13523](https://github.com/qmk/qmk_firmware/pull/13523)) -- allows the slave to be disconnected, enabling one-handed use.
|
||||||
* Switch split_common to CRC subsystem ([#13418](https://github.com/qmk/qmk_firmware/pull/13418))
|
* Switch split_common to CRC subsystem ([#13418](https://github.com/qmk/qmk_firmware/pull/13418))
|
||||||
|
|
||||||
!> If you're updating your split keyboard, you will need to flash both sides of the split with the your firmware.
|
::: warning
|
||||||
|
If you're updating your split keyboard, you will need to flash both sides of the split with the your firmware.
|
||||||
|
:::
|
||||||
|
|
||||||
### Teensy 4.x support ([#13056](https://github.com/qmk/qmk_firmware/pull/13056), [#13076](https://github.com/qmk/qmk_firmware/pull/13076), [#13077](https://github.com/qmk/qmk_firmware/pull/13077)) :id=teensy-4-x-support
|
### Teensy 4.x support ([#13056](https://github.com/qmk/qmk_firmware/pull/13056), [#13076](https://github.com/qmk/qmk_firmware/pull/13076), [#13077](https://github.com/qmk/qmk_firmware/pull/13077)) {#teensy-4-x-support}
|
||||||
|
|
||||||
Updated ChibiOS and ChibiOS-Contrib, which brought in support for Teensy 4.x dev boards, running NXP i.MX1062.
|
Updated ChibiOS and ChibiOS-Contrib, which brought in support for Teensy 4.x dev boards, running NXP i.MX1062.
|
||||||
|
|
||||||
|
@ -243,7 +245,7 @@ We've added dozens of new keys to `info.json` so that you can configure more tha
|
||||||
* `usb.force_nkro`, `usb.max_power`, `usb.no_startup_check`, `usb.polling_interval`, `usb.shared_endpoint.keyboard`, `usb.shared_endpoint.mouse`, `usb.suspend_wakeup_delay`, `usb.wait_for`
|
* `usb.force_nkro`, `usb.max_power`, `usb.no_startup_check`, `usb.polling_interval`, `usb.shared_endpoint.keyboard`, `usb.shared_endpoint.mouse`, `usb.suspend_wakeup_delay`, `usb.wait_for`
|
||||||
* `qmk.keys_per_scan`, `qmk.tap_keycode_delay`, `qmk.tap_capslock_delay`
|
* `qmk.keys_per_scan`, `qmk.tap_keycode_delay`, `qmk.tap_capslock_delay`
|
||||||
|
|
||||||
### Codebase restructure and cleanup :id=codebase-restructure
|
### Codebase restructure and cleanup {#codebase-restructure}
|
||||||
|
|
||||||
QMK was originally based on TMK, and has grown in size considerably since its first inception. To keep moving things forward, restructure of some of the core areas of the code is needed to support new concepts and new hardware, and progress is happening along those lines:
|
QMK was originally based on TMK, and has grown in size considerably since its first inception. To keep moving things forward, restructure of some of the core areas of the code is needed to support new concepts and new hardware, and progress is happening along those lines:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# QMK Breaking Changes - 2021 November 27 Changelog
|
# QMK Breaking Changes - 2021 November 27 Changelog
|
||||||
|
|
||||||
## 2000 keyboards! :id=qmk-2000th-keyboard
|
## 2000 keyboards! {#qmk-2000th-keyboard}
|
||||||
|
|
||||||
QMK had it's 2000th keyboard submitted during this breaking changes cycle.... and it only _just_ made the cut-off!
|
QMK had it's 2000th keyboard submitted during this breaking changes cycle.... and it only _just_ made the cut-off!
|
||||||
|
|
||||||
|
@ -11,9 +11,9 @@ QMK had it's 2000th keyboard submitted during this breaking changes cycle.... an
|
||||||
|
|
||||||
From the whole QMK team, a major thankyou to the community for embracing QMK as your preferred keyboard firmware!
|
From the whole QMK team, a major thankyou to the community for embracing QMK as your preferred keyboard firmware!
|
||||||
|
|
||||||
## Notable Features :id=notable-features
|
## Notable Features {#notable-features}
|
||||||
|
|
||||||
### Expanded Pointing Device support ([#14343](https://github.com/qmk/qmk_firmware/pull/14343)) :id=expanded-pointing-device
|
### Expanded Pointing Device support ([#14343](https://github.com/qmk/qmk_firmware/pull/14343)) {#expanded-pointing-device}
|
||||||
|
|
||||||
Pointing device support has been reworked and reimplemented to allow for easier integration of new peripherals.
|
Pointing device support has been reworked and reimplemented to allow for easier integration of new peripherals.
|
||||||
|
|
||||||
|
@ -31,9 +31,9 @@ QMK now has core-supplied support for the following pointing device peripherals:
|
||||||
| `POINTING_DEVICE_DRIVER = pimoroni_trackball` | Pimoroni Trackball |
|
| `POINTING_DEVICE_DRIVER = pimoroni_trackball` | Pimoroni Trackball |
|
||||||
| `POINTING_DEVICE_DRIVER = pmw3360` | PMW 3360 |
|
| `POINTING_DEVICE_DRIVER = pmw3360` | PMW 3360 |
|
||||||
|
|
||||||
See the new documentation for the [Pointing Device](../feature_pointing_device.md) feature for more information on specific configuration for each driver.
|
See the new documentation for the [Pointing Device](../feature_pointing_device) feature for more information on specific configuration for each driver.
|
||||||
|
|
||||||
### Dynamic Tapping Term ([#11036](https://github.com/qmk/qmk_firmware/pull/11036)) :id=dynamic-tapping-term
|
### Dynamic Tapping Term ([#11036](https://github.com/qmk/qmk_firmware/pull/11036)) {#dynamic-tapping-term}
|
||||||
|
|
||||||
For people who are starting out with tapping keys, or for people who think tapping keys don't "feel right", it's sometimes quite difficult to determine what duration of tapping term to use to make things seem natural.
|
For people who are starting out with tapping keys, or for people who think tapping keys don't "feel right", it's sometimes quite difficult to determine what duration of tapping term to use to make things seem natural.
|
||||||
|
|
||||||
|
@ -47,9 +47,9 @@ If you're in this stage of discovery, you can now add `DYNAMIC_TAPPING_TERM_ENAB
|
||||||
|
|
||||||
Coupled with the use of `qmk console` or QMK Toolbox to show console output from your keyboard, you can tweak the tapping term dynamically in order to narrow down what "feels right" to you. Once you're happy, drop in the resulting number into your keymap's `config.h` and you're good to go!
|
Coupled with the use of `qmk console` or QMK Toolbox to show console output from your keyboard, you can tweak the tapping term dynamically in order to narrow down what "feels right" to you. Once you're happy, drop in the resulting number into your keymap's `config.h` and you're good to go!
|
||||||
|
|
||||||
### Macros in JSON keymaps ([#14374](https://github.com/qmk/qmk_firmware/pull/14374)) :id=macros-in-keymap-json
|
### Macros in JSON keymaps ([#14374](https://github.com/qmk/qmk_firmware/pull/14374)) {#macros-in-keymap-json}
|
||||||
|
|
||||||
You can now define up to 32 macros in your `keymap.json` file, as used by [QMK Configurator](newbs_building_firmware_configurator.md), and `qmk compile`. You can define these macros in a list under the `macros` keyword, like this:
|
You can now define up to 32 macros in your `keymap.json` file, as used by [QMK Configurator](../newbs_building_firmware_configurator), and `qmk compile`. You can define these macros in a list under the `macros` keyword, like this:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -83,9 +83,9 @@ You can now define up to 32 macros in your `keymap.json` file, as used by [QMK C
|
||||||
|
|
||||||
In due course, [QMK Configurator](https://config.qmk.fm/) will pick up support for defining these in its UI, but for now the json is the only way to define macros.
|
In due course, [QMK Configurator](https://config.qmk.fm/) will pick up support for defining these in its UI, but for now the json is the only way to define macros.
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
The following keyboards have had their source moved within QMK:
|
The following keyboards have had their source moved within QMK:
|
||||||
|
|
||||||
|
@ -104,21 +104,21 @@ The following keyboards have had their source moved within QMK:
|
||||||
| signum/3_0/elitec | signum/3_0 |
|
| signum/3_0/elitec | signum/3_0 |
|
||||||
| tgr/jane | tgr/jane/v2 |
|
| tgr/jane | tgr/jane/v2 |
|
||||||
|
|
||||||
### Squeezing space out of AVR ([#15243](https://github.com/qmk/qmk_firmware/pull/15243)) :id=squeezing-space-from-avr
|
### Squeezing space out of AVR ([#15243](https://github.com/qmk/qmk_firmware/pull/15243)) {#squeezing-space-from-avr}
|
||||||
|
|
||||||
The AVR platform has been problematic for some time, in the sense that it is severely resource-constrained -- this makes life difficult for anyone attempting to add new functionality such as display panels to their keymap code. The illustrious Drashna has contributed some newer documentation on how to attempt to free up some space on AVR-based keyboards that are in short supply.
|
The AVR platform has been problematic for some time, in the sense that it is severely resource-constrained -- this makes life difficult for anyone attempting to add new functionality such as display panels to their keymap code. The illustrious Drashna has contributed some newer documentation on how to attempt to free up some space on AVR-based keyboards that are in short supply.
|
||||||
|
|
||||||
Of course, there are much fewer constraints with ARM chips... ;)
|
Of course, there are much fewer constraints with ARM chips... ;)
|
||||||
|
|
||||||
### Require explicit enabling of RGB Matrix modes ([#15018](https://github.com/qmk/qmk_firmware/pull/15018)) :id=explicit-rgb-modes
|
### Require explicit enabling of RGB Matrix modes ([#15018](https://github.com/qmk/qmk_firmware/pull/15018)) {#explicit-rgb-modes}
|
||||||
|
|
||||||
Related to the previous section -- RGB Matrix modes have now been made to be opt-in, rather than opt-out. As these animations are now opt-in, you may find that your keyboard no longer has all the RGB modes you're expecting -- you may need to configure and recompile your firmware and enable your animations of choice... with any luck they'll still fit in the space available.
|
Related to the previous section -- RGB Matrix modes have now been made to be opt-in, rather than opt-out. As these animations are now opt-in, you may find that your keyboard no longer has all the RGB modes you're expecting -- you may need to configure and recompile your firmware and enable your animations of choice... with any luck they'll still fit in the space available.
|
||||||
|
|
||||||
Most keyboards keep their original functionality, but over time the QMK maintainers have found that removal of animations ends up being the quickest way to free up space... and some keyboards have had animations such as reactive effects disabled by default in order to still fit within the flash space available.
|
Most keyboards keep their original functionality, but over time the QMK maintainers have found that removal of animations ends up being the quickest way to free up space... and some keyboards have had animations such as reactive effects disabled by default in order to still fit within the flash space available.
|
||||||
|
|
||||||
The full list of configurables to turn specific animations back on can be found at on the [RGB Matrix documentation](feature_rgb_matrix.md#rgb-matrix-effects) page.
|
The full list of configurables to turn specific animations back on can be found at on the [RGB Matrix documentation](../feature_rgb_matrix#rgb-matrix-effects) page.
|
||||||
|
|
||||||
### OLED task refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/14864)) :id=oled-task-refactor
|
### OLED task refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/14864)) {#oled-task-refactor}
|
||||||
|
|
||||||
OLED display code was traditionally difficult to override in keymaps as they did not follow the standard pattern of `bool *_kb()` deferring to `bool *_user()` functions, allowing signalling to the higher level that processing had already been done.
|
OLED display code was traditionally difficult to override in keymaps as they did not follow the standard pattern of `bool *_kb()` deferring to `bool *_user()` functions, allowing signalling to the higher level that processing had already been done.
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ bool oled_task_kb(void) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Bootmagic Full Removal ([#15002](https://github.com/qmk/qmk_firmware/pull/15002)) :id=bootmagic-full-removal
|
### Bootmagic Full Removal ([#15002](https://github.com/qmk/qmk_firmware/pull/15002)) {#bootmagic-full-removal}
|
||||||
|
|
||||||
As noted during previous breaking changes cycles, QMK decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
|
As noted during previous breaking changes cycles, QMK decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
|
||||||
|
|
||||||
|
@ -170,13 +170,13 @@ This is the historical timeline for the behavior of `BOOTMAGIC_ENABLE`:
|
||||||
- (done) From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` – setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail.
|
- (done) From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` – setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail.
|
||||||
- (now) From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` – setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail.
|
- (now) From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` – setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail.
|
||||||
|
|
||||||
### Remove QWIIC_DRIVERS ([#14174](https://github.com/qmk/qmk_firmware/pull/14174)) :id=remove-qwiic
|
### Remove QWIIC_DRIVERS ([#14174](https://github.com/qmk/qmk_firmware/pull/14174)) {#remove-qwiic}
|
||||||
|
|
||||||
Due to minimal QWIIC adoption and other options for similar functionality, the QWIIC drivers were removed from QMK. Existing OLED usages have been migrated across to the normal QMK OLED driver instead.
|
Due to minimal QWIIC adoption and other options for similar functionality, the QWIIC drivers were removed from QMK. Existing OLED usages have been migrated across to the normal QMK OLED driver instead.
|
||||||
|
|
||||||
## Notable core changes :id=notable-core
|
## Notable core changes {#notable-core}
|
||||||
|
|
||||||
### New MCU Support :id=new-mcu-support
|
### New MCU Support {#new-mcu-support}
|
||||||
|
|
||||||
QMK firmware picked up support for a handful of new MCU families, potentially making it a bit easier to source components.
|
QMK firmware picked up support for a handful of new MCU families, potentially making it a bit easier to source components.
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ QMK firmware is now no longer limited to AVR and ARM - it also picked up support
|
||||||
* Westberrytech pr ([#14422](https://github.com/qmk/qmk_firmware/pull/14422))
|
* Westberrytech pr ([#14422](https://github.com/qmk/qmk_firmware/pull/14422))
|
||||||
* Initial pass of F405 support ([#14584](https://github.com/qmk/qmk_firmware/pull/14584))
|
* Initial pass of F405 support ([#14584](https://github.com/qmk/qmk_firmware/pull/14584))
|
||||||
|
|
||||||
### EEPROM Changes :id=eeprom-changes
|
### EEPROM Changes {#eeprom-changes}
|
||||||
|
|
||||||
There were a few EEPROM-related changes that landed during this breaking changes cycle, most prominently the long-awaited ability for the Drop boards to gain persistent storage. Any users of the Drop CTRL or Drop ALT should update QMK Toolbox as well -- coupled with a QMK firmware update settings should now be saved.
|
There were a few EEPROM-related changes that landed during this breaking changes cycle, most prominently the long-awaited ability for the Drop boards to gain persistent storage. Any users of the Drop CTRL or Drop ALT should update QMK Toolbox as well -- coupled with a QMK firmware update settings should now be saved.
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ There were a few EEPROM-related changes that landed during this breaking changes
|
||||||
* Further tidy up of STM32 eeprom emulation ([#14591](https://github.com/qmk/qmk_firmware/pull/14591))
|
* Further tidy up of STM32 eeprom emulation ([#14591](https://github.com/qmk/qmk_firmware/pull/14591))
|
||||||
* Enable eeprom with F401xE ld ([#14752](https://github.com/qmk/qmk_firmware/pull/14752))
|
* Enable eeprom with F401xE ld ([#14752](https://github.com/qmk/qmk_firmware/pull/14752))
|
||||||
|
|
||||||
### Compilation Database :id=compile-commands
|
### Compilation Database {#compile-commands}
|
||||||
|
|
||||||
A clang-compatible compilation database generator has been added as an option in order to help development environments such as Visual Studio Code.
|
A clang-compatible compilation database generator has been added as an option in order to help development environments such as Visual Studio Code.
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ Do note that switching keyboards will require re-generation of this file.
|
||||||
* New CLI subcommand to create clang-compatible compilation database (`compile_commands.json`) ([#14370](https://github.com/qmk/qmk_firmware/pull/14370))
|
* New CLI subcommand to create clang-compatible compilation database (`compile_commands.json`) ([#14370](https://github.com/qmk/qmk_firmware/pull/14370))
|
||||||
* compiledb: query include paths from gcc directly. ([#14462](https://github.com/qmk/qmk_firmware/pull/14462))
|
* compiledb: query include paths from gcc directly. ([#14462](https://github.com/qmk/qmk_firmware/pull/14462))
|
||||||
|
|
||||||
### Codebase restructure and cleanup :id=codebase-restructure
|
### Codebase restructure and cleanup {#codebase-restructure}
|
||||||
|
|
||||||
QMK continues on its restructuring journey, in order to make it easier to integrate newer features and add support for new hardware. This quarter's batch of changes include:
|
QMK continues on its restructuring journey, in order to make it easier to integrate newer features and add support for new hardware. This quarter's batch of changes include:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# QMK Breaking Changes - 2022 February 26 Changelog
|
# QMK Breaking Changes - 2022 February 26 Changelog
|
||||||
|
|
||||||
## Notable Features :id=notable-features
|
## Notable Features {#notable-features}
|
||||||
|
|
||||||
### Default USB Polling rate now 1kHz ([#15352](https://github.com/qmk/qmk_firmware/pull/15352))
|
### Default USB Polling rate now 1kHz ([#15352](https://github.com/qmk/qmk_firmware/pull/15352))
|
||||||
|
|
||||||
|
@ -12,13 +12,13 @@ Something something *Lets go gamers!*
|
||||||
|
|
||||||
Pointing devices can now be shared across a split keyboard with support for a single pointing device or a pointing device on each side.
|
Pointing devices can now be shared across a split keyboard with support for a single pointing device or a pointing device on each side.
|
||||||
|
|
||||||
See the [Pointing Device](feature_pointing_device.md) documentation for further configuration options.
|
See the [Pointing Device](../feature_pointing_device) documentation for further configuration options.
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Legacy macro and action_function system removed ([#16025](https://github.com/qmk/qmk_firmware/pull/16025))
|
### Legacy macro and action_function system removed ([#16025](https://github.com/qmk/qmk_firmware/pull/16025))
|
||||||
|
|
||||||
The long time deprecated `MACRO()` and `action_get_macro` methods have been removed. Where possible, existing usages have been migrated over to core [Macros](feature_macros.md).
|
The long time deprecated `MACRO()` and `action_get_macro` methods have been removed. Where possible, existing usages have been migrated over to core [Macros](../feature_macros).
|
||||||
|
|
||||||
### Create a build error if no bootloader is specified ([#16181](https://github.com/qmk/qmk_firmware/pull/16181))
|
### Create a build error if no bootloader is specified ([#16181](https://github.com/qmk/qmk_firmware/pull/16181))
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ Bootloader configuration is no longer assumed. Keyboards must now set either:
|
||||||
|
|
||||||
In preparation of future bluetooth work, the `AdafruitBLE` integration has been renamed to allow potential for any other Adafruit BLE products.
|
In preparation of future bluetooth work, the `AdafruitBLE` integration has been renamed to allow potential for any other Adafruit BLE products.
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
The following keyboards have had their source moved within QMK:
|
The following keyboards have had their source moved within QMK:
|
||||||
|
|
||||||
|
@ -241,9 +241,9 @@ The following keyboards have had their source moved within QMK:
|
||||||
| zinc/rev1 | 25keys/zinc/rev1 |
|
| zinc/rev1 | 25keys/zinc/rev1 |
|
||||||
| zinc/reva | 25keys/zinc/reva |
|
| zinc/reva | 25keys/zinc/reva |
|
||||||
|
|
||||||
## Notable core changes :id=notable-core
|
## Notable core changes {#notable-core}
|
||||||
|
|
||||||
### New MCU Support :id=new-mcu-support
|
### New MCU Support {#new-mcu-support}
|
||||||
|
|
||||||
Building on previous cycles, QMK firmware picked up support for a couple extra MCU variants:
|
Building on previous cycles, QMK firmware picked up support for a couple extra MCU variants:
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
# QMK Breaking Changes - 2022 May 28 Changelog
|
# QMK Breaking Changes - 2022 May 28 Changelog
|
||||||
|
|
||||||
## Notable Features :id=notable-features
|
## Notable Features {#notable-features}
|
||||||
|
|
||||||
### Caps Word ([#16588](https://github.com/qmk/qmk_firmware/pull/16588)) :id=caps-word
|
### Caps Word ([#16588](https://github.com/qmk/qmk_firmware/pull/16588)) {#caps-word}
|
||||||
|
|
||||||
This is a new feature that allows for capslock-like functionality that turns itself off at the end of the word.
|
This is a new feature that allows for capslock-like functionality that turns itself off at the end of the word.
|
||||||
|
|
||||||
For instance, if you wish to type "QMK" without holding shift the entire time, you can either tap both left and right shift, or double-tap shift, to turn on _Caps Word_ -- then type `qmk` (lowercase) without holding shift. Once you hit any key other than `a`--`z`, `0`--`9`, `-`, `_`, delete, or backspace, this will go back to normal typing!
|
For instance, if you wish to type "QMK" without holding shift the entire time, you can either tap both left and right shift, or double-tap shift, to turn on _Caps Word_ -- then type `qmk` (lowercase) without holding shift. Once you hit any key other than `a`--`z`, `0`--`9`, `-`, `_`, delete, or backspace, this will go back to normal typing!
|
||||||
|
|
||||||
There are other activation mechanisms as well as configurable options like timeout and the like -- see the [Caps Word documentation](feature_caps_word.md) for more information.
|
There are other activation mechanisms as well as configurable options like timeout and the like -- see the [Caps Word documentation](../feature_caps_word) for more information.
|
||||||
|
|
||||||
### Quantum Painter ([#10174](https://github.com/qmk/qmk_firmware/pull/10174)) :id=quantum-painter
|
### Quantum Painter ([#10174](https://github.com/qmk/qmk_firmware/pull/10174)) {#quantum-painter}
|
||||||
|
|
||||||
QMK has had support for small OLED displays for some time now, but hasn't really gained too much ability to draw to panels other than the SSD1306 or SH1106 panels.
|
QMK has had support for small OLED displays for some time now, but hasn't really gained too much ability to draw to panels other than the SSD1306 or SH1106 panels.
|
||||||
|
|
||||||
|
@ -18,27 +18,31 @@ Quantum Painter is a new drawing subsystem available to suitable ARM and RISC-V
|
||||||
|
|
||||||
The QMK CLI has new commands added to be able to generate images and fonts for Quantum Painter to digest -- it's even capable of converting animated gifs for display on screen.
|
The QMK CLI has new commands added to be able to generate images and fonts for Quantum Painter to digest -- it's even capable of converting animated gifs for display on screen.
|
||||||
|
|
||||||
See the [Quantum Painter documentation](quantum_painter.md) for more information on how to set up the displays as well as how to convert images and fonts.
|
See the [Quantum Painter documentation](../quantum_painter) for more information on how to set up the displays as well as how to convert images and fonts.
|
||||||
|
|
||||||
!> Quantum Painter is not supported on AVR due to complexity and size constraints. Boards based on AVR such as ProMicro or Elite-C builds will not be able to leverage Quantum Painter.
|
::: warning
|
||||||
|
Quantum Painter is not supported on AVR due to complexity and size constraints. Boards based on AVR such as ProMicro or Elite-C builds will not be able to leverage Quantum Painter.
|
||||||
|
:::
|
||||||
|
|
||||||
### Encoder Mapping ([#13286](https://github.com/qmk/qmk_firmware/pull/13286)) :id=encoder-mapping
|
### Encoder Mapping ([#13286](https://github.com/qmk/qmk_firmware/pull/13286)) {#encoder-mapping}
|
||||||
|
|
||||||
One of the long-standing complaints with Encoders is that there has been no easy way to configure them in user keymaps. [#13286](https://github.com/qmk/qmk_firmware/pull/13286) added support for [Encoder Mapping](feature_encoders.md#encoder-map), which allows users to define encoder functionality in a similar way to their normal keymap.
|
One of the long-standing complaints with Encoders is that there has been no easy way to configure them in user keymaps. [#13286](https://github.com/qmk/qmk_firmware/pull/13286) added support for [Encoder Mapping](../feature_encoders#encoder-map), which allows users to define encoder functionality in a similar way to their normal keymap.
|
||||||
|
|
||||||
!> This is not yet supported by QMK Configurator. It is also unlikely to ever be supported by VIA.
|
::: warning
|
||||||
|
This is not yet supported by QMK Configurator. It is also unlikely to ever be supported by VIA.
|
||||||
|
:::
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### `RESET` => `QK_BOOT` ([#17037](https://github.com/qmk/qmk_firmware/pull/17037)) :id=reset-2-qk_boot
|
### `RESET` => `QK_BOOT` ([#17037](https://github.com/qmk/qmk_firmware/pull/17037)) {#reset-2-qk_boot}
|
||||||
|
|
||||||
QMK is always in the process of picking up support for new hardware platforms. One of the side-effects for future integrations has shown that QMK's usage of `RESET` as a keycode is causing naming collisions. As a result, [#17037](https://github.com/qmk/qmk_firmware/pull/17037) changed usages of `RESET` to the new keycode `QK_BOOT` in the majority of default-like keymaps. At this stage the old keycode is still usable but will likely be removed in the next breaking changes cycle. Users with keymaps containing `RESET` should also move to `QK_BOOT`.
|
QMK is always in the process of picking up support for new hardware platforms. One of the side-effects for future integrations has shown that QMK's usage of `RESET` as a keycode is causing naming collisions. As a result, [#17037](https://github.com/qmk/qmk_firmware/pull/17037) changed usages of `RESET` to the new keycode `QK_BOOT` in the majority of default-like keymaps. At this stage the old keycode is still usable but will likely be removed in the next breaking changes cycle. Users with keymaps containing `RESET` should also move to `QK_BOOT`.
|
||||||
|
|
||||||
### Sendstring keycode overhaul ([#16941](https://github.com/qmk/qmk_firmware/pull/16941)) :id=sendstring-keycodes
|
### Sendstring keycode overhaul ([#16941](https://github.com/qmk/qmk_firmware/pull/16941)) {#sendstring-keycodes}
|
||||||
|
|
||||||
Some keycodes used with `SEND_STRING` and its relatives have been deprecated and may have their old keycode usages removed at a later date. The list of [deprecated keycodes](https://github.com/qmk/qmk_firmware/blob/ebd402788346aa6e88bde1486b2a835684d40d39/quantum/send_string_keycodes.h#L456-L505) should be consulted to determine if you're using one of the older names (the first identifier after `#define`) -- you should swap to the newer variant (the second identifier on the same line).
|
Some keycodes used with `SEND_STRING` and its relatives have been deprecated and may have their old keycode usages removed at a later date. The list of [deprecated keycodes](https://github.com/qmk/qmk_firmware/blob/ebd402788346aa6e88bde1486b2a835684d40d39/quantum/send_string_keycodes.h#L456-L505) should be consulted to determine if you're using one of the older names (the first identifier after `#define`) -- you should swap to the newer variant (the second identifier on the same line).
|
||||||
|
|
||||||
### Pillow Installation ([#17133](https://github.com/qmk/qmk_firmware/pull/17133)) :id=pillow-install
|
### Pillow Installation ([#17133](https://github.com/qmk/qmk_firmware/pull/17133)) {#pillow-install}
|
||||||
|
|
||||||
The merge of Quantum Painter added some new dependencies in the QMK CLI, most notably _Pillow_, which requires some installation in order for the CLI to function. If you've got an existing installation, you'll need to run some commands in order to get things working:
|
The merge of Quantum Painter added some new dependencies in the QMK CLI, most notably _Pillow_, which requires some installation in order for the CLI to function. If you've got an existing installation, you'll need to run some commands in order to get things working:
|
||||||
|
|
||||||
|
@ -62,7 +66,7 @@ On Linux or WSL:
|
||||||
python3 -m pip install --user --upgrade qmk
|
python3 -m pip install --user --upgrade qmk
|
||||||
```
|
```
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
The following keyboards have had their source moved within QMK:
|
The following keyboards have had their source moved within QMK:
|
||||||
|
|
||||||
|
@ -97,7 +101,7 @@ The following keyboards have had their source moved within QMK:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Full changelist :id=full-changelist
|
## Full changelist {#full-changelist}
|
||||||
|
|
||||||
Core:
|
Core:
|
||||||
* Quantum Painter ([#10174](https://github.com/qmk/qmk_firmware/pull/10174))
|
* Quantum Painter ([#10174](https://github.com/qmk/qmk_firmware/pull/10174))
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
# QMK Breaking Changes - 2022 August 27 Changelog
|
# QMK Breaking Changes - 2022 August 27 Changelog
|
||||||
|
|
||||||
## Notable Features :id=notable-features
|
## Notable Features {#notable-features}
|
||||||
|
|
||||||
### Add Raspberry Pi RP2040 support ([#14877](https://github.com/qmk/qmk_firmware/pull/14877), [#17514](https://github.com/qmk/qmk_firmware/pull/17514), [#17516](https://github.com/qmk/qmk_firmware/pull/17516), [#17519](https://github.com/qmk/qmk_firmware/pull/17519), [#17612](https://github.com/qmk/qmk_firmware/pull/17612), [#17512](https://github.com/qmk/qmk_firmware/pull/17512), [#17557](https://github.com/qmk/qmk_firmware/pull/17557), [#17817](https://github.com/qmk/qmk_firmware/pull/17817), [#17839](https://github.com/qmk/qmk_firmware/pull/17839), [#18100](https://github.com/qmk/qmk_firmware/pull/18100)) :id=rp2040-support
|
### Add Raspberry Pi RP2040 support ([#14877](https://github.com/qmk/qmk_firmware/pull/14877), [#17514](https://github.com/qmk/qmk_firmware/pull/17514), [#17516](https://github.com/qmk/qmk_firmware/pull/17516), [#17519](https://github.com/qmk/qmk_firmware/pull/17519), [#17612](https://github.com/qmk/qmk_firmware/pull/17612), [#17512](https://github.com/qmk/qmk_firmware/pull/17512), [#17557](https://github.com/qmk/qmk_firmware/pull/17557), [#17817](https://github.com/qmk/qmk_firmware/pull/17817), [#17839](https://github.com/qmk/qmk_firmware/pull/17839), [#18100](https://github.com/qmk/qmk_firmware/pull/18100)) {#rp2040-support}
|
||||||
|
|
||||||
QMK _finally_ picked up support for RP2040-based boards, such as the Raspberry Pi Pico, the Sparkfun Pro Micro RP2040, and the Adafruit KB2040. One of QMK's newest collaborators, _@KarlK90_, effectively did `/micdrop` with RP2040, with a massive set of changes to both QMK and the repository QMK uses for the base platform support, ChibiOS[-Contrib]. There has been a flurry of development this breaking changes cycle related to RP2040 from a large number of contributors -- so much so that almost all standard QMK hardware subsystems are supported.
|
QMK _finally_ picked up support for RP2040-based boards, such as the Raspberry Pi Pico, the Sparkfun Pro Micro RP2040, and the Adafruit KB2040. One of QMK's newest collaborators, _@KarlK90_, effectively did `/micdrop` with RP2040, with a massive set of changes to both QMK and the repository QMK uses for the base platform support, ChibiOS[-Contrib]. There has been a flurry of development this breaking changes cycle related to RP2040 from a large number of contributors -- so much so that almost all standard QMK hardware subsystems are supported.
|
||||||
|
|
||||||
Check the [RP2040 platform development page](platformdev_rp2040.md) for all supported peripherals and other hardware implementation details.
|
Check the [RP2040 platform development page](../platformdev_rp2040) for all supported peripherals and other hardware implementation details.
|
||||||
|
|
||||||
### Allow `qmk flash` to use prebuilt firmware binaries ([#16584](https://github.com/qmk/qmk_firmware/pull/16584)) :id=cli-flash-binaries
|
### Allow `qmk flash` to use prebuilt firmware binaries ([#16584](https://github.com/qmk/qmk_firmware/pull/16584)) {#cli-flash-binaries}
|
||||||
|
|
||||||
A long-requested capability of the QMK CLI has been the ability to flash binaries directly, without needing to build a firmware. QMK provides prebuilt `develop`-based default firmwares on our [CI page](https://qmk.tzarc.io/) -- normally people would need [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases/latest) to flash them. This new functionality written by _@Erovia_ allows `qmk flash` to be provided the prebuilt file instead, simplifying the workflow for people who haven't got Toolbox available.
|
A long-requested capability of the QMK CLI has been the ability to flash binaries directly, without needing to build a firmware. QMK provides prebuilt `develop`-based default firmwares on our [CI page](https://qmk.tzarc.io/) -- normally people would need [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases/latest) to flash them. This new functionality written by _@Erovia_ allows `qmk flash` to be provided the prebuilt file instead, simplifying the workflow for people who haven't got Toolbox available.
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Default layers dropped from 32 to 16 ([#15286](https://github.com/qmk/qmk_firmware/pull/15286))
|
### Default layers dropped from 32 to 16 ([#15286](https://github.com/qmk/qmk_firmware/pull/15286))
|
||||||
|
|
||||||
QMK allows for controlling the maximum number of layers it supports through `LAYER_STATE_(8|16|32)BIT`. Each definition allows for the same number of maximum layers -- `LAYER_STATE_8BIT` => 8 layers. There is also a corresponding firmware size decrease that goes along with smaller numbers -- given the vast majority of users don't use more than 16 layers the default has been swapped to 16. AVR users who were not previously specifying their max layer count may see some space freed up as a result.
|
QMK allows for controlling the maximum number of layers it supports through `LAYER_STATE_(8|16|32)BIT`. Each definition allows for the same number of maximum layers -- `LAYER_STATE_8BIT` => 8 layers. There is also a corresponding firmware size decrease that goes along with smaller numbers -- given the vast majority of users don't use more than 16 layers the default has been swapped to 16. AVR users who were not previously specifying their max layer count may see some space freed up as a result.
|
||||||
|
|
||||||
### `RESET` => `QK_BOOT` ([#17940](https://github.com/qmk/qmk_firmware/pull/17940)) :id=reset-2-qk_boot
|
### `RESET` => `QK_BOOT` ([#17940](https://github.com/qmk/qmk_firmware/pull/17940)) {#reset-2-qk_boot}
|
||||||
|
|
||||||
Following the last breaking changes cycle, QMK has been migrating usages of `RESET` to `QK_BOOT` due to naming collisions with our upstream board support packages. [#17940](https://github.com/qmk/qmk_firmware/pull/17940) converts user keymaps across to use the new keycode name. `RESET` should also move to `QK_BOOT`.
|
Following the last breaking changes cycle, QMK has been migrating usages of `RESET` to `QK_BOOT` due to naming collisions with our upstream board support packages. [#17940](https://github.com/qmk/qmk_firmware/pull/17940) converts user keymaps across to use the new keycode name. `RESET` should also move to `QK_BOOT`.
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
The following keyboards have had their source moved within QMK:
|
The following keyboards have had their source moved within QMK:
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ The following keyboards have had their source moved within QMK:
|
||||||
| idobao/id80/v1/ansi | idobao/id80/v2/ansi |
|
| idobao/id80/v1/ansi | idobao/id80/v2/ansi |
|
||||||
| idobao/id80/v1/iso | idobao/id80/v2/iso |
|
| idobao/id80/v1/iso | idobao/id80/v2/iso |
|
||||||
|
|
||||||
### Data-driven USB IDs Refactoring ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) :id=usb-ids-Refactoring
|
### Data-driven USB IDs Refactoring ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) {#usb-ids-Refactoring}
|
||||||
|
|
||||||
QMK has decided to deprecate the specification of USB IDs inside `config.h` in favour of `info.json`, eventually leaving data-driven as the only method to specify USB information.
|
QMK has decided to deprecate the specification of USB IDs inside `config.h` in favour of `info.json`, eventually leaving data-driven as the only method to specify USB information.
|
||||||
|
|
||||||
|
@ -67,25 +67,25 @@ Replaced by `info.json`:
|
||||||
- From 2022 Aug 27, specifying USB information in `config.h` will produce warnings during build but will still function as previously.
|
- From 2022 Aug 27, specifying USB information in `config.h` will produce warnings during build but will still function as previously.
|
||||||
- From 2022 Nov 26, specifying USB information in `config.h` will cause compilation to fail.
|
- From 2022 Nov 26, specifying USB information in `config.h` will cause compilation to fail.
|
||||||
|
|
||||||
## Notable core changes :id=notable-core
|
## Notable core changes {#notable-core}
|
||||||
|
|
||||||
### Board converters ([#17514](https://github.com/qmk/qmk_firmware/pull/17514), [#17603](https://github.com/qmk/qmk_firmware/pull/17603), [#17711](https://github.com/qmk/qmk_firmware/pull/17711), [#17827](https://github.com/qmk/qmk_firmware/pull/17827), [#17593](https://github.com/qmk/qmk_firmware/pull/17593), [#17652](https://github.com/qmk/qmk_firmware/pull/17652), [#17595](https://github.com/qmk/qmk_firmware/pull/17595)) :id=board-converters
|
### Board converters ([#17514](https://github.com/qmk/qmk_firmware/pull/17514), [#17603](https://github.com/qmk/qmk_firmware/pull/17603), [#17711](https://github.com/qmk/qmk_firmware/pull/17711), [#17827](https://github.com/qmk/qmk_firmware/pull/17827), [#17593](https://github.com/qmk/qmk_firmware/pull/17593), [#17652](https://github.com/qmk/qmk_firmware/pull/17652), [#17595](https://github.com/qmk/qmk_firmware/pull/17595)) {#board-converters}
|
||||||
|
|
||||||
Historically QMK had a `CONVERT_TO_PROTON_C` directive for `rules.mk` to allow people to replace an AVR-based Pro Micro with a QMK Proton C. Global parts shortages have prompted people to create their own pin-compatible boards -- QMK has made this conversion generic and now allows for drop-in replacements for a lot more boards. see the [Converters Feature](feature_converters.md) documentation for the full list of supported replacement boards -- in this breaking changes cycle we've gone from 1 to 7.
|
Historically QMK had a `CONVERT_TO_PROTON_C` directive for `rules.mk` to allow people to replace an AVR-based Pro Micro with a QMK Proton C. Global parts shortages have prompted people to create their own pin-compatible boards -- QMK has made this conversion generic and now allows for drop-in replacements for a lot more boards. see the [Converters Feature](../feature_converters) documentation for the full list of supported replacement boards -- in this breaking changes cycle we've gone from 1 to 7.
|
||||||
|
|
||||||
### Add cli command to import keyboard|keymap|kbfirmware ([#16668](https://github.com/qmk/qmk_firmware/pull/16668)) :id=cli-import
|
### Add cli command to import keyboard|keymap|kbfirmware ([#16668](https://github.com/qmk/qmk_firmware/pull/16668)) {#cli-import}
|
||||||
|
|
||||||
To help with importing keyboards and keymaps from other sources, _@zvecr_ added [#16668](https://github.com/qmk/qmk_firmware/pull/16668) which adds a new set of commands to the CLI to automatically import keyboards (`qmk import-keyboard -h`), keymaps (`qmk import-keymap -h`), and kbfirmware definitions (`qmk import-kbfirmware -h`) into QMK.
|
To help with importing keyboards and keymaps from other sources, _@zvecr_ added [#16668](https://github.com/qmk/qmk_firmware/pull/16668) which adds a new set of commands to the CLI to automatically import keyboards (`qmk import-keyboard -h`), keymaps (`qmk import-keymap -h`), and kbfirmware definitions (`qmk import-kbfirmware -h`) into QMK.
|
||||||
|
|
||||||
The now-EOL kbfirmware allowed people who aren't set up with QMK the ability to create keyboard firmwares without requiring a full installation of QMK. Unfortunately, it targets a 7-year-old version of QMK -- adding frustration for users who want the newest features, as well as for QMK maintainers who have to spend time explaining why QMK can't just accept a drive-by code drop from kbfirmware. With any luck, this new command helps both camps!
|
The now-EOL kbfirmware allowed people who aren't set up with QMK the ability to create keyboard firmwares without requiring a full installation of QMK. Unfortunately, it targets a 7-year-old version of QMK -- adding frustration for users who want the newest features, as well as for QMK maintainers who have to spend time explaining why QMK can't just accept a drive-by code drop from kbfirmware. With any luck, this new command helps both camps!
|
||||||
|
|
||||||
### Generic wear-leveling for EEPROM emulation ([#16996](https://github.com/qmk/qmk_firmware/pull/16996), [#17376](https://github.com/qmk/qmk_firmware/pull/17376), [#18102](https://github.com/qmk/qmk_firmware/pull/18102)) :id=wear-leveling
|
### Generic wear-leveling for EEPROM emulation ([#16996](https://github.com/qmk/qmk_firmware/pull/16996), [#17376](https://github.com/qmk/qmk_firmware/pull/17376), [#18102](https://github.com/qmk/qmk_firmware/pull/18102)) {#wear-leveling}
|
||||||
|
|
||||||
QMK has had the ability to write to internal MCU flash in order to emulate EEPROM for some time now, but it was only limited to a small number of MCUs. The base HAL used by QMK for a large number of ARM devices provides a "proper" embedded MCU flash driver, so _@tzarc_ decoupled the wear-leveling algorithm from the old flash writing code, improved it, wrote some tests, and enabled its use for a much larger number of other devices... including RP2040's XIP flash, and external SPI NOR Flash.
|
QMK has had the ability to write to internal MCU flash in order to emulate EEPROM for some time now, but it was only limited to a small number of MCUs. The base HAL used by QMK for a large number of ARM devices provides a "proper" embedded MCU flash driver, so _@tzarc_ decoupled the wear-leveling algorithm from the old flash writing code, improved it, wrote some tests, and enabled its use for a much larger number of other devices... including RP2040's XIP flash, and external SPI NOR Flash.
|
||||||
|
|
||||||
See the [EEPROM Driver](eeprom_driver.md) documentation for more information.
|
See the [EEPROM Driver](../eeprom_driver) documentation for more information.
|
||||||
|
|
||||||
### Pointing Device Improvements ([#16371](https://github.com/qmk/qmk_firmware/pull/16371), [#17111](https://github.com/qmk/qmk_firmware/pull/17111), [#17176](https://github.com/qmk/qmk_firmware/pull/17176), [#17482](https://github.com/qmk/qmk_firmware/pull/17482), [#17776](https://github.com/qmk/qmk_firmware/pull/17776), [#17613](https://github.com/qmk/qmk_firmware/pull/17613)) :id=pointing-device-improvements
|
### Pointing Device Improvements ([#16371](https://github.com/qmk/qmk_firmware/pull/16371), [#17111](https://github.com/qmk/qmk_firmware/pull/17111), [#17176](https://github.com/qmk/qmk_firmware/pull/17176), [#17482](https://github.com/qmk/qmk_firmware/pull/17482), [#17776](https://github.com/qmk/qmk_firmware/pull/17776), [#17613](https://github.com/qmk/qmk_firmware/pull/17613)) {#pointing-device-improvements}
|
||||||
|
|
||||||
Ever since Pointing Device Driver support and Split Pointing Device support were added by _@drashna_ and _@daskygit_, there has been increased interest in the development of the pointing device subsystem and its associated code.
|
Ever since Pointing Device Driver support and Split Pointing Device support were added by _@drashna_ and _@daskygit_, there has been increased interest in the development of the pointing device subsystem and its associated code.
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ Other related changes:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Full changelist :id=full-changelist
|
## Full changelist {#full-changelist}
|
||||||
|
|
||||||
Core:
|
Core:
|
||||||
* Tentative Teensy 3.5 support ([#14420](https://github.com/qmk/qmk_firmware/pull/14420))
|
* Tentative Teensy 3.5 support ([#14420](https://github.com/qmk/qmk_firmware/pull/14420))
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
# QMK Breaking Changes - 2022 November 26 Changelog
|
# QMK Breaking Changes - 2022 November 26 Changelog
|
||||||
|
|
||||||
## Notable Features :id=notable-features
|
## Notable Features {#notable-features}
|
||||||
|
|
||||||
### Autocorrect ([#15699](https://github.com/qmk/qmk_firmware/pull/15699)) :id=autocorrect
|
### Autocorrect ([#15699](https://github.com/qmk/qmk_firmware/pull/15699)) {#autocorrect}
|
||||||
|
|
||||||
_@getreuer_ in their infinite wisdom decided that autocorrect was a feature needed by QMK. As is customary, _@drashna_ adapted it to core and got it into a state that everyone else can use it. See [Feature: Autocorrect](feature_autocorrect.md) for more ifnormation (grin).
|
_@getreuer_ in their infinite wisdom decided that autocorrect was a feature needed by QMK. As is customary, _@drashna_ adapted it to core and got it into a state that everyone else can use it. See [Feature: Autocorrect](../feature_autocorrect) for more ifnormation (grin).
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
The following keyboards have had their source moved within QMK:
|
The following keyboards have had their source moved within QMK:
|
||||||
|
|
||||||
|
@ -23,17 +23,19 @@ The following keyboards have had their source moved within QMK:
|
||||||
| handwired/hillside/52 | hillside/52 |
|
| handwired/hillside/52 | hillside/52 |
|
||||||
| maple_computing/christmas_tree/V2017 | maple_computing/christmas_tree/v2017 |
|
| maple_computing/christmas_tree/V2017 | maple_computing/christmas_tree/v2017 |
|
||||||
|
|
||||||
### Keycodes refactoring :id=keycodes-overhaul-user-action
|
### Keycodes refactoring {#keycodes-overhaul-user-action}
|
||||||
|
|
||||||
QMK's keycodes got a very significant overhaul this breaking changes cycle, with the bulk of the work done by _@zvecr_ and _@fauxpark_ -- renaming, reordering, removing has been their focus in this area. In an attempt to standardise interoperation with host applications, keycode values now have strong versioning so that any connected application has confidence that the keys it thinks exist on the board actually match up with what's compiled in. These strongly-versioned keycode definitions are now published online and will not change, so tools that remap keycodes have a reference to work with. In future versions of QMK, any new or changed keycodes will result in a new version specification. See [API docs](api_docs.md#qmk-constants) for more information on the published versions if you're writing a tool to manage keycodes.
|
QMK's keycodes got a very significant overhaul this breaking changes cycle, with the bulk of the work done by _@zvecr_ and _@fauxpark_ -- renaming, reordering, removing has been their focus in this area. In an attempt to standardise interoperation with host applications, keycode values now have strong versioning so that any connected application has confidence that the keys it thinks exist on the board actually match up with what's compiled in. These strongly-versioned keycode definitions are now published online and will not change, so tools that remap keycodes have a reference to work with. In future versions of QMK, any new or changed keycodes will result in a new version specification. See [API docs](../api_docs#qmk-constants) for more information on the published versions if you're writing a tool to manage keycodes.
|
||||||
|
|
||||||
In most cases user keymaps in the repository have already been updated to reflect the new naming scheme. In some cases user keymaps outside the repository may strike a missing keycode with the old name -- it's highly likely that the name had already been deprecated for some time, and should have been updated previously.
|
In most cases user keymaps in the repository have already been updated to reflect the new naming scheme. In some cases user keymaps outside the repository may strike a missing keycode with the old name -- it's highly likely that the name had already been deprecated for some time, and should have been updated previously.
|
||||||
|
|
||||||
See below for the full list of changesets.
|
See below for the full list of changesets.
|
||||||
|
|
||||||
!> Keycode aliases have been put in place in most cases to cater for "old names" being mapped to "new names" -- the documentation already reflects all the new naming of keys.
|
::: warning
|
||||||
|
Keycode aliases have been put in place in most cases to cater for "old names" being mapped to "new names" -- the documentation already reflects all the new naming of keys.
|
||||||
|
:::
|
||||||
|
|
||||||
### Configuration Item Refactoring :id=config-refactoring
|
### Configuration Item Refactoring {#config-refactoring}
|
||||||
|
|
||||||
A number of configuration items have been renamed for consistency.
|
A number of configuration items have been renamed for consistency.
|
||||||
|
|
||||||
|
@ -66,7 +68,7 @@ Joystick configuration:
|
||||||
| JOYSTICK_AXES_COUNT | JOYSTICK_AXIS_COUNT |
|
| JOYSTICK_AXES_COUNT | JOYSTICK_AXIS_COUNT |
|
||||||
| JOYSTICK_AXES_RESOLUTION | JOYSTICK_AXIS_RESOLUTION |
|
| JOYSTICK_AXES_RESOLUTION | JOYSTICK_AXIS_RESOLUTION |
|
||||||
|
|
||||||
### Data-driven USB IDs Refactoring ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) :id=usb-ids-Refactoring
|
### Data-driven USB IDs Refactoring ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) {#usb-ids-Refactoring}
|
||||||
|
|
||||||
QMK has decided to deprecate the specification of USB IDs inside `config.h` in favour of `info.json`, leaving data-driven as the only method to specify USB information. As per the deprecation schedule put forward last breaking changes cycle, USB information must be specified in `info.json` instead.
|
QMK has decided to deprecate the specification of USB IDs inside `config.h` in favour of `info.json`, leaving data-driven as the only method to specify USB information. As per the deprecation schedule put forward last breaking changes cycle, USB information must be specified in `info.json` instead.
|
||||||
|
|
||||||
|
@ -92,7 +94,7 @@ Replaced by `info.json`:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### LED Indicator callback refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/18450)) :id=led-callback-refactor
|
### LED Indicator callback refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/18450)) {#led-callback-refactor}
|
||||||
|
|
||||||
_RGB Matrix_ and _LED Matrix_ Indicator display code was traditionally difficult to override in keymaps as they did not follow the standard pattern of `bool *_kb()` deferring to `bool *_user()` functions, allowing signalling to the higher level that processing had already been done.
|
_RGB Matrix_ and _LED Matrix_ Indicator display code was traditionally difficult to override in keymaps as they did not follow the standard pattern of `bool *_kb()` deferring to `bool *_user()` functions, allowing signalling to the higher level that processing had already been done.
|
||||||
|
|
||||||
|
@ -128,15 +130,15 @@ bool rgb_matrix_indicators_kb(void) {
|
||||||
|
|
||||||
The equivalent transformations should be done for LED Matrix boards.
|
The equivalent transformations should be done for LED Matrix boards.
|
||||||
|
|
||||||
### Unicode mode refactoring :id=unicode-mode-renaming
|
### Unicode mode refactoring {#unicode-mode-renaming}
|
||||||
|
|
||||||
Unicode modes were renamed in order to prevent collision with equivalent keycodes. The available values for `UNICODE_SELECTED_MODES` changed -- see [Feature: Unicode](feature_unicode.md#setting-the-input-mode) for the new list of values and how to configure them.
|
Unicode modes were renamed in order to prevent collision with equivalent keycodes. The available values for `UNICODE_SELECTED_MODES` changed -- see [Feature: Unicode](../feature_unicode#setting-the-input-mode) for the new list of values and how to configure them.
|
||||||
|
|
||||||
## Notable core changes :id=notable-core
|
## Notable core changes {#notable-core}
|
||||||
|
|
||||||
This breaking changes cycle, a lot of the core changes are related to cleanup and refactoring -- commonly called "tech debt".
|
This breaking changes cycle, a lot of the core changes are related to cleanup and refactoring -- commonly called "tech debt".
|
||||||
|
|
||||||
### Keycodes refactoring :id=keycodes-overhaul-core-changes
|
### Keycodes refactoring {#keycodes-overhaul-core-changes}
|
||||||
|
|
||||||
We aren't going to list each and every change -- they're far too numerous -- instead, we'll just list the related PRs in order to convey just how wide-reaching these changes were:
|
We aren't going to list each and every change -- they're far too numerous -- instead, we'll just list the related PRs in order to convey just how wide-reaching these changes were:
|
||||||
|
|
||||||
|
@ -181,7 +183,7 @@ We aren't going to list each and every change -- they're far too numerous -- ins
|
||||||
* Remove legacy sendstring keycodes ([#18749](https://github.com/qmk/qmk_firmware/pull/18749))
|
* Remove legacy sendstring keycodes ([#18749](https://github.com/qmk/qmk_firmware/pull/18749))
|
||||||
* Reworked backlight keycodes. ([#18961](https://github.com/qmk/qmk_firmware/pull/18961))
|
* Reworked backlight keycodes. ([#18961](https://github.com/qmk/qmk_firmware/pull/18961))
|
||||||
|
|
||||||
### Board Converters :id=board-converters
|
### Board Converters {#board-converters}
|
||||||
|
|
||||||
There was additional work in the space of board converters -- historically QMK allowed for "converting" a Pro Micro build to a QMK Proton-C build. The last few versions of QMK have added support for replacement boards much like the Proton-C, and this quarter was no exception:
|
There was additional work in the space of board converters -- historically QMK allowed for "converting" a Pro Micro build to a QMK Proton-C build. The last few versions of QMK have added support for replacement boards much like the Proton-C, and this quarter was no exception:
|
||||||
|
|
||||||
|
@ -191,9 +193,9 @@ There was additional work in the space of board converters -- historically QMK a
|
||||||
* Add Elite-Pi converter ([#18236](https://github.com/qmk/qmk_firmware/pull/18236))
|
* Add Elite-Pi converter ([#18236](https://github.com/qmk/qmk_firmware/pull/18236))
|
||||||
* Allow QK_MAKE to work with converters ([#18637](https://github.com/qmk/qmk_firmware/pull/18637))
|
* Allow QK_MAKE to work with converters ([#18637](https://github.com/qmk/qmk_firmware/pull/18637))
|
||||||
|
|
||||||
See [Feature: Converters](feature_converters.md) for the full list of board conversions available.
|
See [Feature: Converters](../feature_converters) for the full list of board conversions available.
|
||||||
|
|
||||||
### Pointing and Digitizer device updates :id=pointing-and-digitizer
|
### Pointing and Digitizer device updates {#pointing-and-digitizer}
|
||||||
|
|
||||||
Both pointing devices and digitizer got a host of updates this cycle. Inertia, automatic mouse layers, fixes for preventing sleep... you even get more buttons with digitizers!
|
Both pointing devices and digitizer got a host of updates this cycle. Inertia, automatic mouse layers, fixes for preventing sleep... you even get more buttons with digitizers!
|
||||||
|
|
||||||
|
@ -207,7 +209,7 @@ Both pointing devices and digitizer got a host of updates this cycle. Inertia, a
|
||||||
* Invert pointing device motion pin for cirque touchpads ([#18404](https://github.com/qmk/qmk_firmware/pull/18404))
|
* Invert pointing device motion pin for cirque touchpads ([#18404](https://github.com/qmk/qmk_firmware/pull/18404))
|
||||||
* Refactor more host code (programmable button & digitizer) ([#18565](https://github.com/qmk/qmk_firmware/pull/18565))
|
* Refactor more host code (programmable button & digitizer) ([#18565](https://github.com/qmk/qmk_firmware/pull/18565))
|
||||||
|
|
||||||
## Full changelist :id=full-changelist
|
## Full changelist {#full-changelist}
|
||||||
|
|
||||||
Core:
|
Core:
|
||||||
* quantum: led: split out led_update_ports() for customization of led behaviour ([#14452](https://github.com/qmk/qmk_firmware/pull/14452))
|
* quantum: led: split out led_update_ports() for customization of led behaviour ([#14452](https://github.com/qmk/qmk_firmware/pull/14452))
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# QMK Breaking Changes - 2023 February 26 Changelog
|
# QMK Breaking Changes - 2023 February 26 Changelog
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### `IGNORE_MOD_TAP_INTERRUPT` behaviour changes ([#15741](https://github.com/qmk/qmk_firmware/pull/15741)) :id=i-m-t-i
|
### `IGNORE_MOD_TAP_INTERRUPT` behaviour changes ([#15741](https://github.com/qmk/qmk_firmware/pull/15741)) {#i-m-t-i}
|
||||||
|
|
||||||
`IGNORE_MOD_TAP_INTERRUPT_PER_KEY` has been removed and `IGNORE_MOD_TAP_INTERRUPT` deprecated as a stepping stone towards making `IGNORE_MOD_TAP_INTERRUPT` the new default behavior for mod-taps in the future.
|
`IGNORE_MOD_TAP_INTERRUPT_PER_KEY` has been removed and `IGNORE_MOD_TAP_INTERRUPT` deprecated as a stepping stone towards making `IGNORE_MOD_TAP_INTERRUPT` the new default behavior for mod-taps in the future.
|
||||||
|
|
||||||
|
@ -46,9 +46,9 @@ bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
For more information, you are invited to read the sections on [IGNORE_MOD_TAP_INTERRUPT](tap_hold.md#ignore-mod-tap-interrupt) and [HOLD_ON_OTHER_KEY_PRESS](tap_hold.md#hold-on-other-key-press) in the page on [Tap-Hold configuration options](tap_hold.md).
|
For more information, you are invited to read the sections on [IGNORE_MOD_TAP_INTERRUPT](../tap_hold#ignore-mod-tap-interrupt) and [HOLD_ON_OTHER_KEY_PRESS](../tap_hold#hold-on-other-key-press) in the page on [Tap-Hold configuration options](../tap_hold).
|
||||||
|
|
||||||
### `TAPPING_FORCE_HOLD` => `QUICK_TAP_TERM` ([#17007](https://github.com/qmk/qmk_firmware/pull/17007)) :id=quick-tap-term
|
### `TAPPING_FORCE_HOLD` => `QUICK_TAP_TERM` ([#17007](https://github.com/qmk/qmk_firmware/pull/17007)) {#quick-tap-term}
|
||||||
|
|
||||||
`TAPPING_FORCE_HOLD` feature is now replaced by `QUICK_TAP_TERM`. Instead of turning off auto-repeat completely, user will have the option to configure a `QUICK_TAP_TERM` in milliseconds. When the user holds a tap-hold key after tapping it within `QUICK_TAP_TERM`, QMK will send the tap keycode to the host, enabling auto-repeat.
|
`TAPPING_FORCE_HOLD` feature is now replaced by `QUICK_TAP_TERM`. Instead of turning off auto-repeat completely, user will have the option to configure a `QUICK_TAP_TERM` in milliseconds. When the user holds a tap-hold key after tapping it within `QUICK_TAP_TERM`, QMK will send the tap keycode to the host, enabling auto-repeat.
|
||||||
|
|
||||||
|
@ -80,9 +80,9 @@ uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details, please read the updated documentation section on [Quick Tap Term](tap_hold.md#quick-tap-term).
|
For more details, please read the updated documentation section on [Quick Tap Term](../tap_hold#quick-tap-term).
|
||||||
|
|
||||||
### Leader Key Rework :id=leader-key-rework ([#19632](https://github.com/qmk/qmk_firmware/pull/19632))
|
### Leader Key Rework {#leader-key-rework ([#19632](https://github.com/qmk/qmk_firmware/pull/19632))}
|
||||||
|
|
||||||
The Leader Key feature API has been significantly improved, along with some bugfixes and added tests.
|
The Leader Key feature API has been significantly improved, along with some bugfixes and added tests.
|
||||||
|
|
||||||
|
@ -106,9 +106,9 @@ void leader_end_user(void) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
For more information please see the [Leader Key documentation](feature_leader_key.md).
|
For more information please see the [Leader Key documentation](../feature_leader_key).
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
The following keyboards have had their source moved within QMK:
|
The following keyboards have had their source moved within QMK:
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ The following keyboards have had their source moved within QMK:
|
||||||
| the_uni | stenothe_uni |
|
| the_uni | stenothe_uni |
|
||||||
| xelus/xs60 | xelus/xs60/soldered |
|
| xelus/xs60 | xelus/xs60/soldered |
|
||||||
|
|
||||||
## Notable core changes :id=notable-core
|
## Notable core changes {#notable-core}
|
||||||
|
|
||||||
As per last breaking changes cycle, there has been _a lot_ of emphasis on behind-the-scenes changes, mainly around consolidation of core subsystems and constant values, as well as addressing tech debt. Whilst not outwardly visible, this cleanup and refactoring should start paying dividends as it simplifies future development and maintenance.
|
As per last breaking changes cycle, there has been _a lot_ of emphasis on behind-the-scenes changes, mainly around consolidation of core subsystems and constant values, as well as addressing tech debt. Whilst not outwardly visible, this cleanup and refactoring should start paying dividends as it simplifies future development and maintenance.
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ A handful of examples:
|
||||||
* Many more configuration options have moved into `info.json`, such as backlight, encoders
|
* Many more configuration options have moved into `info.json`, such as backlight, encoders
|
||||||
* Additional unit tests to ensure keycode behaviours don't accidentally change
|
* Additional unit tests to ensure keycode behaviours don't accidentally change
|
||||||
|
|
||||||
## Full changelist :id=full-changelist
|
## Full changelist {#full-changelist}
|
||||||
|
|
||||||
Core:
|
Core:
|
||||||
* Remove IGNORE_MOD_TAP_INTERRUPT_PER_KEY in favour of HOLD_ON_OTHER_KEY_PRESS_PER_KEY ([#15741](https://github.com/qmk/qmk_firmware/pull/15741))
|
* Remove IGNORE_MOD_TAP_INTERRUPT_PER_KEY in favour of HOLD_ON_OTHER_KEY_PRESS_PER_KEY ([#15741](https://github.com/qmk/qmk_firmware/pull/15741))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# QMK Breaking Changes - 2023 May 28 Changelog
|
# QMK Breaking Changes - 2023 May 28 Changelog
|
||||||
|
|
||||||
## Notable Changes :id=notable-changes
|
## Notable Changes {#notable-changes}
|
||||||
|
|
||||||
As per last breaking changes cycle, there has been _a lot_ of emphasis on behind-the-scenes changes, mainly around migration of configurables into `info.json` files, cleanup of `info.json` files, additional layout definitions for keyboards, adding support for general community layouts to keyboards, as well as addressing technical debt.
|
As per last breaking changes cycle, there has been _a lot_ of emphasis on behind-the-scenes changes, mainly around migration of configurables into `info.json` files, cleanup of `info.json` files, additional layout definitions for keyboards, adding support for general community layouts to keyboards, as well as addressing technical debt.
|
||||||
|
|
||||||
|
@ -20,11 +20,11 @@ Of note for keyboard designers:
|
||||||
* `encoder_map[][NUM_ENCODERS][2]` => `encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS]`
|
* `encoder_map[][NUM_ENCODERS][2]` => `encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS]`
|
||||||
* Users assumed the `2` referred to the number of encoders, rather than the number of directions (which is always 2)
|
* Users assumed the `2` referred to the number of encoders, rather than the number of directions (which is always 2)
|
||||||
|
|
||||||
### Repeat last key ([#19700](https://github.com/qmk/qmk_firmware/pull/19700)) :id=repeat-last-key
|
### Repeat last key ([#19700](https://github.com/qmk/qmk_firmware/pull/19700)) {#repeat-last-key}
|
||||||
|
|
||||||
A new pair of keys has been added to QMK -- namely `QK_REPEAT_KEY` and `QK_ALT_REPEAT_KEY` (shortened: `QK_REP`/`QK_AREP`). These allow you to repeat the last key pressed, or in the case of the alternate key, press the "opposite" of the last key. For example, if you press `KC_LEFT`, pressing `QK_REPEAT_KEY` afterwards repeats `KC_LEFT`, but pressing `QK_ALT_REPEAT_KEY` instead sends `KC_RIGHT`.
|
A new pair of keys has been added to QMK -- namely `QK_REPEAT_KEY` and `QK_ALT_REPEAT_KEY` (shortened: `QK_REP`/`QK_AREP`). These allow you to repeat the last key pressed, or in the case of the alternate key, press the "opposite" of the last key. For example, if you press `KC_LEFT`, pressing `QK_REPEAT_KEY` afterwards repeats `KC_LEFT`, but pressing `QK_ALT_REPEAT_KEY` instead sends `KC_RIGHT`.
|
||||||
|
|
||||||
The full list of default alternate keys is available on the [Repeat Key](feature_repeat_key.md) documentation.
|
The full list of default alternate keys is available on the [Repeat Key](../feature_repeat_key) documentation.
|
||||||
|
|
||||||
To enable these keys, in your keymap's `rules.mk`, add:
|
To enable these keys, in your keymap's `rules.mk`, add:
|
||||||
|
|
||||||
|
@ -34,27 +34,27 @@ REPEAT_KEY_ENABLE = yes
|
||||||
|
|
||||||
...and add them to your keymap.
|
...and add them to your keymap.
|
||||||
|
|
||||||
### User callback for pre process record ([#20584](https://github.com/qmk/qmk_firmware/pull/20584)) :id=user-callback-for-pre-process-record
|
### User callback for pre process record ([#20584](https://github.com/qmk/qmk_firmware/pull/20584)) {#user-callback-for-pre-process-record}
|
||||||
|
|
||||||
Two new boolean callback functions, `pre_process_record_kb` and `pre_process_record_user`, have been added. They are called at the beginning of `process_record`, right before `process_combo`.
|
Two new boolean callback functions, `pre_process_record_kb` and `pre_process_record_user`, have been added. They are called at the beginning of `process_record`, right before `process_combo`.
|
||||||
|
|
||||||
Similar to existing `*_kb` and `*_user` callback functions, returning `false` will halt further processing of key events. The `pre_process_record_user` function will allow user space opportunity to handle or capture an input before it undergoes quantum processing. For example, while action tapping is still resolving the tap or hold output of a mod-tap key, `pre_process_record_user` can capture the next key record of an input event that follows. That key record can be used to influence the [decision of the mod-tap](https://docs.qmk.fm/#/tap_hold) key that is currently undergoing quantum processing.
|
Similar to existing `*_kb` and `*_user` callback functions, returning `false` will halt further processing of key events. The `pre_process_record_user` function will allow user space opportunity to handle or capture an input before it undergoes quantum processing. For example, while action tapping is still resolving the tap or hold output of a mod-tap key, `pre_process_record_user` can capture the next key record of an input event that follows. That key record can be used to influence the [decision of the mod-tap](../tap_hold) key that is currently undergoing quantum processing.
|
||||||
|
|
||||||
### Consolidate modelm ([#14996](https://github.com/qmk/qmk_firmware/pull/14996) :id=consolidate-modelm
|
### Consolidate modelm ([#14996](https://github.com/qmk/qmk_firmware/pull/14996) {#consolidate-modelm}
|
||||||
|
|
||||||
Several build targets for the IBM Model M were cluttered in different folders. The maintainers of several Model M replacement controller projects agreed to consolidate them under one common folder.
|
Several build targets for the IBM Model M were cluttered in different folders. The maintainers of several Model M replacement controller projects agreed to consolidate them under one common folder.
|
||||||
|
|
||||||
The list of all moved keyboard locations is listed [below](20230528.md#updated-keyboard-codebases).
|
The list of all moved keyboard locations is listed [below](20230528#updated-keyboard-codebases).
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### `IGNORE_MOD_TAP_INTERRUPT` behaviour changes ([#20211](https://github.com/qmk/qmk_firmware/pull/20211)) :id=i-m-t-i
|
### `IGNORE_MOD_TAP_INTERRUPT` behaviour changes ([#20211](https://github.com/qmk/qmk_firmware/pull/20211)) {#i-m-t-i}
|
||||||
|
|
||||||
Following up from the last breaking changes cycle, `IGNORE_MOD_TAP_INTERRUPT` has been removed and if present in keymap code, will now fail to build. The previous functionality for `IGNORE_MOD_TAP_INTERRUPT` is now default, and should you wish to revert to the old behaviour, you can use `HOLD_ON_OTHER_KEY_PRESS` instead.
|
Following up from the last breaking changes cycle, `IGNORE_MOD_TAP_INTERRUPT` has been removed and if present in keymap code, will now fail to build. The previous functionality for `IGNORE_MOD_TAP_INTERRUPT` is now default, and should you wish to revert to the old behaviour, you can use `HOLD_ON_OTHER_KEY_PRESS` instead.
|
||||||
|
|
||||||
For more information, you are invited to read the section on [HOLD_ON_OTHER_KEY_PRESS](tap_hold.md#hold-on-other-key-press) in the page on [Tap-Hold configuration options](tap_hold.md).
|
For more information, you are invited to read the section on [HOLD_ON_OTHER_KEY_PRESS](../tap_hold#hold-on-other-key-press) in the page on [Tap-Hold configuration options](../tap_hold).
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
| Old Keyboard Name | New Keyboard Name |
|
| Old Keyboard Name | New Keyboard Name |
|
||||||
|---------------------------------|-------------------------------------|
|
|---------------------------------|-------------------------------------|
|
||||||
|
@ -77,9 +77,9 @@ For more information, you are invited to read the section on [HOLD_ON_OTHER_KEY_
|
||||||
| tronguylabs/m122_3270/teensy | ibm/model_m_122/m122_3270/teensy |
|
| tronguylabs/m122_3270/teensy | ibm/model_m_122/m122_3270/teensy |
|
||||||
| yugo_m/model_m_101 | ibm/model_m/yugo_m |
|
| yugo_m/model_m_101 | ibm/model_m/yugo_m |
|
||||||
|
|
||||||
## Notable core changes :id=notable-core
|
## Notable core changes {#notable-core}
|
||||||
|
|
||||||
### Encoder functionality fallback ([#20320](https://github.com/qmk/qmk_firmware/pull/20320)) :id=encoder-functionality-fallback
|
### Encoder functionality fallback ([#20320](https://github.com/qmk/qmk_firmware/pull/20320)) {#encoder-functionality-fallback}
|
||||||
|
|
||||||
For keyboards who have not yet been migrated to encoder map, a default set of encoder functionality is now enabled, gracefully degrading functionality depending on which flags are enabled by the keyboard:
|
For keyboards who have not yet been migrated to encoder map, a default set of encoder functionality is now enabled, gracefully degrading functionality depending on which flags are enabled by the keyboard:
|
||||||
|
|
||||||
|
@ -89,13 +89,13 @@ For keyboards who have not yet been migrated to encoder map, a default set of en
|
||||||
|
|
||||||
Additionally, this ensures that builds on QMK Configurator produce some sort of usable encoder mapping.
|
Additionally, this ensures that builds on QMK Configurator produce some sort of usable encoder mapping.
|
||||||
|
|
||||||
### OLED Driver Improvements ([#20331](https://github.com/qmk/qmk_firmware/pull/20331)) :id=oled-driver-improvements
|
### OLED Driver Improvements ([#20331](https://github.com/qmk/qmk_firmware/pull/20331)) {#oled-driver-improvements}
|
||||||
|
|
||||||
The "classic" OLED driver picked up support for additional sizes of OLED displays, support for the SH1107 controller, and SPI-based OLED support.
|
The "classic" OLED driver picked up support for additional sizes of OLED displays, support for the SH1107 controller, and SPI-based OLED support.
|
||||||
|
|
||||||
Other configurable items are available and can be found on the [OLED Driver page](https://docs.qmk.fm/#/feature_oled_driver).
|
Other configurable items are available and can be found on the [OLED Driver page](../feature_oled_driver).
|
||||||
|
|
||||||
## Full changelist :id=full-changelist
|
## Full changelist {#full-changelist}
|
||||||
|
|
||||||
Core:
|
Core:
|
||||||
* Refactor `keyevent_t` for 1ms timing resolution ([#15847](https://github.com/qmk/qmk_firmware/pull/15847))
|
* Refactor `keyevent_t` for 1ms timing resolution ([#15847](https://github.com/qmk/qmk_firmware/pull/15847))
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
# QMK Breaking Changes - 2023 Aug 27 Changelog
|
# QMK Breaking Changes - 2023 Aug 27 Changelog
|
||||||
|
|
||||||
## Notable Changes :id=notable-changes
|
## Notable Changes {#notable-changes}
|
||||||
|
|
||||||
As per last few breaking changes cycles, there have been _a lot_ of behind-the-scenes changes, mainly around migration of configurables into `info.json` files, cleanup of `info.json` files, additional layout definitions for keyboards, adding support for general community layouts to keyboards, as well as addressing technical debt.
|
As per last few breaking changes cycles, there have been _a lot_ of behind-the-scenes changes, mainly around migration of configurables into `info.json` files, cleanup of `info.json` files, additional layout definitions for keyboards, adding support for general community layouts to keyboards, as well as addressing technical debt.
|
||||||
|
|
||||||
One thing to note for this release -- `qmk/qmk_firmware` is no longer accepting PRs for keymaps other than for manufacturer-supported keymaps. User keymap workflow has been documented [here](https://docs.qmk.fm/#/newbs) for several years. This change is to progressively reduce the maintenance burden on the project, and to allow us to focus on the core features of QMK.
|
One thing to note for this release -- `qmk/qmk_firmware` is no longer accepting PRs for keymaps other than for manufacturer-supported keymaps. User keymap workflow has been documented [here](../newbs) for several years. This change is to progressively reduce the maintenance burden on the project, and to allow us to focus on the core features of QMK.
|
||||||
|
|
||||||
Existing user keymaps and userspace areas will likely be relocated/removed in the future -- non-building keymaps and userspace will be first targets, likely during the new breaking changes cycle. We will provide more information on Discord regarding this initiative as it becomes available.
|
Existing user keymaps and userspace areas will likely be relocated/removed in the future -- non-building keymaps and userspace will be first targets, likely during the new breaking changes cycle. We will provide more information on Discord regarding this initiative as it becomes available.
|
||||||
|
|
||||||
### RGB Matrix optimizations ([#21134](https://github.com/qmk/qmk_firmware/pull/21134), [#21135](https://github.com/qmk/qmk_firmware/pull/21135)) :id=rgb-matrix-optimizations
|
### RGB Matrix optimizations ([#21134](https://github.com/qmk/qmk_firmware/pull/21134), [#21135](https://github.com/qmk/qmk_firmware/pull/21135)) {#rgb-matrix-optimizations}
|
||||||
|
|
||||||
Most RGB Matrix implementations now check whether or not RGB LED data has changed and skip transmission if it hasn't. This was measured to improve scan frequency in cases of static or infrequently-changing colors.
|
Most RGB Matrix implementations now check whether or not RGB LED data has changed and skip transmission if it hasn't. This was measured to improve scan frequency in cases of static or infrequently-changing colors.
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@ Some audio code relating to "notes" used `double` datatypes, which are implement
|
||||||
|
|
||||||
AVR sees minimal (if any) benefit -- `double` was interpreted as `float` on AVR anyway.
|
AVR sees minimal (if any) benefit -- `double` was interpreted as `float` on AVR anyway.
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
| Old Keyboard Name | New Keyboard Name |
|
| Old Keyboard Name | New Keyboard Name |
|
||||||
|---------------------------------------|-------------------------------------|
|
|---------------------------------------|-------------------------------------|
|
||||||
|
@ -40,11 +40,11 @@ AVR sees minimal (if any) benefit -- `double` was interpreted as `float` on AVR
|
||||||
| modelh | ibm/model_m/modelh |
|
| modelh | ibm/model_m/modelh |
|
||||||
| vinta | coarse/vinta |
|
| vinta | coarse/vinta |
|
||||||
|
|
||||||
### Remove encoder in-matrix workaround code ([#20389](https://github.com/qmk/qmk_firmware/pull/20389)) :id=remove-encoder-in-matrix-workaround-code
|
### Remove encoder in-matrix workaround code ([#20389](https://github.com/qmk/qmk_firmware/pull/20389)) {#remove-encoder-in-matrix-workaround-code}
|
||||||
|
|
||||||
Some keyboards "hacked" encoder support into spare slots in the key matrix in order to interoperate with VIA. This workaround is no longer necessary, and the code has been removed. If you have a keyboard that uses this workaround, you will need to update your keymap to use the new [Encoder Map](feature_encoders.md#encoder-map) API instead.
|
Some keyboards "hacked" encoder support into spare slots in the key matrix in order to interoperate with VIA. This workaround is no longer necessary, and the code has been removed. If you have a keyboard that uses this workaround, you will need to update your keymap to use the new [Encoder Map](../feature_encoders#encoder-map) API instead.
|
||||||
|
|
||||||
### Unicodemap keycodes rename ([#21092](https://github.com/qmk/qmk_firmware/pull/21092)) :id=unicodemap-keycodes-rename
|
### Unicodemap keycodes rename ([#21092](https://github.com/qmk/qmk_firmware/pull/21092)) {#unicodemap-keycodes-rename}
|
||||||
|
|
||||||
The Unicodemap keycodes have been renamed:
|
The Unicodemap keycodes have been renamed:
|
||||||
|
|
||||||
|
@ -53,11 +53,11 @@ The Unicodemap keycodes have been renamed:
|
||||||
| `X(i)` | `UM(i)` |
|
| `X(i)` | `UM(i)` |
|
||||||
| `XP(i,j)` | `UP(i,j)` |
|
| `XP(i,j)` | `UP(i,j)` |
|
||||||
|
|
||||||
### Remove old OLED API code ([#21651](https://github.com/qmk/qmk_firmware/pull/21651)) :id=remove-old-oled-api-code
|
### Remove old OLED API code ([#21651](https://github.com/qmk/qmk_firmware/pull/21651)) {#remove-old-oled-api-code}
|
||||||
|
|
||||||
Old OLED code using `ssd1306.c` `ssd1306.h`, and `SSD1306OLED` and other similar files have been consolidated to use the standard OLED driver. External user keymaps will need to be updated to use the standard OLED driver accordingly.
|
Old OLED code using `ssd1306.c` `ssd1306.h`, and `SSD1306OLED` and other similar files have been consolidated to use the standard OLED driver. External user keymaps will need to be updated to use the standard OLED driver accordingly.
|
||||||
|
|
||||||
### Driver naming consolidation ([#21551](https://github.com/qmk/qmk_firmware/pull/21551), [#21558](https://github.com/qmk/qmk_firmware/pull/21558), [#21580](https://github.com/qmk/qmk_firmware/pull/21580), [#21594](https://github.com/qmk/qmk_firmware/pull/21594), [#21624](https://github.com/qmk/qmk_firmware/pull/21624), [#21710](https://github.com/qmk/qmk_firmware/pull/21710)) :id=driver-naming-consolidation
|
### Driver naming consolidation ([#21551](https://github.com/qmk/qmk_firmware/pull/21551), [#21558](https://github.com/qmk/qmk_firmware/pull/21558), [#21580](https://github.com/qmk/qmk_firmware/pull/21580), [#21594](https://github.com/qmk/qmk_firmware/pull/21594), [#21624](https://github.com/qmk/qmk_firmware/pull/21624), [#21710](https://github.com/qmk/qmk_firmware/pull/21710)) {#driver-naming-consolidation}
|
||||||
|
|
||||||
In most circumstances this won't affect users -- only keyboard designers with currently-unmerged boards. The only users affected are people who have modified existing keyboards in order to add/modify haptics, lighting, or bluetooth -- and only if the base keyboard did not configure them already. Driver naming has been modified to be lowercase.
|
In most circumstances this won't affect users -- only keyboard designers with currently-unmerged boards. The only users affected are people who have modified existing keyboards in order to add/modify haptics, lighting, or bluetooth -- and only if the base keyboard did not configure them already. Driver naming has been modified to be lowercase.
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ Bluetooth (`BLUETOOTH_DRIVER` / `bluetooth.driver`):
|
||||||
| `BluefruitLE` | `bluefruit_le` |
|
| `BluefruitLE` | `bluefruit_le` |
|
||||||
| `RN42` | `rn42` |
|
| `RN42` | `rn42` |
|
||||||
|
|
||||||
## Full changelist :id=full-changelist
|
## Full changelist {#full-changelist}
|
||||||
|
|
||||||
Core:
|
Core:
|
||||||
* On-each-release tap dance function ([#20255](https://github.com/qmk/qmk_firmware/pull/20255))
|
* On-each-release tap dance function ([#20255](https://github.com/qmk/qmk_firmware/pull/20255))
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
# QMK Breaking Changes - 2023 November 26 Changelog
|
# QMK Breaking Changes - 2023 November 26 Changelog
|
||||||
|
|
||||||
## Notable Features :id=notable-features
|
## Notable Features {#notable-features}
|
||||||
|
|
||||||
As per last few breaking changes cycles, there have been _a lot_ of behind-the-scenes changes, mainly around consolidation of config into `info.json` files, cleanup of `info.json` files, cleaning up driver naming, as well as addressing technical debt.
|
As per last few breaking changes cycles, there have been _a lot_ of behind-the-scenes changes, mainly around consolidation of config into `info.json` files, cleanup of `info.json` files, cleaning up driver naming, as well as addressing technical debt.
|
||||||
|
|
||||||
As a followup to last cycle's [notable changes](20230827.md#notable-changes), as `qmk/qmk_firmware` is no longer accepting PRs for keymaps we're pleased to announce that storing and building keymaps externally from the normal QMK Firmware repository is now possible. This is done through the new [External Userspace](newbs_external_userspace.md) feature, more details below!
|
As a followup to last cycle's [notable changes](20230827#notable-changes), as `qmk/qmk_firmware` is no longer accepting PRs for keymaps we're pleased to announce that storing and building keymaps externally from the normal QMK Firmware repository is now possible. This is done through the new [External Userspace](../newbs_external_userspace) feature, more details below!
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
| Old Keyboard Name | New Keyboard Name |
|
| Old Keyboard Name | New Keyboard Name |
|
||||||
|---------------------------------------|-------------------------------|
|
|---------------------------------------|-------------------------------|
|
||||||
|
@ -29,29 +29,31 @@ As a followup to last cycle's [notable changes](20230827.md#notable-changes), as
|
||||||
| studiokestra/line_tkl | studiokestra/line_friends_tkl |
|
| studiokestra/line_tkl | studiokestra/line_friends_tkl |
|
||||||
| ymdk/melody96 | ymdk/melody96/soldered |
|
| ymdk/melody96 | ymdk/melody96/soldered |
|
||||||
|
|
||||||
## Notable core changes :id=notable-core
|
## Notable core changes {#notable-core}
|
||||||
|
|
||||||
### External Userspace ([#22222](https://github.com/qmk/qmk_firmware/pull/22222))
|
### External Userspace ([#22222](https://github.com/qmk/qmk_firmware/pull/22222))
|
||||||
|
|
||||||
As mentioned above, the new External Userspace feature allows for keymaps to be stored and built externally from the main QMK Firmware repository. This allows for keymaps to be stored separately -- usually in their own repository -- and for users to be able to maintain and build their keymaps without needing to fork the main QMK Firmware repository.
|
As mentioned above, the new External Userspace feature allows for keymaps to be stored and built externally from the main QMK Firmware repository. This allows for keymaps to be stored separately -- usually in their own repository -- and for users to be able to maintain and build their keymaps without needing to fork the main QMK Firmware repository.
|
||||||
|
|
||||||
See the [External Userspace documentation](newbs_external_userspace.md) for more details.
|
See the [External Userspace documentation](../newbs_external_userspace) for more details.
|
||||||
|
|
||||||
A significant portion of user keymaps have already been removed from `qmk/qmk_firmware` and more will follow in coming weeks. You can still recover your keymap from the tag [user-keymaps-still-present](https://github.com/qmk/qmk_firmware/tree/user-keymaps-still-present) if required -- a perfect time to migrate to the new External Userspace!
|
A significant portion of user keymaps have already been removed from `qmk/qmk_firmware` and more will follow in coming weeks. You can still recover your keymap from the tag [user-keymaps-still-present](https://github.com/qmk/qmk_firmware/tree/user-keymaps-still-present) if required -- a perfect time to migrate to the new External Userspace!
|
||||||
|
|
||||||
!> This feature is still in beta, and we're looking for feedback on it. Please try it out and let us know what you think -- a new `#help-userspace` channel has been set up on Discord.
|
::: warning
|
||||||
|
This feature is still in beta, and we're looking for feedback on it. Please try it out and let us know what you think -- a new `#help-userspace` channel has been set up on Discord.
|
||||||
|
:::
|
||||||
|
|
||||||
### Improve and Cleanup Shutdown callbacks ([#21060](https://github.com/qmk/qmk_firmware/pull/20160)) :id=improve-and-cleanup-shutdown-callbacks
|
### Improve and Cleanup Shutdown callbacks ([#21060](https://github.com/qmk/qmk_firmware/pull/20160)) {#improve-and-cleanup-shutdown-callbacks}
|
||||||
|
|
||||||
Shutdown callbacks at the keyboard level were never present, preventing safe shutdown sequencing for peripherals such as OLEDs, RGB LEDs, and other devices. This PR adds a new `shutdown_kb` function, as well as amending `shutdown_user`, allowing for safe shutdown of peripherals at both keyboard and keymap level.
|
Shutdown callbacks at the keyboard level were never present, preventing safe shutdown sequencing for peripherals such as OLEDs, RGB LEDs, and other devices. This PR adds a new `shutdown_kb` function, as well as amending `shutdown_user`, allowing for safe shutdown of peripherals at both keyboard and keymap level.
|
||||||
|
|
||||||
See the [Keyboard Shutdown/Reboot Code](custom_quantum_functions.md#keyboard-shutdown-reboot-code) documentation for more details.
|
See the [Keyboard Shutdown/Reboot Code](../custom_quantum_functions#keyboard-shutdown-reboot-code) documentation for more details.
|
||||||
|
|
||||||
### OLED Force Flush ([#20953](https://github.com/qmk/qmk_firmware/pull/20953)) :id=oled-force-flush
|
### OLED Force Flush ([#20953](https://github.com/qmk/qmk_firmware/pull/20953)) {#oled-force-flush}
|
||||||
|
|
||||||
Along with the new `shutdown_kb` function, a new API `oled_render_dirty(bool)` function has been added. This allows OLED contents to be written deterministically when supplied with `true` -- that is, the OLED will be updated immediately, rather than waiting for the next OLED update cycle. This allows for OLEDs to show things such as "BOOTLOADER MODE" and the like if resetting to bootloader from QMK.
|
Along with the new `shutdown_kb` function, a new API `oled_render_dirty(bool)` function has been added. This allows OLED contents to be written deterministically when supplied with `true` -- that is, the OLED will be updated immediately, rather than waiting for the next OLED update cycle. This allows for OLEDs to show things such as "BOOTLOADER MODE" and the like if resetting to bootloader from QMK.
|
||||||
|
|
||||||
### Switch statement helpers for keycode ranges ([#20059](https://github.com/qmk/qmk_firmware/pull/20059)) :id=switch-statement-helpers-for-keycode-ranges
|
### Switch statement helpers for keycode ranges ([#20059](https://github.com/qmk/qmk_firmware/pull/20059)) {#switch-statement-helpers-for-keycode-ranges}
|
||||||
|
|
||||||
Predefined ranges usable within switch statements have been added for groups of similar keycodes, where people who wish to handle entire blocks at once can do so. This allows keymaps to be immune to changes in keycode values, and also allows for more efficient code generation.
|
Predefined ranges usable within switch statements have been added for groups of similar keycodes, where people who wish to handle entire blocks at once can do so. This allows keymaps to be immune to changes in keycode values, and also allows for more efficient code generation.
|
||||||
|
|
||||||
|
@ -98,17 +100,17 @@ Becomes:
|
||||||
/* do stuff with basic and modifier keycodes */
|
/* do stuff with basic and modifier keycodes */
|
||||||
```
|
```
|
||||||
|
|
||||||
### Quantum Painter OLED support ([#19997](https://github.com/qmk/qmk_firmware/pull/19997)) :id=quantum-painter-oled-support
|
### Quantum Painter OLED support ([#19997](https://github.com/qmk/qmk_firmware/pull/19997)) {#quantum-painter-oled-support}
|
||||||
|
|
||||||
Quantum Painter has picked up support for SH1106 displays -- commonly seen as 128x64 OLEDs. Support for both I2C and SPI displays is available.
|
Quantum Painter has picked up support for SH1106 displays -- commonly seen as 128x64 OLEDs. Support for both I2C and SPI displays is available.
|
||||||
|
|
||||||
If you're already using OLED through `OLED_DRIVER_ENABLE = yes` or equivalent in `info.json` and wish to use Quantum Painter instead, you'll need to disable the old OLED system, instead enabling Quantum Painter as well as enabling the appropriate SH1106 driver. See the [Quantum Painter driver documentation](quantum_painter.md#quantum-painter-drivers) for more details. The old OLED driver is still available, and keymaps do not require migrating to Quantum Painter if you don't want to do so.
|
If you're already using OLED through `OLED_DRIVER_ENABLE = yes` or equivalent in `info.json` and wish to use Quantum Painter instead, you'll need to disable the old OLED system, instead enabling Quantum Painter as well as enabling the appropriate SH1106 driver. See the [Quantum Painter driver documentation](../quantum_painter#quantum-painter-drivers) for more details. The old OLED driver is still available, and keymaps do not require migrating to Quantum Painter if you don't want to do so.
|
||||||
|
|
||||||
### RGB/LED lighting driver naming and cleanup ([#21890](https://github.com/qmk/qmk_firmware/pull/21890), [#21891](https://github.com/qmk/qmk_firmware/pull/21891), [#21892](https://github.com/qmk/qmk_firmware/pull/21892), [#21903](https://github.com/qmk/qmk_firmware/pull/21903), [#21904](https://github.com/qmk/qmk_firmware/pull/21904), [#21905](https://github.com/qmk/qmk_firmware/pull/21905), [#21918](https://github.com/qmk/qmk_firmware/pull/21918), [#21929](https://github.com/qmk/qmk_firmware/pull/21929), [#21938](https://github.com/qmk/qmk_firmware/pull/21938), [#22004](https://github.com/qmk/qmk_firmware/pull/22004), [#22008](https://github.com/qmk/qmk_firmware/pull/22008), [#22009](https://github.com/qmk/qmk_firmware/pull/22009), [#22071](https://github.com/qmk/qmk_firmware/pull/22071), [#22090](https://github.com/qmk/qmk_firmware/pull/22090), [#22099](https://github.com/qmk/qmk_firmware/pull/22099), [#22126](https://github.com/qmk/qmk_firmware/pull/22126), [#22133](https://github.com/qmk/qmk_firmware/pull/22133), [#22163](https://github.com/qmk/qmk_firmware/pull/22163), [#22200](https://github.com/qmk/qmk_firmware/pull/22200), [#22308](https://github.com/qmk/qmk_firmware/pull/22308), [#22309](https://github.com/qmk/qmk_firmware/pull/22309), [#22311](https://github.com/qmk/qmk_firmware/pull/22311), [#22325](https://github.com/qmk/qmk_firmware/pull/22325), [#22365](https://github.com/qmk/qmk_firmware/pull/22365), [#22379](https://github.com/qmk/qmk_firmware/pull/22379), [#22380](https://github.com/qmk/qmk_firmware/pull/22380), [#22381](https://github.com/qmk/qmk_firmware/pull/22381), [#22383](https://github.com/qmk/qmk_firmware/pull/22383), [#22436](https://github.com/qmk/qmk_firmware/pull/22436))
|
### RGB/LED lighting driver naming and cleanup ([#21890](https://github.com/qmk/qmk_firmware/pull/21890), [#21891](https://github.com/qmk/qmk_firmware/pull/21891), [#21892](https://github.com/qmk/qmk_firmware/pull/21892), [#21903](https://github.com/qmk/qmk_firmware/pull/21903), [#21904](https://github.com/qmk/qmk_firmware/pull/21904), [#21905](https://github.com/qmk/qmk_firmware/pull/21905), [#21918](https://github.com/qmk/qmk_firmware/pull/21918), [#21929](https://github.com/qmk/qmk_firmware/pull/21929), [#21938](https://github.com/qmk/qmk_firmware/pull/21938), [#22004](https://github.com/qmk/qmk_firmware/pull/22004), [#22008](https://github.com/qmk/qmk_firmware/pull/22008), [#22009](https://github.com/qmk/qmk_firmware/pull/22009), [#22071](https://github.com/qmk/qmk_firmware/pull/22071), [#22090](https://github.com/qmk/qmk_firmware/pull/22090), [#22099](https://github.com/qmk/qmk_firmware/pull/22099), [#22126](https://github.com/qmk/qmk_firmware/pull/22126), [#22133](https://github.com/qmk/qmk_firmware/pull/22133), [#22163](https://github.com/qmk/qmk_firmware/pull/22163), [#22200](https://github.com/qmk/qmk_firmware/pull/22200), [#22308](https://github.com/qmk/qmk_firmware/pull/22308), [#22309](https://github.com/qmk/qmk_firmware/pull/22309), [#22311](https://github.com/qmk/qmk_firmware/pull/22311), [#22325](https://github.com/qmk/qmk_firmware/pull/22325), [#22365](https://github.com/qmk/qmk_firmware/pull/22365), [#22379](https://github.com/qmk/qmk_firmware/pull/22379), [#22380](https://github.com/qmk/qmk_firmware/pull/22380), [#22381](https://github.com/qmk/qmk_firmware/pull/22381), [#22383](https://github.com/qmk/qmk_firmware/pull/22383), [#22436](https://github.com/qmk/qmk_firmware/pull/22436))
|
||||||
|
|
||||||
As you can probably tell by the list of PRs just above, there has been a lot of cleanup and consolidation this cycle when it comes to RGB/LED lighting drivers. The number of changes is too large to list here, but the general theme has been focusing on consistency of naming, both of drivers themselves and their respective implementation and configuration. Most changes only affect keyboard designers -- if you find that your in-development keyboard is no longer building due to naming of defines changing, your best bet is to refer to another board already in the repository which has had the changes applied.
|
As you can probably tell by the list of PRs just above, there has been a lot of cleanup and consolidation this cycle when it comes to RGB/LED lighting drivers. The number of changes is too large to list here, but the general theme has been focusing on consistency of naming, both of drivers themselves and their respective implementation and configuration. Most changes only affect keyboard designers -- if you find that your in-development keyboard is no longer building due to naming of defines changing, your best bet is to refer to another board already in the repository which has had the changes applied.
|
||||||
|
|
||||||
### Peripheral subsystem enabling ([#22253](https://github.com/qmk/qmk_firmware/pull/22253), [#22448](https://github.com/qmk/qmk_firmware/pull/22448), [#22106](https://github.com/qmk/qmk_firmware/pull/22106)) :id=peripheral-subsystem-enabling
|
### Peripheral subsystem enabling ([#22253](https://github.com/qmk/qmk_firmware/pull/22253), [#22448](https://github.com/qmk/qmk_firmware/pull/22448), [#22106](https://github.com/qmk/qmk_firmware/pull/22106)) {#peripheral-subsystem-enabling}
|
||||||
|
|
||||||
When enabling peripherals such as I2C, SPI, or Analog/ADC, some required manual inclusion of source files in order to provide driver support, and in some cases, when multiple drivers were using the same underlying peripheral, files were being added to the build multiple times.
|
When enabling peripherals such as I2C, SPI, or Analog/ADC, some required manual inclusion of source files in order to provide driver support, and in some cases, when multiple drivers were using the same underlying peripheral, files were being added to the build multiple times.
|
||||||
|
|
||||||
|
@ -125,11 +127,11 @@ For a concrete example, users or keyboard designers who previously added `SRC +=
|
||||||
| `UART_DRIVER_REQUIRED = yes` | `SRC += uart.c` |
|
| `UART_DRIVER_REQUIRED = yes` | `SRC += uart.c` |
|
||||||
| `WS2812_DRIVER_REQUIRED = yes` | `SRC += ws2812.c` |
|
| `WS2812_DRIVER_REQUIRED = yes` | `SRC += ws2812.c` |
|
||||||
|
|
||||||
### NKRO on V-USB boards ([#22398](https://github.com/qmk/qmk_firmware/pull/22398)) :id=vusb-nkro
|
### NKRO on V-USB boards ([#22398](https://github.com/qmk/qmk_firmware/pull/22398)) {#vusb-nkro}
|
||||||
|
|
||||||
NKRO is now available for ATmega32A and 328P-based keyboards (including PS2AVRGB/Bootmapper boards), thanks to some internal refactoring and cleanup. To enable it, the process is the same as always - add `NKRO_ENABLE = yes` to your `rules.mk`, then assign and press the `NK_TOGG` keycode to switch modes.
|
NKRO is now available for ATmega32A and 328P-based keyboards (including PS2AVRGB/Bootmapper boards), thanks to some internal refactoring and cleanup. To enable it, the process is the same as always - add `NKRO_ENABLE = yes` to your `rules.mk`, then assign and press the `NK_TOGG` keycode to switch modes.
|
||||||
|
|
||||||
## Full changelist :id=full-changelist
|
## Full changelist {#full-changelist}
|
||||||
|
|
||||||
Core:
|
Core:
|
||||||
* Compilation warning if both `keymap.json` and `keymap.c` exist ([#19939](https://github.com/qmk/qmk_firmware/pull/19939))
|
* Compilation warning if both `keymap.json` and `keymap.c` exist ([#19939](https://github.com/qmk/qmk_firmware/pull/19939))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# QMK Breaking Changes - 2024 February 25 Changelog
|
# QMK Breaking Changes - 2024 February 25 Changelog
|
||||||
|
|
||||||
## Notable Features :id=notable-features
|
## Notable Features {#notable-features}
|
||||||
|
|
||||||
_0.24.0_ is mainly a maintenance release of QMK Firmware -- as per last few breaking changes cycles, there have been a lot of behind-the-scenes changes, mainly:
|
_0.24.0_ is mainly a maintenance release of QMK Firmware -- as per last few breaking changes cycles, there have been a lot of behind-the-scenes changes, mainly:
|
||||||
|
|
||||||
|
@ -10,17 +10,17 @@ _0.24.0_ is mainly a maintenance release of QMK Firmware -- as per last few brea
|
||||||
* keyboard relocations
|
* keyboard relocations
|
||||||
* addressing technical debt
|
* addressing technical debt
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Windows Driver Changes ([QMK Toolbox 0.3.0 Release](https://github.com/qmk/qmk_toolbox/releases/tag/0.3.0))
|
### Windows Driver Changes ([QMK Toolbox 0.3.0 Release](https://github.com/qmk/qmk_toolbox/releases/tag/0.3.0))
|
||||||
|
|
||||||
Flashing keyboards that target `atmel-dfu` or `qmk-dfu` on Windows using `qmk flash` or QMK Toolbox have traditionally used _libusb_ for access to the DFU USB device. Since QMK Toolbox 0.3.0, this has changed to WinUSB.
|
Flashing keyboards that target `atmel-dfu` or `qmk-dfu` on Windows using `qmk flash` or QMK Toolbox have traditionally used _libusb_ for access to the DFU USB device. Since QMK Toolbox 0.3.0, this has changed to WinUSB.
|
||||||
|
|
||||||
If you update QMK Toolbox or update QMK MSYS, you may find that flashing Atmel DFU keyboards no longer functions as intended. If you strike such issues when flashing new firmware, you will need to replace the _libusb_ driver with _WinUSB_ using Zadig. You can follow the [Recovering from Installation to Wrong Device](driver_installation_zadig.md#recovering-from-installation-to-wrong-device) instructions to replace the driver associated with the Atmel DFU bootloader, skipping the section about removal as Zadig will safely replace the driver instead. Please ensure your keyboard is in bootloader mode and has _libusb_ as the existing driver before attempting to use Zadig to replace the driver. If instead you see _HidUsb_ you're not in bootloader mode and should not continue with driver replacement.
|
If you update QMK Toolbox or update QMK MSYS, you may find that flashing Atmel DFU keyboards no longer functions as intended. If you strike such issues when flashing new firmware, you will need to replace the _libusb_ driver with _WinUSB_ using Zadig. You can follow the [Recovering from Installation to Wrong Device](../driver_installation_zadig#recovering-from-installation-to-wrong-device) instructions to replace the driver associated with the Atmel DFU bootloader, skipping the section about removal as Zadig will safely replace the driver instead. Please ensure your keyboard is in bootloader mode and has _libusb_ as the existing driver before attempting to use Zadig to replace the driver. If instead you see _HidUsb_ you're not in bootloader mode and should not continue with driver replacement.
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
One note with updated keyboard names -- historical keyboard names are still considered valid when using [External Userspace](newbs_external_userspace.md) for builds. If you're already using External Userspace, you do not need to move your keymap inside your repository.
|
One note with updated keyboard names -- historical keyboard names are still considered valid when using [External Userspace](../newbs_external_userspace) for builds. If you're already using External Userspace, you do not need to move your keymap inside your repository.
|
||||||
|
|
||||||
| Old Keyboard Name | New Keyboard Name |
|
| Old Keyboard Name | New Keyboard Name |
|
||||||
|-------------------------|---------------------------------|
|
|-------------------------|---------------------------------|
|
||||||
|
@ -77,9 +77,9 @@ One note with updated keyboard names -- historical keyboard names are still cons
|
||||||
| z12 | zigotica/z12 |
|
| z12 | zigotica/z12 |
|
||||||
| z34 | zigotica/z34 |
|
| z34 | zigotica/z34 |
|
||||||
|
|
||||||
## Notable core changes :id=notable-core
|
## Notable core changes {#notable-core}
|
||||||
|
|
||||||
### Renaming Arduino-style GPIO pin functions ([#23085](https://github.com/qmk/qmk_firmware/pull/23085), [#23093](https://github.com/qmk/qmk_firmware/pull/23093)) :id=gpio-rename
|
### Renaming Arduino-style GPIO pin functions ([#23085](https://github.com/qmk/qmk_firmware/pull/23085), [#23093](https://github.com/qmk/qmk_firmware/pull/23093)) {#gpio-rename}
|
||||||
|
|
||||||
QMK has long used Arduino-style GPIO naming conventions. This has been confusing for users, as over time they've had new variations added, as well as users mistakenly thinking that QMK supports the rest of the Arduino ecosystem.
|
QMK has long used Arduino-style GPIO naming conventions. This has been confusing for users, as over time they've had new variations added, as well as users mistakenly thinking that QMK supports the rest of the Arduino ecosystem.
|
||||||
|
|
||||||
|
@ -110,17 +110,17 @@ Much like the GPIO refactoring, I2C APIs were also updated to conform to QMK nam
|
||||||
| `i2c_writeReg()` | `i2c_write_register()` |
|
| `i2c_writeReg()` | `i2c_write_register()` |
|
||||||
| `i2c_writeReg16()` | `i2c_write_register16()` |
|
| `i2c_writeReg16()` | `i2c_write_register16()` |
|
||||||
|
|
||||||
### Renaming _Bootmagic Lite_ => _Bootmagic_ ([#22970](https://github.com/qmk/qmk_firmware/pull/22970), [#22979](https://github.com/qmk/qmk_firmware/pull/22979)) :id=bootmagic-rename
|
### Renaming _Bootmagic Lite_ => _Bootmagic_ ([#22970](https://github.com/qmk/qmk_firmware/pull/22970), [#22979](https://github.com/qmk/qmk_firmware/pull/22979)) {#bootmagic-rename}
|
||||||
|
|
||||||
Bootmagic "Lite" had no real meaning once the historical Bootmagic "Full" was deprecated and removed. Any references to _Bootmagic Lite_ should now just refer to _Bootmagic_. We hope we got the majority of the code and the documentation, so if you find any more, let us know!
|
Bootmagic "Lite" had no real meaning once the historical Bootmagic "Full" was deprecated and removed. Any references to _Bootmagic Lite_ should now just refer to _Bootmagic_. We hope we got the majority of the code and the documentation, so if you find any more, let us know!
|
||||||
|
|
||||||
### Threshold for automatic mouse layer activation ([#21398](https://github.com/qmk/qmk_firmware/pull/21398)) :id=auto-mouse-layer
|
### Threshold for automatic mouse layer activation ([#21398](https://github.com/qmk/qmk_firmware/pull/21398)) {#auto-mouse-layer}
|
||||||
|
|
||||||
In some cases, accidental automatic activation of the mouse layer made it difficult to continue typing, such as when brushing across a trackball. `AUTO_MOUSE_THRESHOLD` is now a configurable option in `config.h` which allows for specifying what the movement threshold is before automatically activating the mouse layer.
|
In some cases, accidental automatic activation of the mouse layer made it difficult to continue typing, such as when brushing across a trackball. `AUTO_MOUSE_THRESHOLD` is now a configurable option in `config.h` which allows for specifying what the movement threshold is before automatically activating the mouse layer.
|
||||||
|
|
||||||
### DIP Switch Mapping ([#22543](https://github.com/qmk/qmk_firmware/pull/22543)) :id=dip-switch-map
|
### DIP Switch Mapping ([#22543](https://github.com/qmk/qmk_firmware/pull/22543)) {#dip-switch-map}
|
||||||
|
|
||||||
Much like Encoder Mapping, DIP Switch Mapping allows for specifying a table of actions to execute when a DIP switch state changes. See the [DIP Switch Documentation](feature_dip_switch.md#dip-switch-map) for more information.
|
Much like Encoder Mapping, DIP Switch Mapping allows for specifying a table of actions to execute when a DIP switch state changes. See the [DIP Switch Documentation](../feature_dip_switch#dip-switch-map) for more information.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#if defined(DIP_SWITCH_MAP_ENABLE)
|
#if defined(DIP_SWITCH_MAP_ENABLE)
|
||||||
|
@ -131,7 +131,7 @@ const uint16_t PROGMEM dip_switch_map[NUM_DIP_SWITCHES][NUM_DIP_STATES] = {
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
### Quantum Painter updates ([#18521](https://github.com/qmk/qmk_firmware/pull/18521), [#20645](https://github.com/qmk/qmk_firmware/pull/20645), [#22358](https://github.com/qmk/qmk_firmware/pull/22358)) :id=qp-updates
|
### Quantum Painter updates ([#18521](https://github.com/qmk/qmk_firmware/pull/18521), [#20645](https://github.com/qmk/qmk_firmware/pull/20645), [#22358](https://github.com/qmk/qmk_firmware/pull/22358)) {#qp-updates}
|
||||||
|
|
||||||
Quantum Painter picked up support for the following:
|
Quantum Painter picked up support for the following:
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ Quantum Painter picked up support for the following:
|
||||||
|
|
||||||
Quantum Painter now supports the majority of common OLED panels supported by the basic OLED driver, so if you're using an ARM-based board you may find Quantum Painter a much more feature-rich API in comparison.
|
Quantum Painter now supports the majority of common OLED panels supported by the basic OLED driver, so if you're using an ARM-based board you may find Quantum Painter a much more feature-rich API in comparison.
|
||||||
|
|
||||||
## Full changelist :id=full-changelist
|
## Full changelist {#full-changelist}
|
||||||
|
|
||||||
Core:
|
Core:
|
||||||
* [Driver] ILI9486 on Quantum Painter ([#18521](https://github.com/qmk/qmk_firmware/pull/18521))
|
* [Driver] ILI9486 on Quantum Painter ([#18521](https://github.com/qmk/qmk_firmware/pull/18521))
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
# QMK Breaking Changes - 2024 May 26 Changelog
|
# QMK Breaking Changes - 2024 May 26 Changelog
|
||||||
|
|
||||||
## Notable Features :id=notable-features
|
## Notable Features {#notable-features}
|
||||||
|
|
||||||
May 2024 brings about another heavy maintenance release of QMK. Of the 209 PRs created this breaking changes cycle against the `develop` branch, 174 behind-the-scenes PRs (83%!) were aimed at converting, consolidating, and cleaning up keyboards and their configuration data. Not the most glamorous work, but it means QMK is in a much more manageable spot than what it was 3 months prior. The work steadily continues!
|
May 2024 brings about another heavy maintenance release of QMK. Of the 209 PRs created this breaking changes cycle against the `develop` branch, 174 behind-the-scenes PRs (83%!) were aimed at converting, consolidating, and cleaning up keyboards and their configuration data. Not the most glamorous work, but it means QMK is in a much more manageable spot than what it was 3 months prior. The work steadily continues!
|
||||||
|
|
||||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||||
|
|
||||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||||
|
|
||||||
One note with updated keyboard names -- historical keyboard names are still considered valid when using [External Userspace](newbs_external_userspace.md) for builds. If you're already using External Userspace, you do not need to move your keymap inside your repository.
|
One note with updated keyboard names -- historical keyboard names are still considered valid when using [External Userspace](../newbs_external_userspace) for builds. If you're already using External Userspace, you do not need to move your keymap inside your repository.
|
||||||
|
|
||||||
| Old Keyboard Name | New Keyboard Name |
|
| Old Keyboard Name | New Keyboard Name |
|
||||||
|------------------------------|-----------------------------------|
|
|------------------------------|-----------------------------------|
|
||||||
|
@ -40,7 +40,7 @@ A bunch of legacy keycodes have been removed -- check [the affected keycodes](ht
|
||||||
|
|
||||||
The latest of these were officially deprecated within QMK in the August 2023 breaking changes -- the new keycodes are the way forward.
|
The latest of these were officially deprecated within QMK in the August 2023 breaking changes -- the new keycodes are the way forward.
|
||||||
|
|
||||||
### P3D Spacey Layout Updates ([#23329](https://github.com/qmk/qmk_firmware/pull/23329)) :id=spacey-layout-updates
|
### P3D Spacey Layout Updates ([#23329](https://github.com/qmk/qmk_firmware/pull/23329)) {#spacey-layout-updates}
|
||||||
|
|
||||||
This PR removed the `LAYOUT` macro that was configured for the Spacey.
|
This PR removed the `LAYOUT` macro that was configured for the Spacey.
|
||||||
If you have a keymap for this keyboard, you will need to update your
|
If you have a keymap for this keyboard, you will need to update your
|
||||||
|
@ -54,7 +54,7 @@ keymap using the following steps:
|
||||||
4. Move the keycode for the Right Arrow to the end of the Shift row,
|
4. Move the keycode for the Right Arrow to the end of the Shift row,
|
||||||
after the Down Arrow key.
|
after the Down Arrow key.
|
||||||
|
|
||||||
### MechKeys ACR60 Layout Updates ([#23309](https://github.com/qmk/qmk_firmware/pull/23309)) :id=acr60-layout-updates
|
### MechKeys ACR60 Layout Updates ([#23309](https://github.com/qmk/qmk_firmware/pull/23309)) {#acr60-layout-updates}
|
||||||
|
|
||||||
This PR removed and changed some of the layouts that were configured for the ACR60. If you use one of the following layouts, you will need to update your keymap:
|
This PR removed and changed some of the layouts that were configured for the ACR60. If you use one of the following layouts, you will need to update your keymap:
|
||||||
|
|
||||||
|
@ -63,17 +63,17 @@ This PR removed and changed some of the layouts that were configured for the ACR
|
||||||
- [`LAYOUT_directional`](#layout-directional)
|
- [`LAYOUT_directional`](#layout-directional)
|
||||||
- [`LAYOUT_mitchsplit`](#layout-mitchsplit)
|
- [`LAYOUT_mitchsplit`](#layout-mitchsplit)
|
||||||
|
|
||||||
#### `LAYOUT_hhkb` :id=acr60-layout-hhkb
|
#### `LAYOUT_hhkb` {#acr60-layout-hhkb}
|
||||||
|
|
||||||
1. Change your layout macro to `LAYOUT_60_hhkb`.
|
1. Change your layout macro to `LAYOUT_60_hhkb`.
|
||||||
1. Remove any keycodes for the key between Left Shift and QWERTY Z.
|
1. Remove any keycodes for the key between Left Shift and QWERTY Z.
|
||||||
|
|
||||||
#### `LAYOUT_true_hhkb` :id=acr60-layout-true-hhkb
|
#### `LAYOUT_true_hhkb` {#acr60-layout-true-hhkb}
|
||||||
|
|
||||||
1. Change your layout macro to `LAYOUT_60_true_hhkb`.
|
1. Change your layout macro to `LAYOUT_60_true_hhkb`.
|
||||||
1. Remove any keycodes for the key between Left Shift and QWERTY Z.
|
1. Remove any keycodes for the key between Left Shift and QWERTY Z.
|
||||||
|
|
||||||
#### `LAYOUT_directional` :id=acr60-layout-directional
|
#### `LAYOUT_directional` {#acr60-layout-directional}
|
||||||
|
|
||||||
1. Change your layout macro to `LAYOUT_60_ansi_arrow_split_bs`.
|
1. Change your layout macro to `LAYOUT_60_ansi_arrow_split_bs`.
|
||||||
1. Remove any keycodes for the key between Left Shift and QWERTY Z.
|
1. Remove any keycodes for the key between Left Shift and QWERTY Z.
|
||||||
|
@ -81,16 +81,16 @@ This PR removed and changed some of the layouts that were configured for the ACR
|
||||||
|
|
||||||
If you need split spacebars, you may implement `LAYOUT_60_ansi_arrow_split_space_split_bs` and change your layout to it, removing the keycode between Left Shift and QWERTY Z.
|
If you need split spacebars, you may implement `LAYOUT_60_ansi_arrow_split_space_split_bs` and change your layout to it, removing the keycode between Left Shift and QWERTY Z.
|
||||||
|
|
||||||
#### `LAYOUT_mitchsplit` :id=acr60-layout-mitchsplit
|
#### `LAYOUT_mitchsplit` {#acr60-layout-mitchsplit}
|
||||||
|
|
||||||
1. Use `LAYOUT_60_ansi_split_space_split_rshift`.
|
1. Use `LAYOUT_60_ansi_split_space_split_rshift`.
|
||||||
|
|
||||||
## Notable core changes :id=notable-core
|
## Notable core changes {#notable-core}
|
||||||
|
|
||||||
### Introduction of `keyboard.json` ([22891](https://github.com/qmk/qmk_firmware/pull/22891)) :id=keyboard-json
|
### Introduction of `keyboard.json` ([22891](https://github.com/qmk/qmk_firmware/pull/22891)) {#keyboard-json}
|
||||||
|
|
||||||
One longer term goal of QMK is increased maintainability.
|
One longer term goal of QMK is increased maintainability.
|
||||||
As part of the continued push towards [Data Driven Configuration](data_driven_config.md), the build system has been updated to simplify the existing codebase, and power future workflows.
|
As part of the continued push towards [Data Driven Configuration](../data_driven_config), the build system has been updated to simplify the existing codebase, and power future workflows.
|
||||||
|
|
||||||
The `keyboard.json` configuration file allows the support of a single data file for keyboard level config.
|
The `keyboard.json` configuration file allows the support of a single data file for keyboard level config.
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ Essentially, changes were made in the internals of how QMK interacts with USB fo
|
||||||
|
|
||||||
Compliance checks were run against QMK firmwares for the most popular ARM microcontrollers, as well as suspend/resume tests. As far as we can tell, a whole host of hard-to-reproduce issues are mitigated by this change.
|
Compliance checks were run against QMK firmwares for the most popular ARM microcontrollers, as well as suspend/resume tests. As far as we can tell, a whole host of hard-to-reproduce issues are mitigated by this change.
|
||||||
|
|
||||||
## Full changelist :id=full-changelist
|
## Full changelist {#full-changelist}
|
||||||
|
|
||||||
Core:
|
Core:
|
||||||
* Refactor vusb to protocol use pre/post task ([#14944](https://github.com/qmk/qmk_firmware/pull/14944))
|
* Refactor vusb to protocol use pre/post task ([#14944](https://github.com/qmk/qmk_firmware/pull/14944))
|
||||||
|
|
|
@ -6,8 +6,6 @@ This page lays out the capabilities used by the QMK Firmware documentation, in o
|
||||||
|
|
||||||
Unrelated to styling, high-level tech.
|
Unrelated to styling, high-level tech.
|
||||||
|
|
||||||
* I18n -- translations to other languages: [_langs.md](_langs.md)
|
|
||||||
* Sidebar -- listing of pages by category: [_summary.md](_summary.md)
|
|
||||||
* Title anchors -- `:id=some-anchor-name`, used for direct linking to sections
|
* Title anchors -- `:id=some-anchor-name`, used for direct linking to sections
|
||||||
* Links to anchors:
|
* Links to anchors:
|
||||||
* Style 1: [early initialization](platformdev_chibios_earlyinit.md?id=board-init)
|
* Style 1: [early initialization](platformdev_chibios_earlyinit.md?id=board-init)
|
||||||
|
@ -40,7 +38,10 @@ Unrelated to styling, high-level tech.
|
||||||
|
|
||||||
![QMK Color Wheel with HSV Values](https://i.imgur.com/vkYVo66.jpg)
|
![QMK Color Wheel with HSV Values](https://i.imgur.com/vkYVo66.jpg)
|
||||||
|
|
||||||
<img src="gitbook/images/color-wheel.svg" alt="HSV Color Wheel" width="250"/>
|
![QMK Light](./public/badge-community-light.svg)
|
||||||
|
![QMK Dark](./public/badge-community-dark.svg)
|
||||||
|
|
||||||
|
<img src="./gitbook/images/color-wheel.svg" alt="HSV Color Wheel" width="250"/>
|
||||||
|
|
||||||
### Lists
|
### Lists
|
||||||
|
|
||||||
|
@ -126,6 +127,26 @@ Command+<code>`</code>
|
||||||
|
|
||||||
!> Notification, damnit!
|
!> Notification, damnit!
|
||||||
|
|
||||||
|
::: info
|
||||||
|
This is an info box.
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: tip
|
||||||
|
This is a tip.
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
This is a warning.
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: danger
|
||||||
|
This is a dangerous warning.
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: details
|
||||||
|
This is a details block.
|
||||||
|
:::
|
||||||
|
|
||||||
### Keyboard keys
|
### Keyboard keys
|
||||||
|
|
||||||
<kbd>,</kbd>
|
<kbd>,</kbd>
|
||||||
|
@ -242,6 +263,20 @@ Content three
|
||||||
|
|
||||||
<!-- tabs:end -->
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
::::tabs
|
||||||
|
=== tab a
|
||||||
|
a content 2
|
||||||
|
=== tab b
|
||||||
|
b content 2
|
||||||
|
=== tab c
|
||||||
|
:::tabs
|
||||||
|
== nested tab a
|
||||||
|
nested a content 2
|
||||||
|
== nested tab b
|
||||||
|
nested b content 2
|
||||||
|
:::
|
||||||
|
::::
|
||||||
|
|
||||||
## Details sections
|
## Details sections
|
||||||
|
|
||||||
Expandable:
|
Expandable:
|
||||||
|
@ -254,8 +289,10 @@ Expandable:
|
||||||
This is some inner content.
|
This is some inner content.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
[1]: https://en.wikipedia.org/wiki/Eclipse_(software)
|
|
||||||
|
|
||||||
## Embed
|
## Embed
|
||||||
|
|
||||||
[example embed](__capabilities_inc.md ':include')
|
[example embed](__capabilities_inc.md ':include')
|
||||||
|
|
||||||
|
<!--@include: ./__capabilities_inc.md-->
|
||||||
|
|
||||||
|
[1]: https://en.wikipedia.org/wiki/Eclipse_(software)
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
- Translations
|
|
||||||
- [:uk: English](/)
|
|
||||||
- [:cn: 简体中文](/zh-cn/)
|
|
||||||
- [:jp: 日本語](/ja/)
|
|
|
@ -0,0 +1,309 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "Tutorial",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Introduction", "link": "/newbs" },
|
||||||
|
{ "text": "Setup", "link": "/newbs_getting_started" },
|
||||||
|
{ "text": "Building Your First Firmware", "link": "/newbs_building_firmware" },
|
||||||
|
{ "text": "Flashing Firmware", "link": "/newbs_flashing" },
|
||||||
|
{ "text": "Getting Help/Support", "link": "/support" },
|
||||||
|
{ "text": "External Userspace", "link": "/newbs_external_userspace" },
|
||||||
|
{ "text": "Other Resources", "link": "/newbs_learn_more_resources" },
|
||||||
|
{ "text": "Syllabus", "link": "/syllabus" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "FAQs",
|
||||||
|
"items": [
|
||||||
|
{ "text": "General FAQ", "link": "/faq_general" },
|
||||||
|
{ "text": "Build/Compile QMK", "link": "/faq_build" },
|
||||||
|
{ "text": "Troubleshooting QMK", "link": "/faq_misc" },
|
||||||
|
{ "text": "Debugging QMK", "link": "/faq_debug" },
|
||||||
|
{ "text": "Keymap FAQ", "link": "/faq_keymap" },
|
||||||
|
{ "text": "Squeezing Space from AVR", "link": "/squeezing_avr" },
|
||||||
|
{ "text": "Glossary", "link": "/reference_glossary" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Configurator",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Overview", "link": "/newbs_building_firmware_configurator" },
|
||||||
|
{ "text": "Step by Step", "link": "/configurator_step_by_step" },
|
||||||
|
{ "text": "Troubleshooting", "link": "/configurator_troubleshooting" },
|
||||||
|
{ "text": "Architecture", "link": "/configurator_architecture" },
|
||||||
|
{
|
||||||
|
"text": "QMK API",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Overview", "link": "/api_overview" },
|
||||||
|
{ "text": "API Documentation", "link": "/api_docs" },
|
||||||
|
{ "text": "Keyboard Support", "link": "/reference_configurator_support" },
|
||||||
|
{ "text": "Adding Default Keymaps", "link": "/configurator_default_keymaps" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "CLI",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Overview", "link": "/cli" },
|
||||||
|
{ "text": "Configuration", "link": "/cli_configuration" },
|
||||||
|
{ "text": "Commands", "link": "/cli_commands" },
|
||||||
|
{ "text": "Tab Completion", "link": "/cli_tab_complete" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Using QMK",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"text": "Guides",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Customizing Functionality", "link": "/custom_quantum_functions" },
|
||||||
|
{ "text": "Driver Installation with Zadig", "link": "/driver_installation_zadig" },
|
||||||
|
{ "text": "Keymap Overview", "link": "/keymap" },
|
||||||
|
{
|
||||||
|
"text": "Development Environments",
|
||||||
|
"items": [{ "text": "Docker Guide", "link": "/getting_started_docker" }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Flashing",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Flashing", "link": "/flashing" },
|
||||||
|
{ "text": "Flashing ATmega32A (ps2avrgb)", "link": "/flashing_bootloadhid" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "IDEs",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Using Eclipse with QMK", "link": "/other_eclipse" },
|
||||||
|
{ "text": "Using VSCode with QMK", "link": "/other_vscode" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Git Best Practices",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Introduction", "link": "/newbs_git_best_practices" },
|
||||||
|
{ "text": "Your Fork", "link": "/newbs_git_using_your_master_branch" },
|
||||||
|
{ "text": "Merge Conflicts", "link": "/newbs_git_resolving_merge_conflicts" },
|
||||||
|
{ "text": "Fixing Your Branch", "link": "/newbs_git_resynchronize_a_branch" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Simple Keycodes",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Full List", "link": "/keycodes" },
|
||||||
|
{ "text": "Basic Keycodes", "link": "/keycodes_basic" },
|
||||||
|
{ "text": "Language-Specific Keycodes", "link": "/reference_keymap_extras" },
|
||||||
|
{ "text": "Modifier Keys", "link": "/feature_advanced_keycodes" },
|
||||||
|
{ "text": "Quantum Keycodes", "link": "/quantum_keycodes" },
|
||||||
|
{ "text": "Magic Keycodes", "link": "/keycodes_magic" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Advanced Keycodes",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Command", "link": "/feature_command" },
|
||||||
|
{ "text": "Dynamic Macros", "link": "/feature_dynamic_macros" },
|
||||||
|
{ "text": "Grave Escape", "link": "/feature_grave_esc" },
|
||||||
|
{ "text": "Leader Key", "link": "/feature_leader_key" },
|
||||||
|
{ "text": "Mod-Tap", "link": "/mod_tap" },
|
||||||
|
{ "text": "Macros", "link": "/feature_macros" },
|
||||||
|
{ "text": "Mouse Keys", "link": "/feature_mouse_keys" },
|
||||||
|
{ "text": "Programmable Button", "link": "/feature_programmable_button" },
|
||||||
|
{ "text": "Repeat Key", "link": "/feature_repeat_key" },
|
||||||
|
{ "text": "Space Cadet Shift", "link": "/feature_space_cadet" },
|
||||||
|
{ "text": "US ANSI Shifted Keys", "link": "/keycodes_us_ansi_shifted" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Software Features",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Auto Shift", "link": "/feature_auto_shift" },
|
||||||
|
{ "text": "Autocorrect", "link": "/feature_autocorrect" },
|
||||||
|
{ "text": "Caps Word", "link": "/feature_caps_word" },
|
||||||
|
{ "text": "Combos", "link": "/feature_combo" },
|
||||||
|
{ "text": "Debounce API", "link": "/feature_debounce_type" },
|
||||||
|
{ "text": "Digitizer", "link": "/feature_digitizer" },
|
||||||
|
{ "text": "EEPROM", "link": "/feature_eeprom" },
|
||||||
|
{ "text": "Key Lock", "link": "/feature_key_lock" },
|
||||||
|
{ "text": "Key Overrides", "link": "/feature_key_overrides" },
|
||||||
|
{ "text": "Layers", "link": "/feature_layers" },
|
||||||
|
{ "text": "One Shot Keys", "link": "/one_shot_keys" },
|
||||||
|
{ "text": "OS Detection", "link": "/feature_os_detection" },
|
||||||
|
{ "text": "Raw HID", "link": "/feature_rawhid" },
|
||||||
|
{ "text": "Secure", "link": "/feature_secure" },
|
||||||
|
{ "text": "Send String", "link": "/feature_send_string" },
|
||||||
|
{ "text": "Sequencer", "link": "/feature_sequencer" },
|
||||||
|
{ "text": "Swap Hands", "link": "/feature_swap_hands" },
|
||||||
|
{ "text": "Tap Dance", "link": "/feature_tap_dance" },
|
||||||
|
{ "text": "Tap-Hold Configuration", "link": "/tap_hold" },
|
||||||
|
{ "text": "Tri Layer", "link": "/feature_tri_layer" },
|
||||||
|
{ "text": "Unicode", "link": "/feature_unicode" },
|
||||||
|
{ "text": "Userspace", "link": "/feature_userspace" },
|
||||||
|
{ "text": "WPM Calculation", "link": "/feature_wpm" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Hardware Features",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"text": "Displays",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"text": "Quantum Painter",
|
||||||
|
"link": "quantum_painter",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Quantum Painter LVGL Integration", "link": "/quantum_painter_lvgl" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "text": "HD44780 LCD Driver", "link": "/feature_hd44780" },
|
||||||
|
{ "text": "ST7565 LCD Driver", "link": "/feature_st7565" },
|
||||||
|
{ "text": "OLED Driver", "link": "/feature_oled_driver" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Lighting",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Backlight", "link": "/feature_backlight" },
|
||||||
|
{ "text": "LED Matrix", "link": "/feature_led_matrix" },
|
||||||
|
{ "text": "RGB Lighting", "link": "/feature_rgblight" },
|
||||||
|
{ "text": "RGB Matrix", "link": "/feature_rgb_matrix" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "text": "Audio", "link": "/feature_audio" },
|
||||||
|
{ "text": "Bluetooth", "link": "/feature_bluetooth" },
|
||||||
|
{ "text": "Bootmagic Lite", "link": "/feature_bootmagic" },
|
||||||
|
{ "text": "Converters", "link": "/feature_converters" },
|
||||||
|
{ "text": "Custom Matrix", "link": "/custom_matrix" },
|
||||||
|
{ "text": "DIP Switch", "link": "/feature_dip_switch" },
|
||||||
|
{ "text": "Encoders", "link": "/feature_encoders" },
|
||||||
|
{ "text": "Haptic Feedback", "link": "/feature_haptic_feedback" },
|
||||||
|
{ "text": "Joystick", "link": "/feature_joystick" },
|
||||||
|
{ "text": "LED Indicators", "link": "/feature_led_indicators" },
|
||||||
|
{ "text": "MIDI", "link": "/feature_midi" },
|
||||||
|
{ "text": "Pointing Device", "link": "/feature_pointing_device" },
|
||||||
|
{ "text": "PS/2 Mouse", "link": "/feature_ps2_mouse" },
|
||||||
|
{ "text": "Split Keyboard", "link": "/feature_split_keyboard" },
|
||||||
|
{ "text": "Stenography", "link": "/feature_stenography" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Keyboard Building",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Easy Maker for One Offs", "link": "/easy_maker" },
|
||||||
|
{ "text": "Porting Keyboards", "link": "/porting_your_keyboard_to_qmk" },
|
||||||
|
{ "text": "Hand Wiring Guide", "link": "/hand_wire" },
|
||||||
|
{ "text": "ISP Flashing Guide", "link": "/isp_flashing_guide" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Developing QMK",
|
||||||
|
"items": [
|
||||||
|
{ "text": "PR Checklist", "link": "/pr_checklist" },
|
||||||
|
{
|
||||||
|
"text": "Breaking Changes",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Overview", "link": "/breaking_changes" },
|
||||||
|
{ "text": "My Pull Request Was Flagged", "link": "/breaking_changes_instructions" },
|
||||||
|
{
|
||||||
|
"text": "Most Recent ChangeLog",
|
||||||
|
"link": "/ChangeLog/20240526"
|
||||||
|
},
|
||||||
|
{ "text": "Past Breaking Changes", "link": "/breaking_changes_history" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"text": "C Development",
|
||||||
|
"items": [
|
||||||
|
{ "text": "ARM Debugging Guide", "link": "/arm_debugging" },
|
||||||
|
{ "text": "Coding Conventions", "link": "/coding_conventions_c" },
|
||||||
|
{ "text": "Compatible Microcontrollers", "link": "/compatible_microcontrollers" },
|
||||||
|
{
|
||||||
|
"text": "Drivers",
|
||||||
|
"link": "hardware_drivers",
|
||||||
|
"items": [
|
||||||
|
{ "text": "ADC Driver", "link": "/adc_driver" },
|
||||||
|
{ "text": "APA102 Driver", "link": "/apa102_driver" },
|
||||||
|
{ "text": "Audio Driver", "link": "/audio_driver" },
|
||||||
|
{ "text": "I2C Driver", "link": "/i2c_driver" },
|
||||||
|
{ "text": "SPI Driver", "link": "/spi_driver" },
|
||||||
|
{ "text": "WS2812 Driver", "link": "/ws2812_driver" },
|
||||||
|
{ "text": "EEPROM Driver", "link": "/eeprom_driver" },
|
||||||
|
{ "text": "Flash Driver", "link": "/flash_driver" },
|
||||||
|
{ "text": "'serial' Driver", "link": "/serial_driver" },
|
||||||
|
{ "text": "UART Driver", "link": "/uart_driver" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "text": "GPIO Controls", "link": "/gpio_control" },
|
||||||
|
{ "text": "Keyboard Guidelines", "link": "/hardware_keyboard_guidelines" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"text": "Python Development",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Coding Conventions", "link": "/coding_conventions_python" },
|
||||||
|
{ "text": "QMK CLI Development", "link": "/cli_development" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"text": "Configurator Development",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"text": "QMK API",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Development Environment", "link": "/api_development_environment" },
|
||||||
|
{ "text": "Architecture Overview", "link": "/api_development_overview" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"text": "Hardware Platform Development",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"text": "Arm/ChibiOS",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Selecting an MCU", "link": "/platformdev_selecting_arm_mcu" },
|
||||||
|
{ "text": "Early initialization", "link": "/platformdev_chibios_earlyinit" },
|
||||||
|
{ "text": "Raspberry Pi RP2040", "link": "/platformdev_rp2040" },
|
||||||
|
{ "text": "Proton C", "link": "/platformdev_proton_c" },
|
||||||
|
{ "text": "WeAct Blackpill F4x1", "link": "/platformdev_blackpill_f4x1" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"text": "QMK Reference",
|
||||||
|
"items": [
|
||||||
|
{ "text": "Contributing to QMK", "link": "/contributing" },
|
||||||
|
{ "text": "Config Options", "link": "/config_options" },
|
||||||
|
{ "text": "Data Driven Configuration", "link": "/data_driven_config" },
|
||||||
|
{ "text": "Make Documentation", "link": "/getting_started_make_guide" },
|
||||||
|
{ "text": "Documentation Best Practices", "link": "/documentation_best_practices" },
|
||||||
|
{ "text": "Documentation Templates", "link": "/documentation_templates" },
|
||||||
|
{ "text": "Community Layouts", "link": "/feature_layouts" },
|
||||||
|
{ "text": "Unit Testing", "link": "/unit_testing" },
|
||||||
|
{ "text": "Useful Functions", "link": "/ref_functions" },
|
||||||
|
{ "text": "info.json Format", "link": "/reference_info_json" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"text": "For a Deeper Understanding",
|
||||||
|
"items": [
|
||||||
|
{ "text": "How Keyboards Work", "link": "/how_keyboards_work" },
|
||||||
|
{ "text": "How a Matrix Works", "link": "/how_a_matrix_works" },
|
||||||
|
{ "text": "Understanding QMK", "link": "/understanding_qmk" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
204
docs/_summary.md
204
docs/_summary.md
|
@ -1,204 +0,0 @@
|
||||||
* Tutorial
|
|
||||||
* [Introduction](newbs.md)
|
|
||||||
* [Setup](newbs_getting_started.md)
|
|
||||||
* [Building Your First Firmware](newbs_building_firmware.md)
|
|
||||||
* [Flashing Firmware](newbs_flashing.md)
|
|
||||||
* [Getting Help/Support](support.md)
|
|
||||||
* [External Userspace](newbs_external_userspace.md)
|
|
||||||
* [Other Resources](newbs_learn_more_resources.md)
|
|
||||||
* [Syllabus](syllabus.md)
|
|
||||||
|
|
||||||
* FAQs
|
|
||||||
* [General FAQ](faq_general.md)
|
|
||||||
* [Build/Compile QMK](faq_build.md)
|
|
||||||
* [Troubleshooting QMK](faq_misc.md)
|
|
||||||
* [Debugging QMK](faq_debug.md)
|
|
||||||
* [Keymap FAQ](faq_keymap.md)
|
|
||||||
* [Squeezing Space from AVR](squeezing_avr.md)
|
|
||||||
* [Glossary](reference_glossary.md)
|
|
||||||
|
|
||||||
* Configurator
|
|
||||||
* [Overview](newbs_building_firmware_configurator.md)
|
|
||||||
* [Step by Step](configurator_step_by_step.md)
|
|
||||||
* [Troubleshooting](configurator_troubleshooting.md)
|
|
||||||
* [Architecture](configurator_architecture.md)
|
|
||||||
* QMK API
|
|
||||||
* [Overview](api_overview.md)
|
|
||||||
* [API Documentation](api_docs.md)
|
|
||||||
* [Keyboard Support](reference_configurator_support.md)
|
|
||||||
* [Adding Default Keymaps](configurator_default_keymaps.md)
|
|
||||||
|
|
||||||
* CLI
|
|
||||||
* [Overview](cli.md)
|
|
||||||
* [Configuration](cli_configuration.md)
|
|
||||||
* [Commands](cli_commands.md)
|
|
||||||
* [Tab Completion](cli_tab_complete.md)
|
|
||||||
|
|
||||||
* Using QMK
|
|
||||||
* Guides
|
|
||||||
* [Customizing Functionality](custom_quantum_functions.md)
|
|
||||||
* [Driver Installation with Zadig](driver_installation_zadig.md)
|
|
||||||
* [Keymap Overview](keymap.md)
|
|
||||||
* Development Environments
|
|
||||||
* [Docker Guide](getting_started_docker.md)
|
|
||||||
* Flashing
|
|
||||||
* [Flashing](flashing.md)
|
|
||||||
* [Flashing ATmega32A (ps2avrgb)](flashing_bootloadhid.md)
|
|
||||||
* IDEs
|
|
||||||
* [Using Eclipse with QMK](other_eclipse.md)
|
|
||||||
* [Using VSCode with QMK](other_vscode.md)
|
|
||||||
* Git Best Practices
|
|
||||||
* [Introduction](newbs_git_best_practices.md)
|
|
||||||
* [Your Fork](newbs_git_using_your_master_branch.md)
|
|
||||||
* [Merge Conflicts](newbs_git_resolving_merge_conflicts.md)
|
|
||||||
* [Fixing Your Branch](newbs_git_resynchronize_a_branch.md)
|
|
||||||
|
|
||||||
* Simple Keycodes
|
|
||||||
* [Full List](keycodes.md)
|
|
||||||
* [Basic Keycodes](keycodes_basic.md)
|
|
||||||
* [Language-Specific Keycodes](reference_keymap_extras.md)
|
|
||||||
* [Modifier Keys](feature_advanced_keycodes.md)
|
|
||||||
* [Quantum Keycodes](quantum_keycodes.md)
|
|
||||||
* [Magic Keycodes](keycodes_magic.md)
|
|
||||||
|
|
||||||
* Advanced Keycodes
|
|
||||||
* [Command](feature_command.md)
|
|
||||||
* [Dynamic Macros](feature_dynamic_macros.md)
|
|
||||||
* [Grave Escape](feature_grave_esc.md)
|
|
||||||
* [Leader Key](feature_leader_key.md)
|
|
||||||
* [Mod-Tap](mod_tap.md)
|
|
||||||
* [Macros](feature_macros.md)
|
|
||||||
* [Mouse Keys](feature_mouse_keys.md)
|
|
||||||
* [Programmable Button](feature_programmable_button.md)
|
|
||||||
* [Repeat Key](feature_repeat_key.md)
|
|
||||||
* [Space Cadet Shift](feature_space_cadet.md)
|
|
||||||
* [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
|
|
||||||
|
|
||||||
* Software Features
|
|
||||||
* [Auto Shift](feature_auto_shift.md)
|
|
||||||
* [Autocorrect](feature_autocorrect.md)
|
|
||||||
* [Caps Word](feature_caps_word.md)
|
|
||||||
* [Combos](feature_combo.md)
|
|
||||||
* [Debounce API](feature_debounce_type.md)
|
|
||||||
* [Digitizer](feature_digitizer.md)
|
|
||||||
* [EEPROM](feature_eeprom.md)
|
|
||||||
* [Key Lock](feature_key_lock.md)
|
|
||||||
* [Key Overrides](feature_key_overrides.md)
|
|
||||||
* [Layers](feature_layers.md)
|
|
||||||
* [One Shot Keys](one_shot_keys.md)
|
|
||||||
* [OS Detection](feature_os_detection.md)
|
|
||||||
* [Raw HID](feature_rawhid.md)
|
|
||||||
* [Secure](feature_secure.md)
|
|
||||||
* [Send String](feature_send_string.md)
|
|
||||||
* [Sequencer](feature_sequencer.md)
|
|
||||||
* [Swap Hands](feature_swap_hands.md)
|
|
||||||
* [Tap Dance](feature_tap_dance.md)
|
|
||||||
* [Tap-Hold Configuration](tap_hold.md)
|
|
||||||
* [Tri Layer](feature_tri_layer.md)
|
|
||||||
* [Unicode](feature_unicode.md)
|
|
||||||
* [Userspace](feature_userspace.md)
|
|
||||||
* [WPM Calculation](feature_wpm.md)
|
|
||||||
|
|
||||||
* Hardware Features
|
|
||||||
* Displays
|
|
||||||
* [Quantum Painter](quantum_painter.md)
|
|
||||||
* [Quantum Painter LVGL Integration](quantum_painter_lvgl.md)
|
|
||||||
* [HD44780 LCD Driver](feature_hd44780.md)
|
|
||||||
* [ST7565 LCD Driver](feature_st7565.md)
|
|
||||||
* [OLED Driver](feature_oled_driver.md)
|
|
||||||
* Lighting
|
|
||||||
* [Backlight](feature_backlight.md)
|
|
||||||
* [LED Matrix](feature_led_matrix.md)
|
|
||||||
* [RGB Lighting](feature_rgblight.md)
|
|
||||||
* [RGB Matrix](feature_rgb_matrix.md)
|
|
||||||
* [Audio](feature_audio.md)
|
|
||||||
* [Bluetooth](feature_bluetooth.md)
|
|
||||||
* [Bootmagic Lite](feature_bootmagic.md)
|
|
||||||
* [Converters](feature_converters.md)
|
|
||||||
* [Custom Matrix](custom_matrix.md)
|
|
||||||
* [DIP Switch](feature_dip_switch.md)
|
|
||||||
* [Encoders](feature_encoders.md)
|
|
||||||
* [Haptic Feedback](feature_haptic_feedback.md)
|
|
||||||
* [Joystick](feature_joystick.md)
|
|
||||||
* [LED Indicators](feature_led_indicators.md)
|
|
||||||
* [MIDI](feature_midi.md)
|
|
||||||
* [Pointing Device](feature_pointing_device.md)
|
|
||||||
* [PS/2 Mouse](feature_ps2_mouse.md)
|
|
||||||
* [Split Keyboard](feature_split_keyboard.md)
|
|
||||||
* [Stenography](feature_stenography.md)
|
|
||||||
|
|
||||||
* Keyboard Building
|
|
||||||
* [Easy Maker for One Offs](easy_maker.md)
|
|
||||||
* [Porting Keyboards](porting_your_keyboard_to_qmk.md)
|
|
||||||
* [Hand Wiring Guide](hand_wire.md)
|
|
||||||
* [ISP Flashing Guide](isp_flashing_guide.md)
|
|
||||||
|
|
||||||
* Developing QMK
|
|
||||||
* [PR Checklist](pr_checklist.md)
|
|
||||||
* Breaking Changes
|
|
||||||
* [Overview](breaking_changes.md)
|
|
||||||
* [My Pull Request Was Flagged](breaking_changes_instructions.md)
|
|
||||||
* [Most Recent ChangeLog](ChangeLog/20240526.md "QMK v0.25.0 - 2024 May 26")
|
|
||||||
* [Past Breaking Changes](breaking_changes_history.md)
|
|
||||||
|
|
||||||
* C Development
|
|
||||||
* [ARM Debugging Guide](arm_debugging.md)
|
|
||||||
* [Coding Conventions](coding_conventions_c.md)
|
|
||||||
* [Compatible Microcontrollers](compatible_microcontrollers.md)
|
|
||||||
* [Drivers](hardware_drivers.md)
|
|
||||||
* [ADC Driver](adc_driver.md)
|
|
||||||
* [APA102 Driver](apa102_driver.md)
|
|
||||||
* [Audio Driver](audio_driver.md)
|
|
||||||
* [I2C Driver](i2c_driver.md)
|
|
||||||
* [SPI Driver](spi_driver.md)
|
|
||||||
* [WS2812 Driver](ws2812_driver.md)
|
|
||||||
* [EEPROM Driver](eeprom_driver.md)
|
|
||||||
* [Flash Driver](flash_driver.md)
|
|
||||||
* ['serial' Driver](serial_driver.md)
|
|
||||||
* [UART Driver](uart_driver.md)
|
|
||||||
* [GPIO Controls](gpio_control.md)
|
|
||||||
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
|
|
||||||
|
|
||||||
* Python Development
|
|
||||||
* [Coding Conventions](coding_conventions_python.md)
|
|
||||||
* [QMK CLI Development](cli_development.md)
|
|
||||||
|
|
||||||
* Configurator Development
|
|
||||||
* QMK API
|
|
||||||
* [Development Environment](api_development_environment.md)
|
|
||||||
* [Architecture Overview](api_development_overview.md)
|
|
||||||
|
|
||||||
* Hardware Platform Development
|
|
||||||
* Arm/ChibiOS
|
|
||||||
* [Selecting an MCU](platformdev_selecting_arm_mcu.md)
|
|
||||||
* [Early initialization](platformdev_chibios_earlyinit.md)
|
|
||||||
* [Raspberry Pi RP2040](platformdev_rp2040.md)
|
|
||||||
* [Proton C](platformdev_proton_c.md)
|
|
||||||
* [WeAct Blackpill F4x1](platformdev_blackpill_f4x1.md)
|
|
||||||
|
|
||||||
* QMK Reference
|
|
||||||
* [Contributing to QMK](contributing.md)
|
|
||||||
* [Translating the QMK Docs](translating.md)
|
|
||||||
* [Config Options](config_options.md)
|
|
||||||
* [Data Driven Configuration](data_driven_config.md)
|
|
||||||
* [Make Documentation](getting_started_make_guide.md)
|
|
||||||
* [Documentation Best Practices](documentation_best_practices.md)
|
|
||||||
* [Documentation Templates](documentation_templates.md)
|
|
||||||
* [Community Layouts](feature_layouts.md)
|
|
||||||
* [Unit Testing](unit_testing.md)
|
|
||||||
* [Useful Functions](ref_functions.md)
|
|
||||||
* [info.json Format](reference_info_json.md)
|
|
||||||
|
|
||||||
* For a Deeper Understanding
|
|
||||||
* [How Keyboards Work](how_keyboards_work.md)
|
|
||||||
* [How a Matrix Works](how_a_matrix_works.md)
|
|
||||||
* [Understanding QMK](understanding_qmk.md)
|
|
||||||
|
|
||||||
* QMK Internals (In Progress)
|
|
||||||
* [Defines](internals/defines.md)
|
|
||||||
* [Input Callback Reg](internals/input_callback_reg.md)
|
|
||||||
* [Midi Device](internals/midi_device.md)
|
|
||||||
* [Midi Device Setup Process](internals/midi_device_setup_process.md)
|
|
||||||
* [Midi Util](internals/midi_util.md)
|
|
||||||
* [Send Functions](internals/send_functions.md)
|
|
||||||
* [Sysex Tools](internals/sysex_tools.md)
|
|
|
@ -1,6 +1,6 @@
|
||||||
# ADC Driver
|
# ADC Driver
|
||||||
|
|
||||||
QMK can leverage the Analog-to-Digital Converter (ADC) on supported MCUs to measure voltages on certain pins. This can be useful for implementing things such as battery level indicators for Bluetooth keyboards, or volume controls using a potentiometer, as opposed to a [rotary encoder](feature_encoders.md).
|
QMK can leverage the Analog-to-Digital Converter (ADC) on supported MCUs to measure voltages on certain pins. This can be useful for implementing things such as battery level indicators for Bluetooth keyboards, or volume controls using a potentiometer, as opposed to a [rotary encoder](feature_encoders).
|
||||||
|
|
||||||
This driver currently supports both AVR and a limited selection of ARM devices. The values returned are 10-bit integers (0-1023) mapped between 0V and VCC (usually 5V or 3.3V for AVR, 3.3V only for ARM), however on ARM there is more flexibility in control of operation through `#define`s if you need more precision.
|
This driver currently supports both AVR and a limited selection of ARM devices. The values returned are 10-bit integers (0-1023) mapped between 0V and VCC (usually 5V or 3.3V for AVR, 3.3V only for ARM), however on ARM there is more flexibility in control of operation through `#define`s if you need more precision.
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# APA102 Driver :id=apa102-driver
|
# APA102 Driver {#apa102-driver}
|
||||||
|
|
||||||
This driver provides support for APA102 addressable RGB LEDs. They are similar to the [WS2812](ws2812_driver.md) LEDs, but have increased data and refresh rates.
|
This driver provides support for APA102 addressable RGB LEDs. They are similar to the [WS2812](ws2812_driver) LEDs, but have increased data and refresh rates.
|
||||||
|
|
||||||
## Usage :id=usage
|
## Usage {#usage}
|
||||||
|
|
||||||
In most cases, the APA102 driver code is automatically included if you are using either the [RGBLight](feature_rgblight.md) or [RGB Matrix](feature_rgb_matrix.md) feature with the `apa102` driver set, and you would use those APIs instead.
|
In most cases, the APA102 driver code is automatically included if you are using either the [RGBLight](feature_rgblight) or [RGB Matrix](feature_rgb_matrix) feature with the `apa102` driver set, and you would use those APIs instead.
|
||||||
|
|
||||||
However, if you need to use the driver standalone, add the following to your `rules.mk`:
|
However, if you need to use the driver standalone, add the following to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ APA102_DRIVER_REQUIRED = yes
|
||||||
|
|
||||||
You can then call the APA102 API by including `apa102.h` in your code.
|
You can then call the APA102 API by including `apa102.h` in your code.
|
||||||
|
|
||||||
## Basic Configuration :id=basic-configuration
|
## Basic Configuration {#basic-configuration}
|
||||||
|
|
||||||
Add the following to your `config.h`:
|
Add the following to your `config.h`:
|
||||||
|
|
||||||
|
@ -24,13 +24,13 @@ Add the following to your `config.h`:
|
||||||
|`APA102_CI_PIN` |*Not defined*|The GPIO pin connected to the CI pin of the first LED in the chain|
|
|`APA102_CI_PIN` |*Not defined*|The GPIO pin connected to the CI pin of the first LED in the chain|
|
||||||
|`APA102_DEFAULT_BRIGHTNESS`|`31` |The default global brightness level of the LEDs, from 0 to 31 |
|
|`APA102_DEFAULT_BRIGHTNESS`|`31` |The default global brightness level of the LEDs, from 0 to 31 |
|
||||||
|
|
||||||
## API :id=api
|
## API {#api}
|
||||||
|
|
||||||
### `void apa102_setleds(rgb_led_t *start_led, uint16_t num_leds)`
|
### `void apa102_setleds(rgb_led_t *start_led, uint16_t num_leds)`
|
||||||
|
|
||||||
Send RGB data to the APA102 LED chain.
|
Send RGB data to the APA102 LED chain.
|
||||||
|
|
||||||
#### Arguments :id=api-apa102-setleds-arguments
|
#### Arguments {#api-apa102-setleds-arguments}
|
||||||
|
|
||||||
- `rgb_led_t *start_led`
|
- `rgb_led_t *start_led`
|
||||||
A pointer to the LED array.
|
A pointer to the LED array.
|
||||||
|
@ -43,7 +43,7 @@ Send RGB data to the APA102 LED chain.
|
||||||
|
|
||||||
Set the global brightness.
|
Set the global brightness.
|
||||||
|
|
||||||
#### Arguments :id=api-apa102-set-brightness-arguments
|
#### Arguments {#api-apa102-set-brightness-arguments}
|
||||||
|
|
||||||
- `uint8_t brightness`
|
- `uint8_t brightness`
|
||||||
The brightness level to set, from 0 to 31.
|
The brightness level to set, from 0 to 31.
|
||||||
|
|
|
@ -67,7 +67,7 @@ Once your compile job has finished you'll check the `result` key. The value of t
|
||||||
* `firmware_source_url`: A list of URLs for the full firmware source code
|
* `firmware_source_url`: A list of URLs for the full firmware source code
|
||||||
* `output`: The stdout and stderr for this compile job. Errors will be found here.
|
* `output`: The stdout and stderr for this compile job. Errors will be found here.
|
||||||
|
|
||||||
## Constants :id=qmk-constants
|
## Constants {#qmk-constants}
|
||||||
|
|
||||||
If you're writing a tool that leverages constants used within QMK, the API is used to publish "locked-in" versions of those constants in order to ensure that any third-party tooling has a canonical set of information to work with.
|
If you're writing a tool that leverages constants used within QMK, the API is used to publish "locked-in" versions of those constants in order to ensure that any third-party tooling has a canonical set of information to work with.
|
||||||
|
|
||||||
|
@ -81,9 +81,13 @@ $ curl https://keyboards.develop.qmk.fm/v1/constants_metadata.json # For `develo
|
||||||
{"last_updated": "2022-11-26 12:00:00 GMT", "constants": {"keycodes": ["0.0.1", "0.0.2"]}}
|
{"last_updated": "2022-11-26 12:00:00 GMT", "constants": {"keycodes": ["0.0.1", "0.0.2"]}}
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Versions exported by the `master` endpoint are locked-in. Any extra versions that exist on the `develop` endpoint which don't exist in `master` are subject to change.
|
::: warning
|
||||||
|
Versions exported by the `master` endpoint are locked-in. Any extra versions that exist on the `develop` endpoint which don't exist in `master` are subject to change.
|
||||||
|
:::
|
||||||
|
|
||||||
?> Only keycodes are currently published, but over time all other "externally visible" IDs are expected to appear on these endpoints.
|
::: tip
|
||||||
|
Only keycodes are currently published, but over time all other "externally visible" IDs are expected to appear on these endpoints.
|
||||||
|
:::
|
||||||
|
|
||||||
To retrieve the constants associated with a subsystem, the endpoint format is as follows:
|
To retrieve the constants associated with a subsystem, the endpoint format is as follows:
|
||||||
```
|
```
|
||||||
|
|
|
@ -4,12 +4,12 @@ The QMK API provides an asynchronous API that Web and GUI tools can use to compi
|
||||||
|
|
||||||
## App Developers
|
## App Developers
|
||||||
|
|
||||||
If you are an app developer interested in using this API in your application you should head over to [Using The API](api_docs.md).
|
If you are an app developer interested in using this API in your application you should head over to [Using The API](api_docs).
|
||||||
|
|
||||||
## Keyboard Maintainers
|
## Keyboard Maintainers
|
||||||
|
|
||||||
If you would like to enhance your keyboard's support in the QMK Compiler API head over to the [Keyboard Support](reference_configurator_support.md) section.
|
If you would like to enhance your keyboard's support in the QMK Compiler API head over to the [Keyboard Support](reference_configurator_support) section.
|
||||||
|
|
||||||
## Backend Developers
|
## Backend Developers
|
||||||
|
|
||||||
If you are interested in working on the API itself you should start by setting up a [Development Environment](api_development_environment.md), then check out [Hacking On The API](api_development_overview.md).
|
If you are interested in working on the API itself you should start by setting up a [Development Environment](api_development_environment), then check out [Hacking On The API](api_development_overview).
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Audio Driver :id=audio-driver
|
# Audio Driver {#audio-driver}
|
||||||
|
|
||||||
The [Audio feature](feature_audio.md) breaks the hardware specifics out into separate, exchangeable driver units, with a common interface to the audio-"core" - which itself handles playing songs and notes while tracking their progress in an internal state, initializing/starting/stopping the driver as needed.
|
The [Audio feature](feature_audio) breaks the hardware specifics out into separate, exchangeable driver units, with a common interface to the audio-"core" - which itself handles playing songs and notes while tracking their progress in an internal state, initializing/starting/stopping the driver as needed.
|
||||||
|
|
||||||
Not all MCUs support every available driver, either the platform-support is not there (yet?) or the MCU simply does not have the required hardware peripheral.
|
Not all MCUs support every available driver, either the platform-support is not there (yet?) or the MCU simply does not have the required hardware peripheral.
|
||||||
|
|
||||||
|
|
||||||
## AVR :id=avr
|
## AVR {#avr}
|
||||||
|
|
||||||
Boards built around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker.
|
Boards built around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker.
|
||||||
The possible configurations are:
|
The possible configurations are:
|
||||||
|
@ -23,7 +23,7 @@ AUDIO_DRIVER = pwm_hardware
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## ARM :id=arm
|
## ARM {#arm}
|
||||||
|
|
||||||
For Arm based boards, QMK depends on ChibiOS - hence any MCU supported by the later is likely usable, as long as certain hardware peripherals are available.
|
For Arm based boards, QMK depends on ChibiOS - hence any MCU supported by the later is likely usable, as long as certain hardware peripherals are available.
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ piezo speakers are marked with :one: for the first/primary and :two: for the sec
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### DAC basic :id=dac-basic
|
### DAC basic {#dac-basic}
|
||||||
|
|
||||||
The default driver for ARM boards, in absence of an overriding configuration.
|
The default driver for ARM boards, in absence of an overriding configuration.
|
||||||
This driver needs one Timer per enabled/used DAC channel, to trigger conversion; and a third timer to trigger state updates with the audio-core.
|
This driver needs one Timer per enabled/used DAC channel, to trigger conversion; and a third timer to trigger state updates with the audio-core.
|
||||||
|
@ -79,7 +79,9 @@ Additionally, in the board config, you'll want to make changes to enable the DAC
|
||||||
#define STM32_GPT_USE_TIM8 TRUE
|
#define STM32_GPT_USE_TIM8 TRUE
|
||||||
```
|
```
|
||||||
|
|
||||||
?> Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable).
|
::: tip
|
||||||
|
Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable).
|
||||||
|
:::
|
||||||
|
|
||||||
You can also change the timer used for the overall audio state by defining the driver. For instance:
|
You can also change the timer used for the overall audio state by defining the driver. For instance:
|
||||||
|
|
||||||
|
@ -87,7 +89,7 @@ You can also change the timer used for the overall audio state by defining the d
|
||||||
#define AUDIO_STATE_TIMER GPTD9
|
#define AUDIO_STATE_TIMER GPTD9
|
||||||
```
|
```
|
||||||
|
|
||||||
### DAC additive :id=dac-additive
|
### DAC additive {#dac-additive}
|
||||||
|
|
||||||
only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback.
|
only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback.
|
||||||
|
|
||||||
|
@ -131,7 +133,7 @@ There are a number of predefined quality settings that you can use, with "sane m
|
||||||
| `AUDIO_DAC_QUALITY_VERY_HIGH` | `88200U` | `1` | `256U` |
|
| `AUDIO_DAC_QUALITY_VERY_HIGH` | `88200U` | `1` | `256U` |
|
||||||
| `AUDIO_DAC_QUALITY_SANE_MINIMUM` | `16384U` | `8` | `64U` |
|
| `AUDIO_DAC_QUALITY_SANE_MINIMUM` | `16384U` | `8` | `64U` |
|
||||||
|
|
||||||
#### Notes on buffer size :id=buffer-size
|
#### Notes on buffer size {#buffer-size}
|
||||||
|
|
||||||
By default, the buffer size attempts to keep to these constraints:
|
By default, the buffer size attempts to keep to these constraints:
|
||||||
|
|
||||||
|
@ -162,7 +164,7 @@ You can lower the buffer size if you need a bit more space in your firmware, or
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### PWM hardware :id=pwm-hardware
|
### PWM hardware {#pwm-hardware}
|
||||||
|
|
||||||
This driver uses the ChibiOS-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware.
|
This driver uses the ChibiOS-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware.
|
||||||
The hardware directly toggles the pin via its alternate function. See your MCU's data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function.
|
The hardware directly toggles the pin via its alternate function. See your MCU's data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function.
|
||||||
|
@ -205,7 +207,7 @@ You can also use the Complementary output (`TIMx_CHyN`) for PWM on supported con
|
||||||
#define AUDIO_PWM_COMPLEMENTARY_OUTPUT
|
#define AUDIO_PWM_COMPLEMENTARY_OUTPUT
|
||||||
```
|
```
|
||||||
|
|
||||||
### PWM software :id=pwm-software
|
### PWM software {#pwm-software}
|
||||||
|
|
||||||
This driver uses the PWM callbacks from PWMD1 with TIM1_CH1 to toggle the selected AUDIO_PIN in software.
|
This driver uses the PWM callbacks from PWMD1 with TIM1_CH1 to toggle the selected AUDIO_PIN in software.
|
||||||
During the same callback, with AUDIO_PIN_ALT_AS_NEGATIVE set, the AUDIO_PIN_ALT is toggled inversely to AUDIO_PIN. This is useful for setups that drive a piezo from two pins (instead of one and Gnd).
|
During the same callback, with AUDIO_PIN_ALT_AS_NEGATIVE set, the AUDIO_PIN_ALT is toggled inversely to AUDIO_PIN. This is useful for setups that drive a piezo from two pins (instead of one and Gnd).
|
||||||
|
@ -217,7 +219,7 @@ You can also change the timer used for software PWM by defining the driver. For
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Testing Notes :id=testing-notes
|
### Testing Notes {#testing-notes}
|
||||||
|
|
||||||
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
|
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,10 @@ Practically, this means QMK merges the `develop` branch into the `master` branch
|
||||||
|
|
||||||
## What has been included in past Breaking Changes?
|
## What has been included in past Breaking Changes?
|
||||||
|
|
||||||
* [2024 May 26](ChangeLog/20240526.md)
|
* [2024 May 26](ChangeLog/20240526)
|
||||||
* [2024 Feb 25](ChangeLog/20240225.md)
|
* [2024 Feb 25](ChangeLog/20240225)
|
||||||
* [2023 Nov 26](ChangeLog/20231126.md)
|
* [2023 Nov 26](ChangeLog/20231126)
|
||||||
* [Older Breaking Changes](breaking_changes_history.md)
|
* [Older Breaking Changes](breaking_changes_history)
|
||||||
|
|
||||||
## When is the next Breaking Change?
|
## When is the next Breaking Change?
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ This section documents various processes we use when running the Breaking Change
|
||||||
### 1 Week Before Merge
|
### 1 Week Before Merge
|
||||||
|
|
||||||
* `develop` is now closed to PR merges, only critical bugfixes may be included
|
* `develop` is now closed to PR merges, only critical bugfixes may be included
|
||||||
* Announce that master will be closed from <2 Days Before> to <Day of Merge> -- message `@Breaking Changes Updates` on `#qmk_firmware` in Discord:
|
* Announce that master will be closed from `<2 Days Before>` to `<Day of Merge>` -- message `@Breaking Changes Updates` on `#qmk_firmware` in Discord:
|
||||||
* `@Breaking Changes Updates -- Hey folks, last day for functional PRs to be merged into qmk_firmware for this breaking changes cycle is today. After that, we're handling bugfixes only.`
|
* `@Breaking Changes Updates -- Hey folks, last day for functional PRs to be merged into qmk_firmware for this breaking changes cycle is today. After that, we're handling bugfixes only.`
|
||||||
|
|
||||||
### 2 Days Before Merge
|
### 2 Days Before Merge
|
||||||
|
@ -136,7 +136,7 @@ This happens immediately after the previous `develop` branch is merged to `maste
|
||||||
* Announce that both `master` and `develop` are now unlocked -- message `@Breaking Changes Updates` on `#qmk_firmware` in Discord:
|
* Announce that both `master` and `develop` are now unlocked -- message `@Breaking Changes Updates` on `#qmk_firmware` in Discord:
|
||||||
* `@Breaking Changes Updates -- Hey folks, develop has now been merged into master -- newest batch of changes are now available for everyone to use!`
|
* `@Breaking Changes Updates -- Hey folks, develop has now been merged into master -- newest batch of changes are now available for everyone to use!`
|
||||||
|
|
||||||
* (Optional) [update ChibiOS + ChibiOS-Contrib on `develop`](chibios_upgrade_instructions.md)
|
* (Optional) [update ChibiOS + ChibiOS-Contrib on `develop`](chibios_upgrade_instructions)
|
||||||
|
|
||||||
|
|
||||||
### Set up Discord events for the next cycle
|
### Set up Discord events for the next cycle
|
||||||
|
|
|
@ -2,22 +2,22 @@
|
||||||
|
|
||||||
This page links to all previous changelogs from the QMK Breaking Changes process.
|
This page links to all previous changelogs from the QMK Breaking Changes process.
|
||||||
|
|
||||||
* [2024 May 26](ChangeLog/20240526.md) - version 0.25.0
|
* [2024 May 26](ChangeLog/20240526) - version 0.25.0
|
||||||
* [2024 Feb 25](ChangeLog/20240225.md) - version 0.24.0
|
* [2024 Feb 25](ChangeLog/20240225) - version 0.24.0
|
||||||
* [2023 Nov 26](ChangeLog/20231126.md) - version 0.23.0
|
* [2023 Nov 26](ChangeLog/20231126) - version 0.23.0
|
||||||
* [2023 Aug 27](ChangeLog/20230827.md) - version 0.22.0
|
* [2023 Aug 27](ChangeLog/20230827) - version 0.22.0
|
||||||
* [2023 May 28](ChangeLog/20230528.md) - version 0.21.0
|
* [2023 May 28](ChangeLog/20230528) - version 0.21.0
|
||||||
* [2023 Feb 26](ChangeLog/20230226.md) - version 0.20.0
|
* [2023 Feb 26](ChangeLog/20230226) - version 0.20.0
|
||||||
* [2022 Nov 26](ChangeLog/20221126.md) - version 0.19.0
|
* [2022 Nov 26](ChangeLog/20221126) - version 0.19.0
|
||||||
* [2022 Aug 27](ChangeLog/20220827.md) - version 0.18.0
|
* [2022 Aug 27](ChangeLog/20220827) - version 0.18.0
|
||||||
* [2022 May 28](ChangeLog/20220528.md) - version 0.17.0
|
* [2022 May 28](ChangeLog/20220528) - version 0.17.0
|
||||||
* [2022 Feb 26](ChangeLog/20220226.md) - version 0.16.0
|
* [2022 Feb 26](ChangeLog/20220226) - version 0.16.0
|
||||||
* [2021 Nov 27](ChangeLog/20211127.md) - version 0.15.0
|
* [2021 Nov 27](ChangeLog/20211127) - version 0.15.0
|
||||||
* [2021 Aug 28](ChangeLog/20210828.md) - version 0.14.0
|
* [2021 Aug 28](ChangeLog/20210828) - version 0.14.0
|
||||||
* [2021 May 29](ChangeLog/20210529.md) - version 0.13.0
|
* [2021 May 29](ChangeLog/20210529) - version 0.13.0
|
||||||
* [2021 Feb 27](ChangeLog/20210227.md) - version 0.12.0
|
* [2021 Feb 27](ChangeLog/20210227) - version 0.12.0
|
||||||
* [2020 Nov 28](ChangeLog/20201128.md) - version 0.11.0
|
* [2020 Nov 28](ChangeLog/20201128) - version 0.11.0
|
||||||
* [2020 Aug 29](ChangeLog/20200829.md) - version 0.10.0
|
* [2020 Aug 29](ChangeLog/20200829) - version 0.10.0
|
||||||
* [2020 May 30](ChangeLog/20200530.md) - version 0.9.0
|
* [2020 May 30](ChangeLog/20200530) - version 0.9.0
|
||||||
* [2020 Feb 29](ChangeLog/20200229.md) - version 0.8.0
|
* [2020 Feb 29](ChangeLog/20200229) - version 0.8.0
|
||||||
* [2019 Aug 30](ChangeLog/20190830.md) - version 0.7.0
|
* [2019 Aug 30](ChangeLog/20190830) - version 0.7.0
|
||||||
|
|
12
docs/cli.md
12
docs/cli.md
|
@ -1,14 +1,14 @@
|
||||||
# QMK CLI :id=qmk-cli
|
# QMK CLI {#qmk-cli}
|
||||||
|
|
||||||
## Overview :id=overview
|
## Overview {#overview}
|
||||||
|
|
||||||
The QMK CLI (command line interface) makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more.
|
The QMK CLI (command line interface) makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more.
|
||||||
|
|
||||||
### Requirements :id=requirements
|
### Requirements {#requirements}
|
||||||
|
|
||||||
QMK requires Python 3.7 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI.
|
QMK requires Python 3.7 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI.
|
||||||
|
|
||||||
### Install Using Homebrew (macOS, some Linux) :id=install-using-homebrew
|
### Install Using Homebrew (macOS, some Linux) {#install-using-homebrew}
|
||||||
|
|
||||||
If you have installed [Homebrew](https://brew.sh) you can tap and install QMK:
|
If you have installed [Homebrew](https://brew.sh) you can tap and install QMK:
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware`
|
||||||
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
|
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install Using pip :id=install-using-easy_install-or-pip
|
### Install Using pip {#install-using-easy_install-or-pip}
|
||||||
|
|
||||||
If your system is not listed above you can install QMK manually. First ensure that you have Python 3.7 (or later) installed and have installed pip. Then install QMK with this command:
|
If your system is not listed above you can install QMK manually. First ensure that you have Python 3.7 (or later) installed and have installed pip. Then install QMK with this command:
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware`
|
||||||
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
|
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
|
||||||
```
|
```
|
||||||
|
|
||||||
### Packaging For Other Operating Systems :id=packaging-for-other-operating-systems
|
### Packaging For Other Operating Systems {#packaging-for-other-operating-systems}
|
||||||
|
|
||||||
We are looking for people to create and maintain a `qmk` package for more operating systems. If you would like to create a package for your OS please follow these guidelines:
|
We are looking for people to create and maintain a `qmk` package for more operating systems. If you would like to create a package for your OS please follow these guidelines:
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ qmk compile -j 0 -kb <keyboard_name>
|
||||||
|
|
||||||
## `qmk flash`
|
## `qmk flash`
|
||||||
|
|
||||||
This command is similar to `qmk compile`, but can also target a bootloader. The bootloader is optional, and is set to `:flash` by default. To specify a different bootloader, use `-bl <bootloader>`. Visit the [Flashing Firmware](flashing.md) guide for more details of the available bootloaders.
|
This command is similar to `qmk compile`, but can also target a bootloader. The bootloader is optional, and is set to `:flash` by default. To specify a different bootloader, use `-bl <bootloader>`. Visit the [Flashing Firmware](flashing) guide for more details of the available bootloaders.
|
||||||
|
|
||||||
This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory.
|
This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory.
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ qmk flash -b
|
||||||
|
|
||||||
## `qmk config`
|
## `qmk config`
|
||||||
|
|
||||||
This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration.md).
|
This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration).
|
||||||
|
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
|
||||||
|
@ -703,30 +703,39 @@ Now open your dev environment and live a squiggly-free life.
|
||||||
|
|
||||||
## `qmk docs`
|
## `qmk docs`
|
||||||
|
|
||||||
This command starts a local HTTP server which you can use for browsing or improving the docs. Default port is 8936.
|
This command starts a local HTTP server which you can use for browsing or improving the docs. Default port is 5173.
|
||||||
Use the `-b`/`--browser` flag to automatically open the local webserver in your default browser.
|
|
||||||
|
|
||||||
This command runs `docsify serve` if `docsify-cli` is installed (which provides live reload), otherwise Python's builtin HTTP server module will be used.
|
This command requires `node` and `yarn` to be installed as prerequisites, and provides live reload capability whilst editing.
|
||||||
|
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
|
||||||
```
|
```
|
||||||
qmk docs [-b] [-p PORT]
|
usage: qmk docs [-h]
|
||||||
|
|
||||||
|
options:
|
||||||
|
-h, --help show this help message and exit
|
||||||
```
|
```
|
||||||
|
|
||||||
## `qmk generate-docs`
|
## `qmk generate-docs`
|
||||||
|
|
||||||
This command allows you to generate QMK documentation locally. It can be uses for general browsing or improving the docs. External tools such as [serve](https://www.npmjs.com/package/serve) can be used to browse the generated files.
|
This command allows you to generate QMK documentation locally. It can be uses for general browsing or improving the docs.
|
||||||
|
Use the `-s`/`--serve` flag to also serve the static site once built. Default port is 4173.
|
||||||
|
|
||||||
|
This command requires `node` and `yarn` to be installed as prerequisites, and requires the operating system to support symlinks.
|
||||||
|
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
|
||||||
```
|
```
|
||||||
qmk generate-docs
|
usage: qmk generate-docs [-h] [-s]
|
||||||
|
|
||||||
|
options:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-s, --serve Serves the generated docs once built.
|
||||||
```
|
```
|
||||||
|
|
||||||
## `qmk generate-rgb-breathe-table`
|
## `qmk generate-rgb-breathe-table`
|
||||||
|
|
||||||
This command generates a lookup table (LUT) header file for the [RGB Lighting](feature_rgblight.md) feature's breathing animation. Place this file in your keyboard or keymap directory as `rgblight_breathe_table.h` to override the default LUT in `quantum/rgblight/`.
|
This command generates a lookup table (LUT) header file for the [RGB Lighting](feature_rgblight) feature's breathing animation. Place this file in your keyboard or keymap directory as `rgblight_breathe_table.h` to override the default LUT in `quantum/rgblight/`.
|
||||||
|
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
|
||||||
|
@ -793,15 +802,15 @@ Run single test:
|
||||||
|
|
||||||
## `qmk painter-convert-graphics`
|
## `qmk painter-convert-graphics`
|
||||||
|
|
||||||
This command converts images to a format usable by QMK, i.e. the QGF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command.
|
This command converts images to a format usable by QMK, i.e. the QGF File Format. See the [Quantum Painter](quantum_painter#quantum-painter-cli) documentation for more information on this command.
|
||||||
|
|
||||||
## `qmk painter-make-font-image`
|
## `qmk painter-make-font-image`
|
||||||
|
|
||||||
This command converts a TTF font to an intermediate format for editing, before converting to the QFF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command.
|
This command converts a TTF font to an intermediate format for editing, before converting to the QFF File Format. See the [Quantum Painter](quantum_painter#quantum-painter-cli) documentation for more information on this command.
|
||||||
|
|
||||||
## `qmk painter-convert-font-image`
|
## `qmk painter-convert-font-image`
|
||||||
|
|
||||||
This command converts an intermediate font image to the QFF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command.
|
This command converts an intermediate font image to the QFF File Format. See the [Quantum Painter](quantum_painter#quantum-painter-cli) documentation for more information on this command.
|
||||||
|
|
||||||
## `qmk test-c`
|
## `qmk test-c`
|
||||||
|
|
||||||
|
|
|
@ -202,7 +202,9 @@ We use nose2, flake8, and yapf to test, lint, and format code. You can use the `
|
||||||
|
|
||||||
We use [yapf](https://github.com/google/yapf) to automatically format code. Our configuration is in the `[yapf]` section of `setup.cfg`.
|
We use [yapf](https://github.com/google/yapf) to automatically format code. Our configuration is in the `[yapf]` section of `setup.cfg`.
|
||||||
|
|
||||||
?> Tip- Many editors can use yapf as a plugin to automatically format code as you type.
|
::: tip
|
||||||
|
Tip- Many editors can use yapf as a plugin to automatically format code as you type.
|
||||||
|
:::
|
||||||
|
|
||||||
## Testing Details
|
## Testing Details
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ Most of our style follows PEP8 with some local modifications to make things less
|
||||||
|
|
||||||
# YAPF
|
# YAPF
|
||||||
|
|
||||||
You can use [yapf](https://github.com/google/yapf) to style your code. We provide a config in [setup.cfg](setup.cfg).
|
You can use [yapf](https://github.com/google/yapf) to style your code. We provide a config in [setup.cfg](https://github.com/qmk/qmk_firmware/blob/master/setup.cfg).
|
||||||
|
|
||||||
# Imports
|
# Imports
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
|
||||||
|
|
||||||
* [RP2040](https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html)
|
* [RP2040](https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html)
|
||||||
|
|
||||||
For a detailed overview about the RP2040 support by QMK see the [dedicated RP2040 page](platformdev_rp2040.md).
|
For a detailed overview about the RP2040 support by QMK see the [dedicated RP2040 page](platformdev_rp2040).
|
||||||
|
|
||||||
## Atmel ATSAM
|
## Atmel ATSAM
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,13 @@ There are three main types of configuration files in QMK:
|
||||||
|
|
||||||
* `config.h`, which contains various preprocessor directives (`#define`, `#ifdef`)
|
* `config.h`, which contains various preprocessor directives (`#define`, `#ifdef`)
|
||||||
* `rules.mk`, which contains additional variables
|
* `rules.mk`, which contains additional variables
|
||||||
* `info.json`, which is utilized for [data-driven configuration](https://docs.qmk.fm/#/data_driven_config)
|
* `info.json`, which is utilized for [data-driven configuration](data_driven_config)
|
||||||
|
|
||||||
This page will only discuss the first two types, `config.h` and `rules.mk`.
|
This page will only discuss the first two types, `config.h` and `rules.mk`.
|
||||||
|
|
||||||
?> While not all settings have data-driven equivalents yet, keyboard makers are encouraged to utilize the `info.json` file to set the metadata for their boards when possible. See the [`info.json` Format](https://docs.qmk.fm/#/reference_info_json) page for more details.
|
::: tip
|
||||||
|
While not all settings have data-driven equivalents yet, keyboard makers are encouraged to utilize the `info.json` file to set the metadata for their boards when possible. See the [`info.json` Format](reference_info_json) page for more details.
|
||||||
|
:::
|
||||||
|
|
||||||
These files exist at various levels in QMK and all files of the same type are combined to build the final configuration. The levels, from lowest priority to highest priority, are:
|
These files exist at various levels in QMK and all files of the same type are combined to build the final configuration. The levels, from lowest priority to highest priority, are:
|
||||||
|
|
||||||
|
@ -56,10 +58,10 @@ This is a C header file that is one of the first things included, and will persi
|
||||||
* the number of columns in your keyboard's matrix
|
* the number of columns in your keyboard's matrix
|
||||||
* `#define MATRIX_ROW_PINS { D0, D5, B5, B6 }`
|
* `#define MATRIX_ROW_PINS { D0, D5, B5, B6 }`
|
||||||
* pins of the rows, from top to bottom
|
* pins of the rows, from top to bottom
|
||||||
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
|
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions#low-level-matrix-overrides) for more information.
|
||||||
* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }`
|
* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }`
|
||||||
* pins of the columns, from left to right
|
* pins of the columns, from left to right
|
||||||
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
|
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions#low-level-matrix-overrides) for more information.
|
||||||
* `#define MATRIX_IO_DELAY 30`
|
* `#define MATRIX_IO_DELAY 30`
|
||||||
* the delay in microseconds when between changing matrix pin state and reading values
|
* the delay in microseconds when between changing matrix pin state and reading values
|
||||||
* `#define MATRIX_HAS_GHOST`
|
* `#define MATRIX_HAS_GHOST`
|
||||||
|
@ -151,26 +153,26 @@ If you define these options you will enable the associated feature, which may in
|
||||||
* enables handling for per key `TAPPING_TERM` settings
|
* enables handling for per key `TAPPING_TERM` settings
|
||||||
* `#define RETRO_TAPPING`
|
* `#define RETRO_TAPPING`
|
||||||
* tap anyway, even after `TAPPING_TERM`, if there was no other key interruption between press and release
|
* tap anyway, even after `TAPPING_TERM`, if there was no other key interruption between press and release
|
||||||
* See [Retro Tapping](tap_hold.md#retro-tapping) for details
|
* See [Retro Tapping](tap_hold#retro-tapping) for details
|
||||||
* `#define RETRO_TAPPING_PER_KEY`
|
* `#define RETRO_TAPPING_PER_KEY`
|
||||||
* enables handling for per key `RETRO_TAPPING` settings
|
* enables handling for per key `RETRO_TAPPING` settings
|
||||||
* `#define TAPPING_TOGGLE 2`
|
* `#define TAPPING_TOGGLE 2`
|
||||||
* how many taps before triggering the toggle
|
* how many taps before triggering the toggle
|
||||||
* `#define PERMISSIVE_HOLD`
|
* `#define PERMISSIVE_HOLD`
|
||||||
* makes tap and hold keys trigger the hold if another key is pressed before releasing, even if it hasn't hit the `TAPPING_TERM`
|
* makes tap and hold keys trigger the hold if another key is pressed before releasing, even if it hasn't hit the `TAPPING_TERM`
|
||||||
* See [Permissive Hold](tap_hold.md#permissive-hold) for details
|
* See [Permissive Hold](tap_hold#permissive-hold) for details
|
||||||
* `#define PERMISSIVE_HOLD_PER_KEY`
|
* `#define PERMISSIVE_HOLD_PER_KEY`
|
||||||
* enabled handling for per key `PERMISSIVE_HOLD` settings
|
* enabled handling for per key `PERMISSIVE_HOLD` settings
|
||||||
* `#define QUICK_TAP_TERM 100`
|
* `#define QUICK_TAP_TERM 100`
|
||||||
* tap-then-hold timing to use a dual role key to repeat keycode
|
* tap-then-hold timing to use a dual role key to repeat keycode
|
||||||
* See [Quick Tap Term](tap_hold.md#quick-tap-term)
|
* See [Quick Tap Term](tap_hold#quick-tap-term)
|
||||||
* Changes the timing of Tap Toggle functionality (`TT` or the One Shot Tap Toggle)
|
* Changes the timing of Tap Toggle functionality (`TT` or the One Shot Tap Toggle)
|
||||||
* Defaults to `TAPPING_TERM` if not defined
|
* Defaults to `TAPPING_TERM` if not defined
|
||||||
* `#define QUICK_TAP_TERM_PER_KEY`
|
* `#define QUICK_TAP_TERM_PER_KEY`
|
||||||
* enables handling for per key `QUICK_TAP_TERM` settings
|
* enables handling for per key `QUICK_TAP_TERM` settings
|
||||||
* `#define HOLD_ON_OTHER_KEY_PRESS`
|
* `#define HOLD_ON_OTHER_KEY_PRESS`
|
||||||
* selects the hold action of a dual-role key as soon as the tap of the dual-role key is interrupted by the press of another key.
|
* selects the hold action of a dual-role key as soon as the tap of the dual-role key is interrupted by the press of another key.
|
||||||
* See "[hold on other key press](tap_hold.md#hold-on-other-key-press)" for details
|
* See "[hold on other key press](tap_hold#hold-on-other-key-press)" for details
|
||||||
* `#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY`
|
* `#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY`
|
||||||
* enables handling for per key `HOLD_ON_OTHER_KEY_PRESS` settings
|
* enables handling for per key `HOLD_ON_OTHER_KEY_PRESS` settings
|
||||||
* `#define LEADER_TIMEOUT 300`
|
* `#define LEADER_TIMEOUT 300`
|
||||||
|
@ -205,7 +207,7 @@ If you define these options you will enable the associated feature, which may in
|
||||||
* `#define TAP_HOLD_CAPS_DELAY 80`
|
* `#define TAP_HOLD_CAPS_DELAY 80`
|
||||||
* Sets the delay for Tap Hold keys (`LT`, `MT`) when using `KC_CAPS_LOCK` keycode, as this has some special handling on MacOS. The value is in milliseconds, and defaults to 80 ms if not defined. For macOS, you may want to set this to 200 or higher.
|
* Sets the delay for Tap Hold keys (`LT`, `MT`) when using `KC_CAPS_LOCK` keycode, as this has some special handling on MacOS. The value is in milliseconds, and defaults to 80 ms if not defined. For macOS, you may want to set this to 200 or higher.
|
||||||
* `#define KEY_OVERRIDE_REPEAT_DELAY 500`
|
* `#define KEY_OVERRIDE_REPEAT_DELAY 500`
|
||||||
* Sets the key repeat interval for [key overrides](feature_key_overrides.md).
|
* Sets the key repeat interval for [key overrides](feature_key_overrides).
|
||||||
* `#define LEGACY_MAGIC_HANDLING`
|
* `#define LEGACY_MAGIC_HANDLING`
|
||||||
* Enables magic configuration handling for advanced keycodes (such as Mod Tap and Layer Tap)
|
* Enables magic configuration handling for advanced keycodes (such as Mod Tap and Layer Tap)
|
||||||
|
|
||||||
|
@ -215,14 +217,14 @@ If you define these options you will enable the associated feature, which may in
|
||||||
* `#define WS2812_DI_PIN D7`
|
* `#define WS2812_DI_PIN D7`
|
||||||
* pin the DI on the WS2812 is hooked-up to
|
* pin the DI on the WS2812 is hooked-up to
|
||||||
* `#define RGBLIGHT_LAYERS`
|
* `#define RGBLIGHT_LAYERS`
|
||||||
* Lets you define [lighting layers](feature_rgblight.md?id=lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
|
* Lets you define [lighting layers](feature_rgblight#lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
|
||||||
* `#define RGBLIGHT_MAX_LAYERS`
|
* `#define RGBLIGHT_MAX_LAYERS`
|
||||||
* Defaults to 8. Can be expanded up to 32 if more [lighting layers](feature_rgblight.md?id=lighting-layers) are needed.
|
* Defaults to 8. Can be expanded up to 32 if more [lighting layers](feature_rgblight#lighting-layers) are needed.
|
||||||
* Note: Increasing the maximum will increase the firmware size and slow sync on split keyboards.
|
* Note: Increasing the maximum will increase the firmware size and slow sync on split keyboards.
|
||||||
* `#define RGBLIGHT_LAYER_BLINK`
|
* `#define RGBLIGHT_LAYER_BLINK`
|
||||||
* Adds ability to [blink](feature_rgblight.md?id=lighting-layer-blink) a lighting layer for a specified number of milliseconds (e.g. to acknowledge an action).
|
* Adds ability to [blink](feature_rgblight#lighting-layer-blink) a lighting layer for a specified number of milliseconds (e.g. to acknowledge an action).
|
||||||
* `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF`
|
* `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF`
|
||||||
* If defined, then [lighting layers](feature_rgblight?id=overriding-rgb-lighting-onoff-status) will be shown even if RGB Light is off.
|
* If defined, then [lighting layers](feature_rgblight#overriding-rgb-lighting-onoff-status) will be shown even if RGB Light is off.
|
||||||
* `#define RGBLIGHT_LED_COUNT 12`
|
* `#define RGBLIGHT_LED_COUNT 12`
|
||||||
* number of LEDs
|
* number of LEDs
|
||||||
* `#define RGBLIGHT_SPLIT`
|
* `#define RGBLIGHT_SPLIT`
|
||||||
|
@ -294,7 +296,7 @@ There are a few different ways to set handedness for split keyboards (listed in
|
||||||
* `#define MATRIX_ROW_PINS_RIGHT { <row pins> }`
|
* `#define MATRIX_ROW_PINS_RIGHT { <row pins> }`
|
||||||
* `#define MATRIX_COL_PINS_RIGHT { <col pins> }`
|
* `#define MATRIX_COL_PINS_RIGHT { <col pins> }`
|
||||||
* If you want to specify a different pinout for the right half than the left half, you can define `MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT`. Currently, the size of `MATRIX_ROW_PINS` must be the same as `MATRIX_ROW_PINS_RIGHT` and likewise for the definition of columns.
|
* If you want to specify a different pinout for the right half than the left half, you can define `MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT`. Currently, the size of `MATRIX_ROW_PINS` must be the same as `MATRIX_ROW_PINS_RIGHT` and likewise for the definition of columns.
|
||||||
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
|
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions#low-level-matrix-overrides) for more information.
|
||||||
|
|
||||||
* `#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }`
|
* `#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }`
|
||||||
* If you want to specify a different direct pinout for the right half than the left half, you can define `DIRECT_PINS_RIGHT`. Currently, the size of `DIRECT_PINS` must be the same as `DIRECT_PINS_RIGHT`.
|
* If you want to specify a different direct pinout for the right half than the left half, you can define `DIRECT_PINS_RIGHT`. Currently, the size of `DIRECT_PINS` must be the same as `DIRECT_PINS_RIGHT`.
|
||||||
|
@ -356,7 +358,7 @@ There are a few different ways to set handedness for split keyboards (listed in
|
||||||
|
|
||||||
* `#define SPLIT_TRANSACTION_IDS_KB .....`
|
* `#define SPLIT_TRANSACTION_IDS_KB .....`
|
||||||
* `#define SPLIT_TRANSACTION_IDS_USER .....`
|
* `#define SPLIT_TRANSACTION_IDS_USER .....`
|
||||||
* Allows for custom data sync with the slave when using the QMK-provided split transport. See [custom data sync between sides](feature_split_keyboard.md#custom-data-sync) for more information.
|
* Allows for custom data sync with the slave when using the QMK-provided split transport. See [custom data sync between sides](feature_split_keyboard#custom-data-sync) for more information.
|
||||||
|
|
||||||
# The `rules.mk` File
|
# The `rules.mk` File
|
||||||
|
|
||||||
|
@ -385,7 +387,7 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
|
||||||
... a.o c.o ... lib_b.a lib_d.a ...
|
... a.o c.o ... lib_b.a lib_d.a ...
|
||||||
```
|
```
|
||||||
* `LAYOUTS`
|
* `LAYOUTS`
|
||||||
* A list of [layouts](feature_layouts.md) this keyboard supports.
|
* A list of [layouts](feature_layouts) this keyboard supports.
|
||||||
* `LTO_ENABLE`
|
* `LTO_ENABLE`
|
||||||
* Enables Link Time Optimization (LTO) when compiling the keyboard. This makes the process take longer, but it can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable).
|
* Enables Link Time Optimization (LTO) when compiling the keyboard. This makes the process take longer, but it can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable).
|
||||||
|
|
||||||
|
@ -404,7 +406,7 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
|
||||||
* `bootloadhid`
|
* `bootloadhid`
|
||||||
* `usbasploader`
|
* `usbasploader`
|
||||||
|
|
||||||
## Feature Options :id=feature-options
|
## Feature Options {#feature-options}
|
||||||
|
|
||||||
Use these to enable or disable building certain features. The more you have enabled the bigger your firmware will be, and you run the risk of building a firmware too large for your MCU.
|
Use these to enable or disable building certain features. The more you have enabled the bigger your firmware will be, and you run the risk of building a firmware too large for your MCU.
|
||||||
|
|
||||||
|
@ -451,7 +453,7 @@ Use these to enable or disable building certain features. The more you have enab
|
||||||
* `NO_USB_STARTUP_CHECK`
|
* `NO_USB_STARTUP_CHECK`
|
||||||
* Disables usb suspend check after keyboard startup. Usually the keyboard waits for the host to wake it up before any tasks are performed. This is useful for split keyboards as one half will not get a wakeup call but must send commands to the master.
|
* Disables usb suspend check after keyboard startup. Usually the keyboard waits for the host to wake it up before any tasks are performed. This is useful for split keyboards as one half will not get a wakeup call but must send commands to the master.
|
||||||
* `DEFERRED_EXEC_ENABLE`
|
* `DEFERRED_EXEC_ENABLE`
|
||||||
* Enables deferred executor support -- timed delays before callbacks are invoked. See [deferred execution](custom_quantum_functions.md#deferred-execution) for more information.
|
* Enables deferred executor support -- timed delays before callbacks are invoked. See [deferred execution](custom_quantum_functions#deferred-execution) for more information.
|
||||||
* `DYNAMIC_TAPPING_TERM_ENABLE`
|
* `DYNAMIC_TAPPING_TERM_ENABLE`
|
||||||
* Allows to configure the global tapping term on the fly.
|
* Allows to configure the global tapping term on the fly.
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
# Adding Default Keymaps to QMK Configurator :id=adding-default-keymaps
|
# Adding Default Keymaps to QMK Configurator {#adding-default-keymaps}
|
||||||
|
|
||||||
This page covers how to add a default keymap for a keyboard to QMK Configurator.
|
This page covers how to add a default keymap for a keyboard to QMK Configurator.
|
||||||
|
|
||||||
|
|
||||||
## Technical Information :id=technical-information
|
## Technical Information {#technical-information}
|
||||||
|
|
||||||
QMK Configurator uses JSON as its native file format for keymaps. As much as possible, these should be kept such that they behave the same as running `make <keyboard>:default` from `qmk_firmware`.
|
QMK Configurator uses JSON as its native file format for keymaps. As much as possible, these should be kept such that they behave the same as running `make <keyboard>:default` from `qmk_firmware`.
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ f14629ed1cd7c7ec9089604d64f29a99981558e8 Remove/migrate action_get_macro()s from
|
||||||
In this example, `f14629ed1cd7c7ec9089604d64f29a99981558e8` is the value that should be used for `commit`.
|
In this example, `f14629ed1cd7c7ec9089604d64f29a99981558e8` is the value that should be used for `commit`.
|
||||||
|
|
||||||
|
|
||||||
## Example :id=example
|
## Example {#example}
|
||||||
|
|
||||||
If one wished to add a default keymap for the H87a by Hineybush, one would run the `git log` command above against the H87a's default keymap in `qmk_firmware`:
|
If one wished to add a default keymap for the H87a by Hineybush, one would run the `git log` command above against the H87a's default keymap in `qmk_firmware`:
|
||||||
|
|
||||||
|
@ -96,9 +96,9 @@ The default keymap uses the `LAYOUT_all` macro, so that will be the value of the
|
||||||
The white space in the `layers` arrays have no effect on the functionality of the keymap, but are used to make these files easier for humans to read.
|
The white space in the `layers` arrays have no effect on the functionality of the keymap, but are used to make these files easier for humans to read.
|
||||||
|
|
||||||
|
|
||||||
## Caveats :id=caveats
|
## Caveats {#caveats}
|
||||||
|
|
||||||
### Layers can only be referenced by number :id=layer-references
|
### Layers can only be referenced by number {#layer-references}
|
||||||
|
|
||||||
A common QMK convention is to name layers using a series of `#define`s, or an `enum` statement:
|
A common QMK convention is to name layers using a series of `#define`s, or an `enum` statement:
|
||||||
|
|
||||||
|
@ -112,11 +112,11 @@ enum layer_names {
|
||||||
|
|
||||||
This works in C, but for Configurator, you *must* use the layer's numeric index – `MO(_FN)` would need to be `MO(2)` in the above example.
|
This works in C, but for Configurator, you *must* use the layer's numeric index – `MO(_FN)` would need to be `MO(2)` in the above example.
|
||||||
|
|
||||||
### No support for custom code of any kind :id=custom-code
|
### No support for custom code of any kind {#custom-code}
|
||||||
|
|
||||||
Features that require adding functions to the keymap.c file, such as Tap Dance or Unicode, can not be compiled in Configurator **at all**. Even setting `TAP_DANCE_ENABLE = yes` in the `qmk_firmware` repository at the keyboard level will prevent Configurator from compiling **any** firmware for that keyboard. This is limited both by the API and the current spec of our JSON keymap format.
|
Features that require adding functions to the keymap.c file, such as Tap Dance or Unicode, can not be compiled in Configurator **at all**. Even setting `TAP_DANCE_ENABLE = yes` in the `qmk_firmware` repository at the keyboard level will prevent Configurator from compiling **any** firmware for that keyboard. This is limited both by the API and the current spec of our JSON keymap format.
|
||||||
|
|
||||||
### Limited Support for Custom keycodes :id=custom-keycodes
|
### Limited Support for Custom keycodes {#custom-keycodes}
|
||||||
|
|
||||||
There is a way to support custom keycodes: if the logic for a custom keycode is implemented at the keyboard level instead of the keymap level in qmk_firmware, that keycode *can* be used in Configurator and it *will* compile and work. Instead of using the following in your `keymap.c`:
|
There is a way to support custom keycodes: if the logic for a custom keycode is implemented at the keyboard level instead of the keymap level in qmk_firmware, that keycode *can* be used in Configurator and it *will* compile and work. Instead of using the following in your `keymap.c`:
|
||||||
|
|
||||||
|
@ -186,6 +186,6 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
|
||||||
Note the call to `process_record_user()` at the end.
|
Note the call to `process_record_user()` at the end.
|
||||||
|
|
||||||
## Additional Reading :id=additional-reading
|
## Additional Reading {#additional-reading}
|
||||||
|
|
||||||
For QMK Configurator to support your keyboard, your keyboard must be present in the `master` branch of the `qmk_firmware` repository. For instructions on this, please see [Supporting Your Keyboard in QMK Configurator](reference_configurator_support.md).
|
For QMK Configurator to support your keyboard, your keyboard must be present in the `master` branch of the `qmk_firmware` repository. For instructions on this, please see [Supporting Your Keyboard in QMK Configurator](reference_configurator_support).
|
||||||
|
|
|
@ -6,11 +6,15 @@ This page describes the steps for building your firmware in QMK Configurator.
|
||||||
|
|
||||||
Click the drop down box and select the keyboard you want to create a keymap for.
|
Click the drop down box and select the keyboard you want to create a keymap for.
|
||||||
|
|
||||||
?> If your keyboard has several versions, make sure you select the correct one.
|
::: tip
|
||||||
|
If your keyboard has several versions, make sure you select the correct one.
|
||||||
|
:::
|
||||||
|
|
||||||
I'll say that again because it's important:
|
I'll say that again because it's important:
|
||||||
|
|
||||||
!> **MAKE SURE YOU SELECT THE RIGHT VERSION!**
|
::: warning
|
||||||
|
**MAKE SURE YOU SELECT THE RIGHT VERSION!**
|
||||||
|
:::
|
||||||
|
|
||||||
If your keyboard has been advertised to be powered by QMK but is not in the list, chances are a developer hasn't gotten to it yet or we haven't had a chance to merge it in yet. File an issue at [qmk_firmware](https://github.com/qmk/qmk_firmware/issues) requesting to support that particular keyboard, if there is no active [Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) for it. There are also QMK powered keyboards that are in their manufacturer's own GitHub accounts. Double check for that as well. <!-- FIXME(skullydazed): This feels too wordy and I'm not sure we want to encourage these kinds of issues. Also, should we prompt them to bug the manufacutrer? -->
|
If your keyboard has been advertised to be powered by QMK but is not in the list, chances are a developer hasn't gotten to it yet or we haven't had a chance to merge it in yet. File an issue at [qmk_firmware](https://github.com/qmk/qmk_firmware/issues) requesting to support that particular keyboard, if there is no active [Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) for it. There are also QMK powered keyboards that are in their manufacturer's own GitHub accounts. Double check for that as well. <!-- FIXME(skullydazed): This feels too wordy and I'm not sure we want to encourage these kinds of issues. Also, should we prompt them to bug the manufacutrer? -->
|
||||||
|
|
||||||
|
@ -18,13 +22,17 @@ If your keyboard has been advertised to be powered by QMK but is not in the list
|
||||||
|
|
||||||
Choose the layout that best represents the keymap you want to create. Some keyboards do not have enough layouts or correct layouts defined yet. They will be supported in the future.
|
Choose the layout that best represents the keymap you want to create. Some keyboards do not have enough layouts or correct layouts defined yet. They will be supported in the future.
|
||||||
|
|
||||||
!> Sometimes there isn't a layout that supports your exact build. In that case select `LAYOUT_all`.
|
::: warning
|
||||||
|
Sometimes there isn't a layout that supports your exact build. In that case select `LAYOUT_all`.
|
||||||
|
:::
|
||||||
|
|
||||||
## Step 3: Name Your Keymap
|
## Step 3: Name Your Keymap
|
||||||
|
|
||||||
Call this keymap what you want.
|
Call this keymap what you want.
|
||||||
|
|
||||||
?> If you are running into issues when compiling, it may be worth changing this name, as it may already exist in the QMK Firmware repo.
|
::: tip
|
||||||
|
If you are running into issues when compiling, it may be worth changing this name, as it may already exist in the QMK Firmware repo.
|
||||||
|
:::
|
||||||
|
|
||||||
## Step 4: Define Your Keymap
|
## Step 4: Define Your Keymap
|
||||||
|
|
||||||
|
@ -34,18 +42,24 @@ Keycode Entry is accomplished in one of 3 ways:
|
||||||
2. Clicking on an empty spot on the layout, then clicking the keycode you desire
|
2. Clicking on an empty spot on the layout, then clicking the keycode you desire
|
||||||
3. Clicking on an empty spot on the layout, then pressing the physical key on your keyboard
|
3. Clicking on an empty spot on the layout, then pressing the physical key on your keyboard
|
||||||
|
|
||||||
?> Hover your mouse over a key and a short blurb will tell you what that keycode does. For a more verbose description please see:
|
::: tip
|
||||||
|
Hover your mouse over a key and a short blurb will tell you what that keycode does. For a more verbose description please see:
|
||||||
|
:::
|
||||||
|
|
||||||
* [Basic Keycode Reference](keycodes_basic.md)
|
* [Basic Keycode Reference](keycodes_basic)
|
||||||
* [Advanced Keycode Reference](feature_advanced_keycodes.md)
|
* [Advanced Keycode Reference](feature_advanced_keycodes)
|
||||||
|
|
||||||
!> If your selected layout doesn't match your physical build leave the unused keys blank. If you're not sure which key is in use, for example you have a one backspace key but `LAYOUT_all` has 2 keys, put the same keycode in both locations.
|
::: warning
|
||||||
|
If your selected layout doesn't match your physical build leave the unused keys blank. If you're not sure which key is in use, for example you have a one backspace key but `LAYOUT_all` has 2 keys, put the same keycode in both locations.
|
||||||
|
:::
|
||||||
|
|
||||||
## Step 5: Save Your Keymap for Future Changes
|
## Step 5: Save Your Keymap for Future Changes
|
||||||
|
|
||||||
When you're satisfied with your keymap or just want to work on it later, press the `Download this QMK Keymap JSON File` button. It will save your keymap to your computer. You can then load this .json file in the future by pressing the `Upload a QMK Keymap JSON File` button.
|
When you're satisfied with your keymap or just want to work on it later, press the `Download this QMK Keymap JSON File` button. It will save your keymap to your computer. You can then load this .json file in the future by pressing the `Upload a QMK Keymap JSON File` button.
|
||||||
|
|
||||||
!> **CAUTION:** This is not the same type of .json file used for kbfirmware.com or any other tool. If you try to use this for those tools, or the .json from those tools with QMK Configurator, you will encounter problems.
|
::: warning
|
||||||
|
**CAUTION:** This is not the same type of .json file used for kbfirmware.com or any other tool. If you try to use this for those tools, or the .json from those tools with QMK Configurator, you will encounter problems.
|
||||||
|
:::
|
||||||
|
|
||||||
## Step 6: Compile Your Firmware File
|
## Step 6: Compile Your Firmware File
|
||||||
|
|
||||||
|
@ -55,4 +69,4 @@ When the compilation is done, you will be able to press the green `Download Firm
|
||||||
|
|
||||||
## Next steps: Flashing Your Keyboard
|
## Next steps: Flashing Your Keyboard
|
||||||
|
|
||||||
Please refer to [Flashing Firmware](newbs_flashing.md).
|
Please refer to [Flashing Firmware](newbs_flashing).
|
||||||
|
|
|
@ -14,8 +14,8 @@ If you're referring to having three spots for space bar, the best course of acti
|
||||||
|
|
||||||
Please see:
|
Please see:
|
||||||
|
|
||||||
* [Basic Keycode Reference](keycodes_basic.md)
|
* [Basic Keycode Reference](keycodes_basic)
|
||||||
* [Advanced Keycode Reference](feature_advanced_keycodes.md)
|
* [Advanced Keycode Reference](feature_advanced_keycodes)
|
||||||
|
|
||||||
## It won't compile
|
## It won't compile
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,8 @@ Never made an open source contribution before? Wondering how contributions work
|
||||||
|
|
||||||
Most of our style is pretty easy to pick up on. If you are familiar with either C or Python you should not have too much trouble with our local styles.
|
Most of our style is pretty easy to pick up on. If you are familiar with either C or Python you should not have too much trouble with our local styles.
|
||||||
|
|
||||||
* [Coding Conventions - C](coding_conventions_c.md)
|
* [Coding Conventions - C](coding_conventions_c)
|
||||||
* [Coding Conventions - Python](coding_conventions_python.md)
|
* [Coding Conventions - Python](coding_conventions_python)
|
||||||
|
|
||||||
# General Guidelines
|
# General Guidelines
|
||||||
|
|
||||||
|
@ -101,17 +101,13 @@ enum my_keycodes {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### Previewing the Documentation :id=previewing-the-documentation
|
### Previewing the Documentation {#previewing-the-documentation}
|
||||||
|
|
||||||
Before opening a pull request, you can preview your changes if you have set up the development environment by running this command from the `qmk_firmware/` folder:
|
Before opening a pull request, you can preview your changes if you have set up the development environment by running this command from the `qmk_firmware/` folder:
|
||||||
|
|
||||||
qmk docs
|
qmk docs
|
||||||
|
|
||||||
or if you only have Python 3 installed:
|
and navigating to `http://localhost:5173/`.
|
||||||
|
|
||||||
python3 -m http.server 8936 --directory docs
|
|
||||||
|
|
||||||
and navigating to `http://localhost:8936/`.
|
|
||||||
|
|
||||||
## Keyboards
|
## Keyboards
|
||||||
|
|
||||||
|
@ -119,7 +115,7 @@ Keyboards are the raison d'être for QMK. Some keyboards are community maintaine
|
||||||
|
|
||||||
We also ask that you follow these guidelines:
|
We also ask that you follow these guidelines:
|
||||||
|
|
||||||
* Write a `readme.md` using [the template](documentation_templates.md).
|
* Write a `readme.md` using [the template](documentation_templates).
|
||||||
* Include a `default` keymap that provides a clean slate for users to start with when creating their own keymaps.
|
* Include a `default` keymap that provides a clean slate for users to start with when creating their own keymaps.
|
||||||
* Do not lump core features in with new keyboards. Submit the feature first and then submit a separate PR for the keyboard.
|
* Do not lump core features in with new keyboards. Submit the feature first and then submit a separate PR for the keyboard.
|
||||||
* Name `.c`/`.h` file after the immediate parent folder, eg `/keyboards/<kb1>/<kb2>/<kb2>.[ch]`
|
* Name `.c`/`.h` file after the immediate parent folder, eg `/keyboards/<kb1>/<kb2>/<kb2>.[ch]`
|
||||||
|
@ -128,7 +124,7 @@ We also ask that you follow these guidelines:
|
||||||
|
|
||||||
## Quantum/TMK Core
|
## Quantum/TMK Core
|
||||||
|
|
||||||
Before you put a lot of work into building your new feature you should make sure you are implementing it in the best way. You can get a basic understanding of QMK by reading [Understanding QMK](understanding_qmk.md), which will take you on a tour of the QMK program flow. From here you should talk to us to get a sense of the best way to implement your idea. There are two main ways to do this:
|
Before you put a lot of work into building your new feature you should make sure you are implementing it in the best way. You can get a basic understanding of QMK by reading [Understanding QMK](understanding_qmk), which will take you on a tour of the QMK program flow. From here you should talk to us to get a sense of the best way to implement your idea. There are two main ways to do this:
|
||||||
|
|
||||||
* [Chat on Discord](https://discord.gg/Uq7gcHh)
|
* [Chat on Discord](https://discord.gg/Uq7gcHh)
|
||||||
* [Open an Issue](https://github.com/qmk/qmk_firmware/issues/new)
|
* [Open an Issue](https://github.com/qmk/qmk_firmware/issues/new)
|
||||||
|
@ -146,7 +142,7 @@ We also ask that you follow these guidelines:
|
||||||
|
|
||||||
* Keep the number of commits reasonable or we will squash your PR
|
* Keep the number of commits reasonable or we will squash your PR
|
||||||
* Do not lump keyboards or keymaps in with core changes. Submit your core changes first.
|
* Do not lump keyboards or keymaps in with core changes. Submit your core changes first.
|
||||||
* Write [Unit Tests](unit_testing.md) for your feature
|
* Write [Unit Tests](unit_testing) for your feature
|
||||||
* Follow the style of the file you are editing. If the style is unclear or there are mixed styles you should conform to the [coding conventions](#coding-conventions) above.
|
* Follow the style of the file you are editing. If the style is unclear or there are mixed styles you should conform to the [coding conventions](#coding-conventions) above.
|
||||||
|
|
||||||
## Refactoring
|
## Refactoring
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
For a lot of people a custom keyboard is about more than sending button presses to your computer. You want to be able to do things that are more complex than simple button presses and macros. QMK has hooks that allow you to inject code, override functionality, and otherwise customize how your keyboard behaves in different situations.
|
For a lot of people a custom keyboard is about more than sending button presses to your computer. You want to be able to do things that are more complex than simple button presses and macros. QMK has hooks that allow you to inject code, override functionality, and otherwise customize how your keyboard behaves in different situations.
|
||||||
|
|
||||||
This page does not assume any special knowledge about QMK, but reading [Understanding QMK](understanding_qmk.md) will help you understand what is going on at a more fundamental level.
|
This page does not assume any special knowledge about QMK, but reading [Understanding QMK](understanding_qmk) will help you understand what is going on at a more fundamental level.
|
||||||
|
|
||||||
## A Word on Core vs Keyboards vs Keymap :id=a-word-on-core-vs-keyboards-vs-keymap
|
## A Word on Core vs Keyboards vs Keymap {#a-word-on-core-vs-keyboards-vs-keymap}
|
||||||
|
|
||||||
We have structured QMK as a hierarchy:
|
We have structured QMK as a hierarchy:
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ enum my_keycodes {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
## Programming the Behavior of Any Keycode :id=programming-the-behavior-of-any-keycode
|
## Programming the Behavior of Any Keycode {#programming-the-behavior-of-any-keycode}
|
||||||
|
|
||||||
When you want to override the behavior of an existing key, or define the behavior for a new key, you should use the `process_record_kb()` and `process_record_user()` functions. These are called by QMK during key processing before the actual key event is handled. If these functions return `true` QMK will process the keycodes as usual. That can be handy for extending the functionality of a key rather than replacing it. If these functions return `false` QMK will skip the normal key handling, and it will be up to you to send any key up or down events that are required.
|
When you want to override the behavior of an existing key, or define the behavior for a new key, you should use the `process_record_kb()` and `process_record_user()` functions. These are called by QMK during key processing before the actual key event is handled. If these functions return `true` QMK will process the keycodes as usual. That can be handy for extending the functionality of a key rather than replacing it. If these functions return `false` QMK will skip the normal key handling, and it will be up to you to send any key up or down events that are required.
|
||||||
|
|
||||||
|
@ -98,7 +98,9 @@ These are the three main initialization functions, listed in the order that they
|
||||||
* `matrix_init_*` - Happens midway through the firmware's startup process. Hardware is initialized, but features may not be yet.
|
* `matrix_init_*` - Happens midway through the firmware's startup process. Hardware is initialized, but features may not be yet.
|
||||||
* `keyboard_post_init_*` - Happens at the end of the firmware's startup process. This is where you'd want to put "customization" code, for the most part.
|
* `keyboard_post_init_*` - Happens at the end of the firmware's startup process. This is where you'd want to put "customization" code, for the most part.
|
||||||
|
|
||||||
!> For most people, the `keyboard_post_init_user` function is what you want to call. For instance, this is where you want to set up things for RGB Underglow.
|
::: warning
|
||||||
|
For most people, the `keyboard_post_init_user` function is what you want to call. For instance, this is where you want to set up things for RGB Underglow.
|
||||||
|
:::
|
||||||
|
|
||||||
## Keyboard Pre Initialization code
|
## Keyboard Pre Initialization code
|
||||||
|
|
||||||
|
@ -144,7 +146,7 @@ This is useful for setting up stuff that you may need elsewhere, but isn't hardw
|
||||||
* Keyboard/Revision: `void matrix_init_kb(void)`
|
* Keyboard/Revision: `void matrix_init_kb(void)`
|
||||||
* Keymap: `void matrix_init_user(void)`
|
* Keymap: `void matrix_init_user(void)`
|
||||||
|
|
||||||
### Low-level Matrix Overrides Function Documentation :id=low-level-matrix-overrides
|
### Low-level Matrix Overrides Function Documentation {#low-level-matrix-overrides}
|
||||||
|
|
||||||
* GPIO pin initialisation: `void matrix_init_pins(void)`
|
* GPIO pin initialisation: `void matrix_init_pins(void)`
|
||||||
* This needs to perform the low-level initialisation of all row and column pins. By default this will initialise the input/output state of each of the GPIO pins listed in `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no initialisation of pin state will occur within QMK itself, instead deferring to the keyboard's override.
|
* This needs to perform the low-level initialisation of all row and column pins. By default this will initialise the input/output state of each of the GPIO pins listed in `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no initialisation of pin state will occur within QMK itself, instead deferring to the keyboard's override.
|
||||||
|
@ -204,7 +206,7 @@ Similar to `matrix_scan_*`, these are called as often as the MCU can handle. To
|
||||||
|
|
||||||
### Example `void housekeeping_task_user(void)` implementation
|
### Example `void housekeeping_task_user(void)` implementation
|
||||||
|
|
||||||
This example will show you how to use `void housekeeping_task_user(void)` to turn off [RGB Light](feature_rgblight.md). For RGB Matrix, the [builtin](https://docs.qmk.fm/#/feature_rgb_matrix?id=additional-configh-options) `RGB_MATRIX_TIMEOUT` should be used.
|
This example will show you how to use `void housekeeping_task_user(void)` to turn off [RGB Light](feature_rgblight). For RGB Matrix, the [builtin](feature_rgb_matrix#additional-configh-options) `RGB_MATRIX_TIMEOUT` should be used.
|
||||||
|
|
||||||
First, add the following lines to your keymap's `config.h`:
|
First, add the following lines to your keymap's `config.h`:
|
||||||
|
|
||||||
|
@ -284,7 +286,7 @@ void suspend_wakeup_init_user(void) {
|
||||||
* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
||||||
|
|
||||||
|
|
||||||
# Keyboard Shutdown/Reboot Code :id=keyboard-shutdown-reboot-code
|
# Keyboard Shutdown/Reboot Code {#keyboard-shutdown-reboot-code}
|
||||||
|
|
||||||
This function gets called whenever the firmware is reset, whether it's a soft reset or reset to the bootloader. This is the spot to use for any sort of cleanup, as this happens right before the actual reset. And it can be useful for turning off different systems (such as RGB, onboard screens, etc).
|
This function gets called whenever the firmware is reset, whether it's a soft reset or reset to the bootloader. This is the spot to use for any sort of cleanup, as this happens right before the actual reset. And it can be useful for turning off different systems (such as RGB, onboard screens, etc).
|
||||||
|
|
||||||
|
@ -296,7 +298,9 @@ If `jump_to_bootloader` is set to `true`, this indicates that the board will be
|
||||||
|
|
||||||
As there is a keyboard and user level function, returning `false` for the user function will disable the keyboard level function, allowing for customization.
|
As there is a keyboard and user level function, returning `false` for the user function will disable the keyboard level function, allowing for customization.
|
||||||
|
|
||||||
?> Bootmagic does not trigger `shutdown_*()` as it happens before most of the initialization process.
|
::: tip
|
||||||
|
Bootmagic does not trigger `shutdown_*()` as it happens before most of the initialization process.
|
||||||
|
:::
|
||||||
|
|
||||||
### Example `shutdown_kb()` Implementation
|
### Example `shutdown_kb()` Implementation
|
||||||
|
|
||||||
|
@ -342,7 +346,7 @@ bool shutdown_user(bool jump_to_bootloader) {
|
||||||
* Keyboard/Revision: `bool shutdown_kb(bool jump_to_bootloader)`
|
* Keyboard/Revision: `bool shutdown_kb(bool jump_to_bootloader)`
|
||||||
* Keymap: `bool shutdown_user(bool jump_to_bootloader)`
|
* Keymap: `bool shutdown_user(bool jump_to_bootloader)`
|
||||||
|
|
||||||
# Deferred Execution :id=deferred-execution
|
# Deferred Execution {#deferred-execution}
|
||||||
|
|
||||||
QMK has the ability to execute a callback after a specified period of time, rather than having to manually manage timers. To enable this functionality, set `DEFERRED_EXEC_ENABLE = yes` in rules.mk.
|
QMK has the ability to execute a callback after a specified period of time, rather than having to manually manage timers. To enable this functionality, set `DEFERRED_EXEC_ENABLE = yes` in rules.mk.
|
||||||
|
|
||||||
|
@ -364,7 +368,9 @@ The second argument `cb_arg` is the same argument passed into `defer_exec()` bel
|
||||||
|
|
||||||
The return value is the number of milliseconds to use if the function should be repeated -- if the callback returns `0` then it's automatically unregistered. In the example above, a hypothetical `my_deferred_functionality()` is invoked to determine if the callback needs to be repeated -- if it does, it reschedules for a `500` millisecond delay, otherwise it informs the deferred execution background task that it's done, by returning `0`.
|
The return value is the number of milliseconds to use if the function should be repeated -- if the callback returns `0` then it's automatically unregistered. In the example above, a hypothetical `my_deferred_functionality()` is invoked to determine if the callback needs to be repeated -- if it does, it reschedules for a `500` millisecond delay, otherwise it informs the deferred execution background task that it's done, by returning `0`.
|
||||||
|
|
||||||
?> Note that the returned delay will be applied to the intended trigger time, not the time of callback invocation. This allows for generally consistent timing even in the face of occasional late execution.
|
::: tip
|
||||||
|
Note that the returned delay will be applied to the intended trigger time, not the time of callback invocation. This allows for generally consistent timing even in the face of occasional late execution.
|
||||||
|
:::
|
||||||
|
|
||||||
## Deferred executor registration
|
## Deferred executor registration
|
||||||
|
|
||||||
|
@ -408,14 +414,14 @@ If registrations fail, then you can increase this value in your keyboard or keym
|
||||||
#define MAX_DEFERRED_EXECUTORS 16
|
#define MAX_DEFERRED_EXECUTORS 16
|
||||||
```
|
```
|
||||||
|
|
||||||
# Advanced topics :id=advanced-topics
|
# Advanced topics {#advanced-topics}
|
||||||
|
|
||||||
This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for.
|
This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for.
|
||||||
|
|
||||||
## Layer Change Code :id=layer-change-code
|
## Layer Change Code {#layer-change-code}
|
||||||
|
|
||||||
[Layer change code](feature_layers.md#layer-change-code)
|
[Layer change code](feature_layers#layer-change-code)
|
||||||
|
|
||||||
## Persistent Configuration (EEPROM) :id=persistent-configuration-eeprom
|
## Persistent Configuration (EEPROM) {#persistent-configuration-eeprom}
|
||||||
|
|
||||||
[Persistent Configuration (EEPROM)](feature_eeprom.md)
|
[Persistent Configuration (EEPROM)](feature_eeprom)
|
||||||
|
|
|
@ -4,7 +4,7 @@ This page describes how QMK's data driven JSON configuration system works. It is
|
||||||
|
|
||||||
## History
|
## History
|
||||||
|
|
||||||
Historically QMK has been configured through a combination of two mechanisms- `rules.mk` and `config.h`. While this worked well when QMK was only a handful of keyboards we've grown to encompass nearly 1500 supported keyboards. That extrapolates out to 6000 configuration files under `keyboards/` alone! The freeform nature of these files and the unique patterns people have used to avoid duplication have made ongoing maintenance a challenge, and a large number of our keyboards follow patterns that are outdated and sometimes harder to understand.
|
Historically QMK has been configured through a combination of two mechanisms- `rules.mk` and `config.h`. While this worked well when QMK was only a handful of keyboards we've grown to encompass nearly 4000 supported keyboards. That extrapolates out to 6000 configuration files under `keyboards/` alone! The freeform nature of these files and the unique patterns people have used to avoid duplication have made ongoing maintenance a challenge, and a large number of our keyboards follow patterns that are outdated and sometimes harder to understand.
|
||||||
|
|
||||||
We have also been working on bringing the power of QMK to people who aren't comformable with a CLI, and other projects such as VIA are working to make using QMK as easy as installing a program. These tools need information about how a keyboard is laid out or what pins and features are available so that users can take full advantage of QMK. We introduced `info.json` as a first step towards this. The QMK API is an effort to combine these 3 sources of information- `config.h`, `rules.mk`, and `info.json`- into a single source of truth that end-user tools can use.
|
We have also been working on bringing the power of QMK to people who aren't comformable with a CLI, and other projects such as VIA are working to make using QMK as easy as installing a program. These tools need information about how a keyboard is laid out or what pins and features are available so that users can take full advantage of QMK. We introduced `info.json` as a first step towards this. The QMK API is an effort to combine these 3 sources of information- `config.h`, `rules.mk`, and `info.json`- into a single source of truth that end-user tools can use.
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ Whenever QMK generates a complete `info.json` it extracts information from `conf
|
||||||
|
|
||||||
If you are not sure how to edit this file or are not comfortable with Python [open an issue](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=) or [join #cli on Discord](https://discord.gg/heQPAgy) and someone can help you with this part.
|
If you are not sure how to edit this file or are not comfortable with Python [open an issue](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=) or [join #cli on Discord](https://discord.gg/heQPAgy) and someone can help you with this part.
|
||||||
|
|
||||||
### Add code to generate it :id=add-code-to-generate-it
|
### Add code to generate it {#add-code-to-generate-it}
|
||||||
|
|
||||||
The final piece of the puzzle is providing your new option to the build system. This is done by generating two files:
|
The final piece of the puzzle is providing your new option to the build system. This is done by generating two files:
|
||||||
|
|
||||||
|
|
|
@ -25,22 +25,30 @@ You can have styled hint blocks drawn around text to draw attention to it.
|
||||||
### Important
|
### Important
|
||||||
|
|
||||||
```
|
```
|
||||||
!> This is important
|
::: warning
|
||||||
|
This is important
|
||||||
|
:::
|
||||||
```
|
```
|
||||||
|
|
||||||
Renders as:
|
Renders as:
|
||||||
|
|
||||||
!> This is important
|
::: warning
|
||||||
|
This is important
|
||||||
|
:::
|
||||||
|
|
||||||
### General Tips
|
### General Tips
|
||||||
|
|
||||||
```
|
```
|
||||||
?> This is a helpful tip.
|
::: tip
|
||||||
|
This is a helpful tip.
|
||||||
|
:::
|
||||||
```
|
```
|
||||||
|
|
||||||
Renders as:
|
Renders as:
|
||||||
|
|
||||||
?> This is a helpful tip.
|
::: tip
|
||||||
|
This is a helpful tip.
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
# Documenting Features
|
# Documenting Features
|
||||||
|
@ -61,4 +69,4 @@ This page describes my cool feature. You can use my cool feature to make coffee
|
||||||
|KC_SUGAR||Order Sugar|
|
|KC_SUGAR||Order Sugar|
|
||||||
```
|
```
|
||||||
|
|
||||||
Place your documentation into `docs/feature_<my_cool_feature>.md`, and add that file to the appropriate place in `docs/_summary.md`. If you have added any keycodes be sure to add them to `docs/keycodes.md` with a link back to your feature page.
|
Place your documentation into `docs/feature_<my_cool_feature>.md`, and add that file to the appropriate place in `docs/_sidebar.json`. If you have added any keycodes be sure to add them to `docs/keycodes.md` with a link back to your feature page.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
This page documents the templates you should use when submitting new Keymaps and Keyboards to QMK.
|
This page documents the templates you should use when submitting new Keymaps and Keyboards to QMK.
|
||||||
|
|
||||||
## Keymap `readme.md` Template :id=keyboard-readmemd-template
|
## Keymap `readme.md` Template {#keyboard-readmemd-template}
|
||||||
|
|
||||||
Most keymaps have an image depicting the layout. You can use [Keyboard Layout Editor](http://keyboard-layout-editor.com) to create an image. Upload it to [Imgur](https://imgur.com) or another hosting service, please do not include images in your Pull Request.
|
Most keymaps have an image depicting the layout. You can use [Keyboard Layout Editor](http://keyboard-layout-editor.com) to create an image. Upload it to [Imgur](https://imgur.com) or another hosting service, please do not include images in your Pull Request.
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ Flashing example for this keyboard:
|
||||||
|
|
||||||
make planck/rev4:default:flash
|
make planck/rev4:default:flash
|
||||||
|
|
||||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
See the [build environment setup](getting_started_build_tools) and the [make instructions](getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](newbs).
|
||||||
|
|
||||||
## Bootloader
|
## Bootloader
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,17 @@ We recommend the use of the [Zadig](https://zadig.akeo.ie/) utility. If you have
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Put your keyboard into bootloader mode, either by hitting the `QK_BOOT` keycode (which may be on a different layer), or by pressing the reset switch that's usually located on the underside of the board. If your keyboard has neither, try holding Escape or Space+`B` as you plug it in (see the [Bootmagic Lite](feature_bootmagic.md) docs for more details). Some boards use [Command](feature_command.md) instead of Bootmagic; in this case, you can enter bootloader mode by hitting Left Shift+Right Shift+`B` or Left Shift+Right Shift+Escape at any point while the keyboard is plugged in.
|
Put your keyboard into bootloader mode, either by hitting the `QK_BOOT` keycode (which may be on a different layer), or by pressing the reset switch that's usually located on the underside of the board. If your keyboard has neither, try holding Escape or Space+`B` as you plug it in (see the [Bootmagic Lite](feature_bootmagic) docs for more details). Some boards use [Command](feature_command) instead of Bootmagic; in this case, you can enter bootloader mode by hitting Left Shift+Right Shift+`B` or Left Shift+Right Shift+Escape at any point while the keyboard is plugged in.
|
||||||
Some keyboards may have specific instructions for entering the bootloader. For example, the [Bootmagic Lite](feature_bootmagic.md) key (default: Escape) might be on a different key, e.g. Left Control; or the magic combination for Command (default: Left Shift+Right Shift) might require you to hold something else, e.g. Left Control+Right Control. Refer to the board's README file if you are unsure.
|
Some keyboards may have specific instructions for entering the bootloader. For example, the [Bootmagic Lite](feature_bootmagic) key (default: Escape) might be on a different key, e.g. Left Control; or the magic combination for Command (default: Left Shift+Right Shift) might require you to hold something else, e.g. Left Control+Right Control. Refer to the board's README file if you are unsure.
|
||||||
|
|
||||||
To put a device in bootloader mode with USBaspLoader, tap the `RESET` button while holding down the `BOOT` button.
|
To put a device in bootloader mode with USBaspLoader, tap the `RESET` button while holding down the `BOOT` button.
|
||||||
Alternatively, hold `BOOT` while inserting the USB cable.
|
Alternatively, hold `BOOT` while inserting the USB cable.
|
||||||
|
|
||||||
Zadig should automatically detect the bootloader device, but you may sometimes need to check **Options → List All Devices** and select the device from the dropdown instead.
|
Zadig should automatically detect the bootloader device, but you may sometimes need to check **Options → List All Devices** and select the device from the dropdown instead.
|
||||||
|
|
||||||
!> If Zadig lists one or more devices with the `HidUsb` driver, your keyboard is probably not in bootloader mode. The arrow will be colored orange and you will be asked to confirm modifying a system driver. **Do not** proceed if this is the case!
|
::: warning
|
||||||
|
If Zadig lists one or more devices with the `HidUsb` driver, your keyboard is probably not in bootloader mode. The arrow will be colored orange and you will be asked to confirm modifying a system driver. **Do not** proceed if this is the case!
|
||||||
|
:::
|
||||||
|
|
||||||
If the arrow appears green, select the driver, and click **Install Driver**. See the [list of known bootloaders](#list-of-known-bootloaders) for the correct driver to install.
|
If the arrow appears green, select the driver, and click **Install Driver**. See the [list of known bootloaders](#list-of-known-bootloaders) for the correct driver to install.
|
||||||
|
|
||||||
|
@ -40,7 +42,9 @@ Right-click each entry and hit **Uninstall device**. Make sure to tick **Delete
|
||||||
|
|
||||||
Click **Action → Scan for hardware changes**. At this point, you should be able to type again. Double check in Zadig that the keyboard device(s) are using the `HidUsb` driver. If so, you're all done, and your board should be functional again! Otherwise, repeat this process until Zadig reports the correct driver.
|
Click **Action → Scan for hardware changes**. At this point, you should be able to type again. Double check in Zadig that the keyboard device(s) are using the `HidUsb` driver. If so, you're all done, and your board should be functional again! Otherwise, repeat this process until Zadig reports the correct driver.
|
||||||
|
|
||||||
?> A full reboot of your computer may sometimes be necessary at this point, to get Windows to pick up the new driver.
|
::: tip
|
||||||
|
A full reboot of your computer may sometimes be necessary at this point, to get Windows to pick up the new driver.
|
||||||
|
:::
|
||||||
|
|
||||||
## Uninstallation
|
## Uninstallation
|
||||||
|
|
||||||
|
@ -60,7 +64,9 @@ Run `pnputil /delete-driver oemXX.inf /uninstall`. This will delete the driver a
|
||||||
|
|
||||||
As with the previous section, this process may need to be repeated multiple times, as multiple drivers can be applicable to the same device.
|
As with the previous section, this process may need to be repeated multiple times, as multiple drivers can be applicable to the same device.
|
||||||
|
|
||||||
!> **WARNING:** Be *extremely careful* when doing this! You could potentially uninstall the driver for some other critical device. If you are unsure, double check the output of `/enum-drivers`, and omit the `/uninstall` flag when running `/delete-driver`.
|
::: warning
|
||||||
|
**WARNING:** Be *extremely careful* when doing this! You could potentially uninstall the driver for some other critical device. If you are unsure, double check the output of `/enum-drivers`, and omit the `/uninstall` flag when running `/delete-driver`.
|
||||||
|
:::
|
||||||
|
|
||||||
## List of Known Bootloaders
|
## List of Known Bootloaders
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ Have you ever needed an easy way to program a controller, such as a Proton C or
|
||||||
There are different styles of Easy Maker available depending on your needs:
|
There are different styles of Easy Maker available depending on your needs:
|
||||||
|
|
||||||
* [Direct Pin](https://config.qmk.fm/#/?filter=ez_maker/direct) - Connect a single switch to a single pin
|
* [Direct Pin](https://config.qmk.fm/#/?filter=ez_maker/direct) - Connect a single switch to a single pin
|
||||||
* Direct Pin + Backlight (Coming Soon) - Like Direct Pin but dedicates a single pin to [Backlight](feature_backlight.md) control
|
* Direct Pin + Backlight (Coming Soon) - Like Direct Pin but dedicates a single pin to [Backlight](feature_backlight) control
|
||||||
* Direct Pin + Numlock (Coming Soon) - Like Direct Pin but dedicates a single pin to the Numlock LED
|
* Direct Pin + Numlock (Coming Soon) - Like Direct Pin but dedicates a single pin to the Numlock LED
|
||||||
* Direct Pin + Capslock (Coming Soon) - Like Direct Pin but dedicates a single pin to the Capslock LED
|
* Direct Pin + Capslock (Coming Soon) - Like Direct Pin but dedicates a single pin to the Capslock LED
|
||||||
* Direct Pin + Encoder (Coming Soon) - Like Direct Pin but uses 2 pins to add a single rotary encoder
|
* Direct Pin + Encoder (Coming Soon) - Like Direct Pin but uses 2 pins to add a single rotary encoder
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# EEPROM Driver Configuration :id=eeprom-driver-configuration
|
# EEPROM Driver Configuration {#eeprom-driver-configuration}
|
||||||
|
|
||||||
The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
|
The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
|
||||||
|
|
||||||
|
@ -12,17 +12,19 @@ Driver | Description
|
||||||
`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost.
|
`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost.
|
||||||
`EEPROM_DRIVER = wear_leveling` | Frontend driver for the wear_leveling system, allowing for EEPROM emulation on top of flash -- both in-MCU and external SPI NOR flash.
|
`EEPROM_DRIVER = wear_leveling` | Frontend driver for the wear_leveling system, allowing for EEPROM emulation on top of flash -- both in-MCU and external SPI NOR flash.
|
||||||
|
|
||||||
## Vendor Driver Configuration :id=vendor-eeprom-driver-configuration
|
## Vendor Driver Configuration {#vendor-eeprom-driver-configuration}
|
||||||
|
|
||||||
#### STM32 L0/L1 Configuration :id=stm32l0l1-eeprom-driver-configuration
|
#### STM32 L0/L1 Configuration {#stm32l0l1-eeprom-driver-configuration}
|
||||||
|
|
||||||
!> Resetting EEPROM using an STM32L0/L1 device takes up to 1 second for every 1kB of internal EEPROM used.
|
::: warning
|
||||||
|
Resetting EEPROM using an STM32L0/L1 device takes up to 1 second for every 1kB of internal EEPROM used.
|
||||||
|
:::
|
||||||
|
|
||||||
`config.h` override | Description | Default Value
|
`config.h` override | Description | Default Value
|
||||||
------------------------------------|--------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------
|
------------------------------------|--------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------
|
||||||
`#define STM32_ONBOARD_EEPROM_SIZE` | The size of the EEPROM to use, in bytes. Erase times can be high, so it's configurable here, if not using the default value. | Minimum required to cover base _eeconfig_ data, or `1024` if VIA is enabled.
|
`#define STM32_ONBOARD_EEPROM_SIZE` | The size of the EEPROM to use, in bytes. Erase times can be high, so it's configurable here, if not using the default value. | Minimum required to cover base _eeconfig_ data, or `1024` if VIA is enabled.
|
||||||
|
|
||||||
## I2C Driver Configuration :id=i2c-eeprom-driver-configuration
|
## I2C Driver Configuration {#i2c-eeprom-driver-configuration}
|
||||||
|
|
||||||
Currently QMK supports 24xx-series chips over I2C. As such, requires a working i2c_master driver configuration. You can override the driver configuration via your config.h:
|
Currently QMK supports 24xx-series chips over I2C. As such, requires a working i2c_master driver configuration. You can override the driver configuration via your config.h:
|
||||||
|
|
||||||
|
@ -52,9 +54,11 @@ RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | <https://www.sparkfun.com/p
|
||||||
24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | <https://www.sparkfun.com/products/525>
|
24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | <https://www.sparkfun.com/products/525>
|
||||||
MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/product/1895>
|
MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/product/1895>
|
||||||
|
|
||||||
?> If you find that the EEPROM is not cooperating, ensure you've correctly shifted up your EEPROM address by 1. For example, the datasheet might state the address as `0b01010000` -- the correct value of `EXTERNAL_EEPROM_I2C_BASE_ADDRESS` needs to be `0b10100000`.
|
::: tip
|
||||||
|
If you find that the EEPROM is not cooperating, ensure you've correctly shifted up your EEPROM address by 1. For example, the datasheet might state the address as `0b01010000` -- the correct value of `EXTERNAL_EEPROM_I2C_BASE_ADDRESS` needs to be `0b10100000`.
|
||||||
|
:::
|
||||||
|
|
||||||
## SPI Driver Configuration :id=spi-eeprom-driver-configuration
|
## SPI Driver Configuration {#spi-eeprom-driver-configuration}
|
||||||
|
|
||||||
Currently QMK supports 25xx-series chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h:
|
Currently QMK supports 25xx-series chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h:
|
||||||
|
|
||||||
|
@ -74,9 +78,11 @@ Module | Equivalent `#define` | Source
|
||||||
-----------------|---------------------------------|------------------------------------------
|
-----------------|---------------------------------|------------------------------------------
|
||||||
MB85RS64V FRAM | `define EEPROM_SPI_MB85RS64V` | <https://www.adafruit.com/product/1897>
|
MB85RS64V FRAM | `define EEPROM_SPI_MB85RS64V` | <https://www.adafruit.com/product/1897>
|
||||||
|
|
||||||
!> There's no way to determine if there is an SPI EEPROM actually responding. Generally, this will result in reads of nothing but zero.
|
::: warning
|
||||||
|
There's no way to determine if there is an SPI EEPROM actually responding. Generally, this will result in reads of nothing but zero.
|
||||||
|
:::
|
||||||
|
|
||||||
## Transient Driver configuration :id=transient-eeprom-driver-configuration
|
## Transient Driver configuration {#transient-eeprom-driver-configuration}
|
||||||
|
|
||||||
The only configurable item for the transient EEPROM driver is its size:
|
The only configurable item for the transient EEPROM driver is its size:
|
||||||
|
|
||||||
|
@ -86,13 +92,13 @@ The only configurable item for the transient EEPROM driver is its size:
|
||||||
|
|
||||||
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`.
|
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`.
|
||||||
|
|
||||||
## Wear-leveling Driver Configuration :id=wear_leveling-eeprom-driver-configuration
|
## Wear-leveling Driver Configuration {#wear_leveling-eeprom-driver-configuration}
|
||||||
|
|
||||||
The wear-leveling driver uses an algorithm to minimise the number of erase cycles on the underlying MCU flash memory.
|
The wear-leveling driver uses an algorithm to minimise the number of erase cycles on the underlying MCU flash memory.
|
||||||
|
|
||||||
There is no specific configuration for this driver, but the wear-leveling system used by this driver may need configuration. See the [wear-leveling configuration](#wear_leveling-configuration) section for more information.
|
There is no specific configuration for this driver, but the wear-leveling system used by this driver may need configuration. See the [wear-leveling configuration](#wear_leveling-configuration) section for more information.
|
||||||
|
|
||||||
# Wear-leveling Configuration :id=wear_leveling-configuration
|
# Wear-leveling Configuration {#wear_leveling-configuration}
|
||||||
|
|
||||||
The wear-leveling driver has a few possible _backing stores_ that may be used by adding to your keyboard's `rules.mk` file:
|
The wear-leveling driver has a few possible _backing stores_ that may be used by adding to your keyboard's `rules.mk` file:
|
||||||
|
|
||||||
|
@ -103,9 +109,11 @@ Driver | Description
|
||||||
`WEAR_LEVELING_DRIVER = rp2040_flash` | This driver is used to write to the same storage the RP2040 executes code from.
|
`WEAR_LEVELING_DRIVER = rp2040_flash` | This driver is used to write to the same storage the RP2040 executes code from.
|
||||||
`WEAR_LEVELING_DRIVER = legacy` | This driver is the "legacy" emulated EEPROM provided in historical revisions of QMK. Currently used for STM32F0xx and STM32F4x1, but slated for deprecation and removal once `embedded_flash` support for those MCU families is complete.
|
`WEAR_LEVELING_DRIVER = legacy` | This driver is the "legacy" emulated EEPROM provided in historical revisions of QMK. Currently used for STM32F0xx and STM32F4x1, but slated for deprecation and removal once `embedded_flash` support for those MCU families is complete.
|
||||||
|
|
||||||
!> All wear-leveling drivers require an amount of RAM equivalent to the selected logical EEPROM size. Increasing the size to 32kB of EEPROM requires 32kB of RAM, which a significant number of MCUs simply do not have.
|
::: warning
|
||||||
|
All wear-leveling drivers require an amount of RAM equivalent to the selected logical EEPROM size. Increasing the size to 32kB of EEPROM requires 32kB of RAM, which a significant number of MCUs simply do not have.
|
||||||
|
:::
|
||||||
|
|
||||||
## Wear-leveling Embedded Flash Driver Configuration :id=wear_leveling-efl-driver-configuration
|
## Wear-leveling Embedded Flash Driver Configuration {#wear_leveling-efl-driver-configuration}
|
||||||
|
|
||||||
This driver performs writes to the embedded flash storage embedded in the MCU. In most circumstances, the last few of sectors of flash are used in order to minimise the likelihood of collision with program code.
|
This driver performs writes to the embedded flash storage embedded in the MCU. In most circumstances, the last few of sectors of flash are used in order to minimise the likelihood of collision with program code.
|
||||||
|
|
||||||
|
@ -119,11 +127,13 @@ Configurable options in your keyboard's `config.h`:
|
||||||
`#define WEAR_LEVELING_BACKING_SIZE` | `2048` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
|
`#define WEAR_LEVELING_BACKING_SIZE` | `2048` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
|
||||||
`#define BACKING_STORE_WRITE_SIZE` | _automatic_ | The byte width of the underlying write used on the MCU, and is usually automatically determined from the selected MCU family. If an error occurs in the auto-detection, you'll need to consult the MCU's datasheet and determine this value, specifying it directly.
|
`#define BACKING_STORE_WRITE_SIZE` | _automatic_ | The byte width of the underlying write used on the MCU, and is usually automatically determined from the selected MCU family. If an error occurs in the auto-detection, you'll need to consult the MCU's datasheet and determine this value, specifying it directly.
|
||||||
|
|
||||||
!> If your MCU does not boot after swapping to the EFL wear-leveling driver, it's likely that the flash size is incorrectly detected, usually as an MCU with larger flash and may require overriding.
|
::: warning
|
||||||
|
If your MCU does not boot after swapping to the EFL wear-leveling driver, it's likely that the flash size is incorrectly detected, usually as an MCU with larger flash and may require overriding.
|
||||||
|
:::
|
||||||
|
|
||||||
## Wear-leveling SPI Flash Driver Configuration :id=wear_leveling-flash_spi-driver-configuration
|
## Wear-leveling SPI Flash Driver Configuration {#wear_leveling-flash_spi-driver-configuration}
|
||||||
|
|
||||||
This driver performs writes to an external SPI NOR Flash peripheral. It also requires a working configuration for the SPI NOR Flash peripheral -- see the [flash driver](flash_driver.md) documentation for more information.
|
This driver performs writes to an external SPI NOR Flash peripheral. It also requires a working configuration for the SPI NOR Flash peripheral -- see the [flash driver](flash_driver) documentation for more information.
|
||||||
|
|
||||||
Configurable options in your keyboard's `config.h`:
|
Configurable options in your keyboard's `config.h`:
|
||||||
|
|
||||||
|
@ -135,9 +145,11 @@ Configurable options in your keyboard's `config.h`:
|
||||||
`#define WEAR_LEVELING_BACKING_SIZE` | `(block_count*block_size)` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
|
`#define WEAR_LEVELING_BACKING_SIZE` | `(block_count*block_size)` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
|
||||||
`#define BACKING_STORE_WRITE_SIZE` | `8` | The write width used whenever a write is performed on the external flash peripheral.
|
`#define BACKING_STORE_WRITE_SIZE` | `8` | The write width used whenever a write is performed on the external flash peripheral.
|
||||||
|
|
||||||
!> There is currently a limit of 64kB for the EEPROM subsystem within QMK, so using a larger flash is not going to be beneficial as the logical size cannot be increased beyond 65536. The backing size may be increased to a larger value, but erase timing may suffer as a result.
|
::: warning
|
||||||
|
There is currently a limit of 64kB for the EEPROM subsystem within QMK, so using a larger flash is not going to be beneficial as the logical size cannot be increased beyond 65536. The backing size may be increased to a larger value, but erase timing may suffer as a result.
|
||||||
|
:::
|
||||||
|
|
||||||
## Wear-leveling RP2040 Driver Configuration :id=wear_leveling-rp2040-driver-configuration
|
## Wear-leveling RP2040 Driver Configuration {#wear_leveling-rp2040-driver-configuration}
|
||||||
|
|
||||||
This driver performs writes to the same underlying storage that the RP2040 executes its code.
|
This driver performs writes to the same underlying storage that the RP2040 executes its code.
|
||||||
|
|
||||||
|
@ -151,7 +163,7 @@ Configurable options in your keyboard's `config.h`:
|
||||||
`#define WEAR_LEVELING_BACKING_SIZE` | `8192` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size as well as the sector size.
|
`#define WEAR_LEVELING_BACKING_SIZE` | `8192` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size as well as the sector size.
|
||||||
`#define BACKING_STORE_WRITE_SIZE` | `2` | The write width used whenever a write is performed on the external flash peripheral.
|
`#define BACKING_STORE_WRITE_SIZE` | `2` | The write width used whenever a write is performed on the external flash peripheral.
|
||||||
|
|
||||||
## Wear-leveling Legacy EEPROM Emulation Driver Configuration :id=wear_leveling-legacy-driver-configuration
|
## Wear-leveling Legacy EEPROM Emulation Driver Configuration {#wear_leveling-legacy-driver-configuration}
|
||||||
|
|
||||||
This driver performs writes to the embedded flash storage embedded in the MCU much like the normal Embedded Flash Driver, and is only for use with STM32F0xx and STM32F4x1 devices. This flash implementation is still currently provided as the EFL driver is currently non-functional for the previously mentioned families.
|
This driver performs writes to the embedded flash storage embedded in the MCU much like the normal Embedded Flash Driver, and is only for use with STM32F0xx and STM32F4x1 devices. This flash implementation is still currently provided as the EFL driver is currently non-functional for the previously mentioned families.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Frequently Asked Build Questions
|
# Frequently Asked Build Questions
|
||||||
|
|
||||||
This page covers questions about building QMK. If you haven't yet done so, you should read the [Build Environment Setup](getting_started_build_tools.md) and [Make Instructions](getting_started_make_guide.md) guides.
|
This page covers questions about building QMK. If you haven't yet done so, you should read the [Build Environment Setup](newbs_getting_started) and [Make Instructions](getting_started_make_guide) guides.
|
||||||
|
|
||||||
## Can't Program on Linux
|
## Can't Program on Linux
|
||||||
You will need proper permissions to operate a device. For Linux users, see the instructions regarding `udev` rules, below. If you have issues with `udev`, a work-around is to use the `sudo` command. If you are not familiar with this command, check its manual with `man sudo` or [see this webpage](https://linux.die.net/man/8/sudo).
|
You will need proper permissions to operate a device. For Linux users, see the instructions regarding `udev` rules, below. If you have issues with `udev`, a work-around is to use the `sudo` command. If you are not familiar with this command, check its manual with `man sudo` or [see this webpage](https://linux.die.net/man/8/sudo).
|
||||||
|
@ -17,7 +17,7 @@ or just:
|
||||||
|
|
||||||
Note that running `make` with `sudo` is generally ***not*** a good idea, and you should use one of the former methods, if possible.
|
Note that running `make` with `sudo` is generally ***not*** a good idea, and you should use one of the former methods, if possible.
|
||||||
|
|
||||||
### Linux `udev` Rules :id=linux-udev-rules
|
### Linux `udev` Rules {#linux-udev-rules}
|
||||||
|
|
||||||
On Linux, you'll need proper privileges to communicate with the bootloader device. You can either use `sudo` when flashing firmware (not recommended), or place [this file](https://github.com/qmk/qmk_firmware/tree/master/util/udev/50-qmk.rules) into `/etc/udev/rules.d/`.
|
On Linux, you'll need proper privileges to communicate with the bootloader device. You can either use `sudo` when flashing firmware (not recommended), or place [this file](https://github.com/qmk/qmk_firmware/tree/master/util/udev/50-qmk.rules) into `/etc/udev/rules.d/`.
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ Issues encountered when flashing keyboards on Windows are most often due to havi
|
||||||
|
|
||||||
Re-running the QMK installation script (`./util/qmk_install.sh` from the `qmk_firmware` directory in MSYS2 or WSL) or reinstalling the QMK Toolbox may fix the issue. Alternatively, you can download and run the [`qmk_driver_installer`](https://github.com/qmk/qmk_driver_installer) package manually.
|
Re-running the QMK installation script (`./util/qmk_install.sh` from the `qmk_firmware` directory in MSYS2 or WSL) or reinstalling the QMK Toolbox may fix the issue. Alternatively, you can download and run the [`qmk_driver_installer`](https://github.com/qmk/qmk_driver_installer) package manually.
|
||||||
|
|
||||||
If that doesn't work, then you may need to download and run Zadig. See [Bootloader Driver Installation with Zadig](driver_installation_zadig.md) for more detailed information.
|
If that doesn't work, then you may need to download and run Zadig. See [Bootloader Driver Installation with Zadig](driver_installation_zadig) for more detailed information.
|
||||||
|
|
||||||
## USB VID and PID
|
## USB VID and PID
|
||||||
You can use any ID you want with editing `config.h`. Using any presumably unused ID will be no problem in fact except for very low chance of collision with other product.
|
You can use any ID you want with editing `config.h`. Using any presumably unused ID will be no problem in fact except for very low chance of collision with other product.
|
||||||
|
@ -66,4 +66,4 @@ Due to how EEPROM works on ARM based chips, saved settings may no longer be vali
|
||||||
[Planck rev6 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) can be used to force an eeprom reset. After flashing this image, flash your normal firmware again which should restore your keyboard to _normal_ working order.
|
[Planck rev6 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) can be used to force an eeprom reset. After flashing this image, flash your normal firmware again which should restore your keyboard to _normal_ working order.
|
||||||
[Preonic rev3 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/537849497313738762/preonic_rev3_default.bin)
|
[Preonic rev3 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/537849497313738762/preonic_rev3_default.bin)
|
||||||
|
|
||||||
If bootmagic is enabled in any form, you should be able to do this too (see [Bootmagic docs](feature_bootmagic.md) and keyboard info for specifics on how to do this).
|
If bootmagic is enabled in any form, you should be able to do this too (see [Bootmagic docs](feature_bootmagic) and keyboard info for specifics on how to do this).
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
This page details various common questions people have about troubleshooting their keyboards.
|
This page details various common questions people have about troubleshooting their keyboards.
|
||||||
|
|
||||||
## Debugging :id=debugging
|
## Debugging {#debugging}
|
||||||
|
|
||||||
Your keyboard will output debug information if you have `CONSOLE_ENABLE = yes` in your `rules.mk`. By default the output is very limited, but you can turn on debug mode to increase the amount of debug output. Use the `DB_TOGG` keycode in your keymap, use the [Command](feature_command.md) feature to enable debug mode, or add the following code to your keymap.
|
Your keyboard will output debug information if you have `CONSOLE_ENABLE = yes` in your `rules.mk`. By default the output is very limited, but you can turn on debug mode to increase the amount of debug output. Use the `DB_TOGG` keycode in your keymap, use the [Command](feature_command) feature to enable debug mode, or add the following code to your keymap.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void keyboard_post_init_user(void) {
|
void keyboard_post_init_user(void) {
|
||||||
|
@ -26,15 +26,15 @@ For compatible platforms, [QMK Toolbox](https://github.com/qmk/qmk_toolbox) can
|
||||||
|
|
||||||
### Debugging with QMK CLI
|
### Debugging with QMK CLI
|
||||||
|
|
||||||
Prefer a terminal based solution? The [QMK CLI console command](cli_commands.md#qmk-console) can be used to display debug messages from your keyboard.
|
Prefer a terminal based solution? The [QMK CLI console command](cli_commands#qmk-console) can be used to display debug messages from your keyboard.
|
||||||
|
|
||||||
### Debugging With hid_listen
|
### Debugging With hid_listen
|
||||||
|
|
||||||
Something stand-alone? [hid_listen](https://www.pjrc.com/teensy/hid_listen.html), provided by PJRC, can also be used to display debug messages. Prebuilt binaries for Windows,Linux,and MacOS are available.
|
Something stand-alone? [hid_listen](https://www.pjrc.com/teensy/hid_listen.html), provided by PJRC, can also be used to display debug messages. Prebuilt binaries for Windows,Linux,and MacOS are available.
|
||||||
|
|
||||||
## Sending Your Own Debug Messages :id=debug-api
|
## Sending Your Own Debug Messages {#debug-api}
|
||||||
|
|
||||||
Sometimes it's useful to print debug messages from within your [custom code](custom_quantum_functions.md). Doing so is pretty simple. Start by including `print.h` at the top of your file:
|
Sometimes it's useful to print debug messages from within your [custom code](custom_quantum_functions). Doing so is pretty simple. Start by including `print.h` at the top of your file:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
|
@ -49,7 +49,7 @@ After that you can use a few different print functions:
|
||||||
|
|
||||||
## Debug Examples
|
## Debug Examples
|
||||||
|
|
||||||
Below is a collection of real world debugging examples. For additional information, refer to [Debugging/Troubleshooting QMK](faq_debug.md).
|
Below is a collection of real world debugging examples. For additional information, refer to [Debugging/Troubleshooting QMK](faq_debug).
|
||||||
|
|
||||||
### Which matrix position is this keypress?
|
### Which matrix position is this keypress?
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
|
|
||||||
## I don't know where to start!
|
## I don't know where to start!
|
||||||
|
|
||||||
If this is the case, then you should start with our [Newbs Guide](newbs.md). There is a lot of great info there, and that should cover everything you need to get started.
|
If this is the case, then you should start with our [Newbs Guide](newbs). There is a lot of great info there, and that should cover everything you need to get started.
|
||||||
|
|
||||||
If that's an issue, hop onto the [QMK Configurator](https://config.qmk.fm), as that will handle a majority of what you need there.
|
If that's an issue, hop onto the [QMK Configurator](https://config.qmk.fm), as that will handle a majority of what you need there.
|
||||||
|
|
||||||
## How can I flash the firmware I built?
|
## How can I flash the firmware I built?
|
||||||
|
|
||||||
First, head to the [Compiling/Flashing FAQ Page](faq_build.md). There is a good deal of info there, and you'll find a bunch of solutions to common issues there.
|
First, head to the [Compiling/Flashing FAQ Page](faq_build). There is a good deal of info there, and you'll find a bunch of solutions to common issues there.
|
||||||
|
|
||||||
## What if I have an issue that isn't covered here?
|
## What if I have an issue that isn't covered here?
|
||||||
|
|
||||||
|
@ -26,9 +26,9 @@ Then please open an [issue](https://github.com/qmk/qmk_firmware/issues/new), and
|
||||||
|
|
||||||
## But `git` and `GitHub` are intimidating!
|
## But `git` and `GitHub` are intimidating!
|
||||||
|
|
||||||
Don't worry, we have some pretty nice [Guidelines](newbs_git_best_practices.md) on how to start using `git` and GitHub to make things easier to develop.
|
Don't worry, we have some pretty nice [Guidelines](newbs_git_best_practices) on how to start using `git` and GitHub to make things easier to develop.
|
||||||
|
|
||||||
Additionally, you can find additional `git` and GitHub related links [here](newbs_learn_more_resources.md).
|
Additionally, you can find additional `git` and GitHub related links [here](newbs_learn_more_resources).
|
||||||
|
|
||||||
## I have a Keyboard that I want to add support for
|
## I have a Keyboard that I want to add support for
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ If you have any questions about this, open an issue or head to [Discord](https:/
|
||||||
|
|
||||||
TMK was originally designed and implemented by [Jun Wako](https://github.com/tmk). QMK started as [Jack Humbert](https://github.com/jackhumbert)'s fork of TMK for the Planck. After a while Jack's fork had diverged quite a bit from TMK, and in 2015 Jack decided to rename his fork to QMK.
|
TMK was originally designed and implemented by [Jun Wako](https://github.com/tmk). QMK started as [Jack Humbert](https://github.com/jackhumbert)'s fork of TMK for the Planck. After a while Jack's fork had diverged quite a bit from TMK, and in 2015 Jack decided to rename his fork to QMK.
|
||||||
|
|
||||||
From a technical standpoint QMK builds upon TMK by adding several new features. Most notably QMK has expanded the number of available keycodes and uses these to implement advanced features like `S()`, `LCTL()`, and `MO()`. You can see a complete list of these keycodes in [Keycodes](keycodes.md).
|
From a technical standpoint QMK builds upon TMK by adding several new features. Most notably QMK has expanded the number of available keycodes and uses these to implement advanced features like `S()`, `LCTL()`, and `MO()`. You can see a complete list of these keycodes in [Keycodes](keycodes).
|
||||||
|
|
||||||
From a project and community management standpoint TMK maintains all the officially supported keyboards by himself, with a bit of community support. Separate community maintained forks exist or can be created for other keyboards. Only a few keymaps are provided by default, so users typically don't share keymaps with each other. QMK encourages sharing of both keyboards and keymaps through a centrally managed repository, accepting all pull requests that follow the quality standards. These are mostly community maintained, but the QMK team also helps when necessary.
|
From a project and community management standpoint TMK maintains all the officially supported keyboards by himself, with a bit of community support. Separate community maintained forks exist or can be created for other keyboards. Only a few keymaps are provided by default, so users typically don't share keymaps with each other. QMK encourages sharing of both keyboards and keymaps through a centrally managed repository, accepting all pull requests that follow the quality standards. These are mostly community maintained, but the QMK team also helps when necessary.
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Keymap FAQ
|
# Keymap FAQ
|
||||||
|
|
||||||
This page covers questions people often have about keymaps. If you haven't you should read [Keymap Overview](keymap.md) first.
|
This page covers questions people often have about keymaps. If you haven't you should read [Keymap Overview](keymap) first.
|
||||||
|
|
||||||
## What Keycodes Can I Use?
|
## What Keycodes Can I Use?
|
||||||
|
|
||||||
See [Keycodes](keycodes.md) for an index of keycodes available to you. These link to more extensive documentation when available.
|
See [Keycodes](keycodes) for an index of keycodes available to you. These link to more extensive documentation when available.
|
||||||
|
|
||||||
Keycodes are actually defined in [quantum/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/keycode.h).
|
Keycodes are actually defined in [quantum/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/keycode.h).
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ QMK has a couple of features which allow you to change the behavior of your keyb
|
||||||
|
|
||||||
Refer to the EEPROM clearing methods above, which should return those keys to normal operation. If that doesn't work, look here:
|
Refer to the EEPROM clearing methods above, which should return those keys to normal operation. If that doesn't work, look here:
|
||||||
|
|
||||||
* [Magic Keycodes](keycodes_magic.md)
|
* [Magic Keycodes](keycodes_magic)
|
||||||
* [Command](feature_command.md)
|
* [Command](feature_command)
|
||||||
|
|
||||||
## The Menu Key Isn't Working
|
## The Menu Key Isn't Working
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ Old vintage mechanical keyboards occasionally have lock switches but modern ones
|
||||||
|
|
||||||
## Input Special Characters Other Than ASCII like Cédille 'Ç'
|
## Input Special Characters Other Than ASCII like Cédille 'Ç'
|
||||||
|
|
||||||
See the [Unicode](feature_unicode.md) feature.
|
See the [Unicode](feature_unicode) feature.
|
||||||
|
|
||||||
## `Fn` Key on macOS
|
## `Fn` Key on macOS
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ https://github.com/tekezo/Karabiner/issues/403
|
||||||
|
|
||||||
## Esc and <code>`</code> on a Single Key
|
## Esc and <code>`</code> on a Single Key
|
||||||
|
|
||||||
See the [Grave Escape](feature_grave_esc.md) feature.
|
See the [Grave Escape](feature_grave_esc) feature.
|
||||||
|
|
||||||
## Eject on Mac OSX
|
## Eject on Mac OSX
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Miscellaneous FAQ
|
# Miscellaneous FAQ
|
||||||
|
|
||||||
## How do I test my keyboard? :id=testing
|
## How do I test my keyboard? {#testing}
|
||||||
|
|
||||||
Testing your keyboard is usually pretty straightforward. Press every single key and make sure it sends the keys you expect. You can use [QMK Configurator](https://config.qmk.fm/#/test/)'s test mode to check your keyboard, even if it doesn't run QMK.
|
Testing your keyboard is usually pretty straightforward. Press every single key and make sure it sends the keys you expect. You can use [QMK Configurator](https://config.qmk.fm/#/test/)'s test mode to check your keyboard, even if it doesn't run QMK.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Modifier Keys :id=modifier-keys
|
# Modifier Keys {#modifier-keys}
|
||||||
|
|
||||||
These allow you to combine a modifier with a keycode. When pressed, the keydown event for the modifier, then `kc` will be sent. On release, the keyup event for `kc`, then the modifier will be sent.
|
These allow you to combine a modifier with a keycode. When pressed, the keydown event for the modifier, then `kc` will be sent. On release, the keyup event for `kc`, then the modifier will be sent.
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ These allow you to combine a modifier with a keycode. When pressed, the keydown
|
||||||
|
|
||||||
You can also chain them, for example `LCTL(LALT(KC_DEL))` or `C(A(KC_DEL))` makes a key that sends Control+Alt+Delete with a single keypress.
|
You can also chain them, for example `LCTL(LALT(KC_DEL))` or `C(A(KC_DEL))` makes a key that sends Control+Alt+Delete with a single keypress.
|
||||||
|
|
||||||
# Checking Modifier State :id=checking-modifier-state
|
# Checking Modifier State {#checking-modifier-state}
|
||||||
|
|
||||||
The current modifier state can mainly be accessed with two functions: `get_mods()` for normal modifiers and modtaps and `get_oneshot_mods()` for one-shot modifiers (unless they're held, in which case they act like normal modifier keys).
|
The current modifier state can mainly be accessed with two functions: `get_mods()` for normal modifiers and modtaps and `get_oneshot_mods()` for one-shot modifiers (unless they're held, in which case they act like normal modifier keys).
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ The presence of one or more specific modifiers in the current modifier state can
|
||||||
Thus, to give an example, `01000010` would be the internal representation of LShift+RAlt.
|
Thus, to give an example, `01000010` would be the internal representation of LShift+RAlt.
|
||||||
For more information on bitwise operators in C, click [here](https://en.wikipedia.org/wiki/Bitwise_operations_in_C) to open the Wikipedia page on the topic.
|
For more information on bitwise operators in C, click [here](https://en.wikipedia.org/wiki/Bitwise_operations_in_C) to open the Wikipedia page on the topic.
|
||||||
|
|
||||||
In practice, this means that you can check whether a given modifier is active with `get_mods() & MOD_BIT(KC_<modifier>)` (see the [list of modifier keycodes](keycodes_basic.md#modifiers)) or with `get_mods() & MOD_MASK_<modifier>` if the difference between left and right hand modifiers is not important and you want to match both. Same thing can be done for one-shot modifiers if you replace `get_mods()` with `get_oneshot_mods()`.
|
In practice, this means that you can check whether a given modifier is active with `get_mods() & MOD_BIT(KC_<modifier>)` (see the [list of modifier keycodes](keycodes_basic#modifiers)) or with `get_mods() & MOD_MASK_<modifier>` if the difference between left and right hand modifiers is not important and you want to match both. Same thing can be done for one-shot modifiers if you replace `get_mods()` with `get_oneshot_mods()`.
|
||||||
|
|
||||||
To check that *only* a specific set of mods is active at a time, use a simple equality operator: `get_mods() == <mod mask>`.
|
To check that *only* a specific set of mods is active at a time, use a simple equality operator: `get_mods() == <mod mask>`.
|
||||||
|
|
||||||
|
@ -77,11 +77,11 @@ Similarly, in addition to `get_oneshot_mods()`, there also exists these function
|
||||||
* `set_oneshot_mods(mods)`: Overwrite current one-shot modifier state with `mods`
|
* `set_oneshot_mods(mods)`: Overwrite current one-shot modifier state with `mods`
|
||||||
* `clear_oneshot_mods()`: Reset the one-shot modifier state by disabling all one-shot modifiers
|
* `clear_oneshot_mods()`: Reset the one-shot modifier state by disabling all one-shot modifiers
|
||||||
|
|
||||||
## Examples :id=examples
|
## Examples {#examples}
|
||||||
|
|
||||||
The following examples use [advanced macro functions](feature_macros.md#advanced-macro-functions) which you can read more about in the [documentation page on macros](feature_macros.md).
|
The following examples use [advanced macro functions](feature_macros#advanced-macro-functions) which you can read more about in the [documentation page on macros](feature_macros).
|
||||||
|
|
||||||
### Alt + Escape for Alt + Tab :id=alt-escape-for-alt-tab
|
### Alt + Escape for Alt + Tab {#alt-escape-for-alt-tab}
|
||||||
|
|
||||||
Simple example where chording Left Alt with `KC_ESC` makes it behave like `KC_TAB` for alt-tabbing between applications. This example strictly checks if only Left Alt is active, meaning you can't do Alt+Shift+Esc to switch between applications in reverse order. Also keep in mind that this removes the ability to trigger the actual Alt+Escape keyboard shortcut, though it keeps the ability to do AltGr+Escape.
|
Simple example where chording Left Alt with `KC_ESC` makes it behave like `KC_TAB` for alt-tabbing between applications. This example strictly checks if only Left Alt is active, meaning you can't do Alt+Shift+Esc to switch between applications in reverse order. Also keep in mind that this removes the ability to trigger the actual Alt+Escape keyboard shortcut, though it keeps the ability to do AltGr+Escape.
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### Shift + Backspace for Delete :id=shift-backspace-for-delete
|
### Shift + Backspace for Delete {#shift-backspace-for-delete}
|
||||||
|
|
||||||
Advanced example where the original behaviour of shift is cancelled when chorded with `KC_BSPC` and is instead fully replaced by `KC_DEL`. Two main variables are created to make this work well: `mod_state` and `delkey_registered`. The first one stores the modifier state and is used to restore it after registering `KC_DEL`. The second variable is a boolean variable (true or false) which keeps track of the status of `KC_DEL` to manage the release of the whole Backspace/Delete key correctly.
|
Advanced example where the original behaviour of shift is cancelled when chorded with `KC_BSPC` and is instead fully replaced by `KC_DEL`. Two main variables are created to make this work well: `mod_state` and `delkey_registered`. The first one stores the modifier state and is used to restore it after registering `KC_DEL`. The second variable is a boolean variable (true or false) which keeps track of the status of `KC_DEL` to manage the release of the whole Backspace/Delete key correctly.
|
||||||
|
|
||||||
|
@ -160,28 +160,28 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
Alternatively, this can be done with [Key Overrides](feature_key_overrides?id=simple-example).
|
Alternatively, this can be done with [Key Overrides](feature_key_overrides#simple-example).
|
||||||
|
|
||||||
# Advanced topics :id=advanced-topics
|
# Advanced topics {#advanced-topics}
|
||||||
|
|
||||||
This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for.
|
This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for.
|
||||||
|
|
||||||
## Layers :id=switching-and-toggling-layers
|
## Layers {#switching-and-toggling-layers}
|
||||||
|
|
||||||
* [Layers](feature_layers.md)
|
* [Layers](feature_layers)
|
||||||
|
|
||||||
## Mod-Tap :id=mod-tap
|
## Mod-Tap {#mod-tap}
|
||||||
|
|
||||||
* [Mod-Tap](mod_tap.md)
|
* [Mod-Tap](mod_tap)
|
||||||
|
|
||||||
## One Shot Keys :id=one-shot-keys
|
## One Shot Keys {#one-shot-keys}
|
||||||
|
|
||||||
* [One Shot Keys](one_shot_keys.md)
|
* [One Shot Keys](one_shot_keys)
|
||||||
|
|
||||||
## Tap-Hold Configuration Options :id=tap-hold-configuration-options
|
## Tap-Hold Configuration Options {#tap-hold-configuration-options}
|
||||||
|
|
||||||
* [Tap-Hold Configuration Options](tap_hold.md)
|
* [Tap-Hold Configuration Options](tap_hold)
|
||||||
|
|
||||||
## Key Overrides :id=key-overrides
|
## Key Overrides {#key-overrides}
|
||||||
|
|
||||||
* [Key Overrides](feature_key_overrides.md)
|
* [Key Overrides](feature_key_overrides)
|
||||||
|
|
|
@ -27,7 +27,7 @@ per speaker is - for example with a piezo buzzer - the black lead to Ground, and
|
||||||
|
|
||||||
|
|
||||||
## ARM based boards
|
## ARM based boards
|
||||||
for more technical details, see the notes on [Audio driver](audio_driver.md).
|
for more technical details, see the notes on [Audio driver](audio_driver).
|
||||||
|
|
||||||
<!-- because I'm not sure where to fit this in: https://waveeditonline.com/ -->
|
<!-- because I'm not sure where to fit this in: https://waveeditonline.com/ -->
|
||||||
### DAC (basic)
|
### DAC (basic)
|
||||||
|
@ -131,7 +131,7 @@ You can override the default songs by doing something like this in your `config.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#ifdef AUDIO_ENABLE
|
#ifdef AUDIO_ENABLE
|
||||||
# define STARTUP_SONG SONG(STARTUP_SOUND)
|
# define STARTUP_SONG SONG(STARTUP_SOUND)
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -167,7 +167,9 @@ The available keycodes for audio are:
|
||||||
|`QK_AUDIO_OFF` |`AU_OFF` |Turns off Audio Feature |
|
|`QK_AUDIO_OFF` |`AU_OFF` |Turns off Audio Feature |
|
||||||
|`QK_AUDIO_TOGGLE` |`AU_TOGG`|Toggles Audio state |
|
|`QK_AUDIO_TOGGLE` |`AU_TOGG`|Toggles Audio state |
|
||||||
|
|
||||||
!> These keycodes turn all of the audio functionality on and off. Turning it off means that audio feedback, audio clicky, music mode, etc. are disabled, completely.
|
::: warning
|
||||||
|
These keycodes turn all of the audio functionality on and off. Turning it off means that audio feedback, audio clicky, music mode, etc. are disabled, completely.
|
||||||
|
:::
|
||||||
|
|
||||||
## Audio Config
|
## Audio Config
|
||||||
|
|
||||||
|
@ -346,7 +348,7 @@ You can configure the default, min and max frequencies, the stepping and built i
|
||||||
|
|
||||||
## MIDI Functionality
|
## MIDI Functionality
|
||||||
|
|
||||||
See [MIDI](feature_midi.md)
|
See [MIDI](feature_midi)
|
||||||
|
|
||||||
## Audio Keycodes
|
## Audio Keycodes
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,9 @@ occasion. This is simply due to habit and holding some keys a little longer
|
||||||
than others. Once you find this value, work on tapping your problem keys a little
|
than others. Once you find this value, work on tapping your problem keys a little
|
||||||
quicker than normal and you will be set.
|
quicker than normal and you will be set.
|
||||||
|
|
||||||
?> Auto Shift has three special keys that can help you get this value right very quick. See "Auto Shift Setup" for more details!
|
::: tip
|
||||||
|
Auto Shift has three special keys that can help you get this value right very quick. See "Auto Shift Setup" for more details!
|
||||||
|
:::
|
||||||
|
|
||||||
For more granular control of this feature, you can add the following to your `config.h`:
|
For more granular control of this feature, you can add the following to your `config.h`:
|
||||||
|
|
||||||
|
@ -179,23 +181,23 @@ For more granular control, there is `get_auto_shifted_key`. The default function
|
||||||
```c
|
```c
|
||||||
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||||
switch (keycode) {
|
switch (keycode) {
|
||||||
# ifndef NO_AUTO_SHIFT_ALPHA
|
# ifndef NO_AUTO_SHIFT_ALPHA
|
||||||
case AUTO_SHIFT_ALPHA:
|
case AUTO_SHIFT_ALPHA:
|
||||||
# endif
|
# endif
|
||||||
# ifndef NO_AUTO_SHIFT_NUMERIC
|
# ifndef NO_AUTO_SHIFT_NUMERIC
|
||||||
case AUTO_SHIFT_NUMERIC:
|
case AUTO_SHIFT_NUMERIC:
|
||||||
# endif
|
# endif
|
||||||
# ifndef NO_AUTO_SHIFT_SPECIAL
|
# ifndef NO_AUTO_SHIFT_SPECIAL
|
||||||
# ifndef NO_AUTO_SHIFT_TAB
|
# ifndef NO_AUTO_SHIFT_TAB
|
||||||
case KC_TAB:
|
case KC_TAB:
|
||||||
# endif
|
# endif
|
||||||
# ifndef NO_AUTO_SHIFT_SYMBOLS
|
# ifndef NO_AUTO_SHIFT_SYMBOLS
|
||||||
case AUTO_SHIFT_SYMBOLS:
|
case AUTO_SHIFT_SYMBOLS:
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# ifdef AUTO_SHIFT_ENTER
|
# ifdef AUTO_SHIFT_ENTER
|
||||||
case KC_ENT:
|
case KC_ENT:
|
||||||
# endif
|
# endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return get_custom_auto_shifted_key(keycode, record);
|
return get_custom_auto_shifted_key(keycode, record);
|
||||||
|
@ -290,7 +292,7 @@ Holding and releasing a Tap Hold key without pressing another key will ordinaril
|
||||||
result in only the hold. With `retro shift` enabled this action will instead
|
result in only the hold. With `retro shift` enabled this action will instead
|
||||||
produce a shifted version of the tap keycode on release.
|
produce a shifted version of the tap keycode on release.
|
||||||
|
|
||||||
It does not require [Retro Tapping](tap_hold.md#retro-tapping) to be enabled, and
|
It does not require [Retro Tapping](tap_hold#retro-tapping) to be enabled, and
|
||||||
if both are enabled the state of `retro tapping` will only apply if the tap keycode
|
if both are enabled the state of `retro tapping` will only apply if the tap keycode
|
||||||
is not matched by Auto Shift. `RETRO_TAPPING_PER_KEY` and its corresponding
|
is not matched by Auto Shift. `RETRO_TAPPING_PER_KEY` and its corresponding
|
||||||
function, however, are checked before `retro shift` is applied.
|
function, however, are checked before `retro shift` is applied.
|
||||||
|
@ -314,10 +316,10 @@ Without a value set, holds of any length without an interrupting key will produc
|
||||||
|
|
||||||
This value (if set) must be greater than one's `TAPPING_TERM`, as the key press
|
This value (if set) must be greater than one's `TAPPING_TERM`, as the key press
|
||||||
must be designated as a 'hold' by `process_tapping` before we send the modifier.
|
must be designated as a 'hold' by `process_tapping` before we send the modifier.
|
||||||
[Per-key tapping terms](tap_hold.md#tapping-term) can be used as a workaround.
|
[Per-key tapping terms](tap_hold#tapping-term) can be used as a workaround.
|
||||||
There is no such limitation in regards to `AUTO_SHIFT_TIMEOUT` for normal keys.
|
There is no such limitation in regards to `AUTO_SHIFT_TIMEOUT` for normal keys.
|
||||||
|
|
||||||
**Note:** Tap Holds must be added to Auto Shift, see [here.](feature_auto_shift.md#auto-shift-per-key)
|
**Note:** Tap Holds must be added to Auto Shift, see [here.](feature_auto_shift#auto-shift-per-key)
|
||||||
`IS_RETRO` may be helpful if one wants all Tap Holds retro shifted.
|
`IS_RETRO` may be helpful if one wants all Tap Holds retro shifted.
|
||||||
|
|
||||||
### Retro Shift and Tap Hold Configurations
|
### Retro Shift and Tap Hold Configurations
|
||||||
|
@ -326,7 +328,7 @@ Tap Hold Configurations work a little differently when using Retro Shift.
|
||||||
Referencing `TAPPING_TERM` makes little sense, as holding longer would result in
|
Referencing `TAPPING_TERM` makes little sense, as holding longer would result in
|
||||||
shifting one of the keys.
|
shifting one of the keys.
|
||||||
|
|
||||||
`RETRO_SHIFT` enables [`PERMISSIVE_HOLD`-like behaviour](tap_hold.md#permissive-hold) (even if not explicitly enabled) on all mod-taps for which `RETRO_SHIFT` applies.
|
`RETRO_SHIFT` enables [`PERMISSIVE_HOLD`-like behaviour](tap_hold#permissive-hold) (even if not explicitly enabled) on all mod-taps for which `RETRO_SHIFT` applies.
|
||||||
|
|
||||||
## Using Auto Shift Setup
|
## Using Auto Shift Setup
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
There are a lot of words that are prone to being typed incorrectly, due to habit, sequence or just user error. This feature leverages your firmware to automatically correct these errors, to help reduce typos.
|
There are a lot of words that are prone to being typed incorrectly, due to habit, sequence or just user error. This feature leverages your firmware to automatically correct these errors, to help reduce typos.
|
||||||
|
|
||||||
## How does it work? :id=how-does-it-work
|
## How does it work? {#how-does-it-work}
|
||||||
|
|
||||||
The feature maintains a small buffer of recent key presses. On each key press, it checks whether the buffer ends in a recognized typo, and if so, automatically sends keystrokes to correct it.
|
The feature maintains a small buffer of recent key presses. On each key press, it checks whether the buffer ends in a recognized typo, and if so, automatically sends keystrokes to correct it.
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ The tricky part is how to efficiently check the buffer for typos. We don’t wan
|
||||||
|
|
||||||
Since we search whether the buffer ends in a typo, we store the trie writing in reverse. The trie is queried starting from the last letter, then second to last letter, and so on, until either a letter doesn’t match or we reach a leaf, meaning a typo was found.
|
Since we search whether the buffer ends in a typo, we store the trie writing in reverse. The trie is queried starting from the last letter, then second to last letter, and so on, until either a letter doesn’t match or we reach a leaf, meaning a typo was found.
|
||||||
|
|
||||||
## How do I enable Autocorrection :id=how-do-i-enable-autocorrection
|
## How do I enable Autocorrection {#how-do-i-enable-autocorrection}
|
||||||
|
|
||||||
In your `rules.mk`, add this:
|
In your `rules.mk`, add this:
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ Additionally, you will need a library for autocorrection. A small sample librar
|
||||||
|
|
||||||
By default, autocorrect is disabled. To enable it, you need to use the `AC_TOGG` keycode to enable it. The status is stored in persistent memory, so you shouldn't need to enabled it again.
|
By default, autocorrect is disabled. To enable it, you need to use the `AC_TOGG` keycode to enable it. The status is stored in persistent memory, so you shouldn't need to enabled it again.
|
||||||
|
|
||||||
## Customizing autocorrect library :id=customizing-autocorrect-library
|
## Customizing autocorrect library {#customizing-autocorrect-library}
|
||||||
|
|
||||||
To provide a custom library, you need to create a text file with the corrections. For instance:
|
To provide a custom library, you need to create a text file with the corrections. For instance:
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ static const uint8_t autocorrect_data[DICTIONARY_SIZE] PROGMEM = {85, 7, 0, 23,
|
||||||
0};
|
0};
|
||||||
```
|
```
|
||||||
|
|
||||||
### Avoiding false triggers :id=avoiding-false-triggers
|
### Avoiding false triggers {#avoiding-false-triggers}
|
||||||
|
|
||||||
By default, typos are searched within words, to find typos within longer identifiers like maxFitlerOuput. While this is useful, a consequence is that autocorrection will falsely trigger when a typo happens to be a substring of a correctly-spelled word. For instance, if we had thier -> their as an entry, it would falsely trigger on (correct, though relatively uncommon) words like “wealthier” and “filthier.”
|
By default, typos are searched within words, to find typos within longer identifiers like maxFitlerOuput. While this is useful, a consequence is that autocorrection will falsely trigger when a typo happens to be a substring of a correctly-spelled word. For instance, if we had thier -> their as an entry, it would falsely trigger on (correct, though relatively uncommon) words like “wealthier” and “filthier.”
|
||||||
|
|
||||||
|
@ -82,7 +82,9 @@ The solution is to set a word break : before and/or after the typo to constrain
|
||||||
|
|
||||||
The `qmk generate-autocorrect-data` commands can make an effort to check for entries that would false trigger as substrings of correct words. It searches each typo against a dictionary of 25K English words from the english_words Python package, provided it’s installed. (run `python3 -m pip install english_words` to install it.)
|
The `qmk generate-autocorrect-data` commands can make an effort to check for entries that would false trigger as substrings of correct words. It searches each typo against a dictionary of 25K English words from the english_words Python package, provided it’s installed. (run `python3 -m pip install english_words` to install it.)
|
||||||
|
|
||||||
?> Unfortunately, this is limited to just english words, at this point.
|
::: tip
|
||||||
|
Unfortunately, this is limited to just english words, at this point.
|
||||||
|
:::
|
||||||
|
|
||||||
## Overriding Autocorrect
|
## Overriding Autocorrect
|
||||||
|
|
||||||
|
@ -96,7 +98,7 @@ This works because the autocorrection implementation doesn’t understand hotkey
|
||||||
|
|
||||||
Additionally, you can use the `AC_TOGG` keycode to toggle the on/off status for Autocorrect.
|
Additionally, you can use the `AC_TOGG` keycode to toggle the on/off status for Autocorrect.
|
||||||
|
|
||||||
### Keycodes :id=keycodes
|
### Keycodes {#keycodes}
|
||||||
|
|
||||||
|Keycode |Aliases |Description |
|
|Keycode |Aliases |Description |
|
||||||
|-----------------------|---------|----------------------------------------------|
|
|-----------------------|---------|----------------------------------------------|
|
||||||
|
@ -110,7 +112,9 @@ Additionally, you can use the `AC_TOGG` keycode to toggle the on/off status for
|
||||||
|
|
||||||
Callback function `bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods)` is available to customise incoming keycodes and handle exceptions. You can use this function to sanitise input before they are passed onto the autocorrect engine
|
Callback function `bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods)` is available to customise incoming keycodes and handle exceptions. You can use this function to sanitise input before they are passed onto the autocorrect engine
|
||||||
|
|
||||||
?> Sanitisation of input is required because autocorrect will only match 8-bit [basic keycodes](keycodes_basic.md) for typos. If valid modifier keys or 16-bit keycodes that are part of a user's word input (such as Shift + A) is passed through, they will fail typo letter detection. For example a [Mod-Tap](mod_tap.md) key such as `LCTL_T(KC_A)` is 16-bit and should be masked for the 8-bit `KC_A`.
|
::: tip
|
||||||
|
Sanitisation of input is required because autocorrect will only match 8-bit [basic keycodes](keycodes_basic) for typos. If valid modifier keys or 16-bit keycodes that are part of a user's word input (such as Shift + A) is passed through, they will fail typo letter detection. For example a [Mod-Tap](mod_tap) key such as `LCTL_T(KC_A)` is 16-bit and should be masked for the 8-bit `KC_A`.
|
||||||
|
:::
|
||||||
|
|
||||||
The default user callback function is found inside `quantum/process_keycode/process_autocorrect.c`. It covers most use-cases for QMK special functions and quantum keycodes, including [overriding autocorrect](#overriding-autocorrect) with a modifier other than shift. The `process_autocorrect_user` function is `weak` defined to allow user's copy inside `keymap.c` (or code files) to overwrite it.
|
The default user callback function is found inside `quantum/process_keycode/process_autocorrect.c`. It covers most use-cases for QMK special functions and quantum keycodes, including [overriding autocorrect](#overriding-autocorrect) with a modifier other than shift. The `process_autocorrect_user` function is `weak` defined to allow user's copy inside `keymap.c` (or code files) to overwrite it.
|
||||||
|
|
||||||
|
@ -145,11 +149,11 @@ bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *t
|
||||||
// Exclude tap-hold keys when they are held down
|
// Exclude tap-hold keys when they are held down
|
||||||
// and mask for base keycode when they are tapped.
|
// and mask for base keycode when they are tapped.
|
||||||
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
|
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
|
||||||
# ifdef NO_ACTION_LAYER
|
# ifdef NO_ACTION_LAYER
|
||||||
// Exclude Layer Tap, if layers are disabled
|
// Exclude Layer Tap, if layers are disabled
|
||||||
// but action tapping is still enabled.
|
// but action tapping is still enabled.
|
||||||
return false;
|
return false;
|
||||||
# endif
|
# endif
|
||||||
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
|
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
|
||||||
// Exclude hold if mods other than Shift is not active
|
// Exclude hold if mods other than Shift is not active
|
||||||
if (!record->tap.count) {
|
if (!record->tap.count) {
|
||||||
|
@ -194,13 +198,17 @@ bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *t
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
?> In this callback function, `return false` will skip processing of that keycode for autocorrect. Adding `*typo_buffer_size = 0` will also reset the autocorrect buffer at the same time, cancelling any current letters already stored in the buffer.
|
::: tip
|
||||||
|
In this callback function, `return false` will skip processing of that keycode for autocorrect. Adding `*typo_buffer_size = 0` will also reset the autocorrect buffer at the same time, cancelling any current letters already stored in the buffer.
|
||||||
|
:::
|
||||||
|
|
||||||
### Apply Autocorrect
|
### Apply Autocorrect
|
||||||
|
|
||||||
Additionally, `apply_autocorrect(uint8_t backspaces, const char *str, char *typo, char *correct)` allows for users to add additional handling to the autocorrection, or replace the functionality entirely. This passes on the number of backspaces needed to replace the words, as well as the replacement string (partial word, not the full word), and the typo and corrected strings (complete words).
|
Additionally, `apply_autocorrect(uint8_t backspaces, const char *str, char *typo, char *correct)` allows for users to add additional handling to the autocorrection, or replace the functionality entirely. This passes on the number of backspaces needed to replace the words, as well as the replacement string (partial word, not the full word), and the typo and corrected strings (complete words).
|
||||||
|
|
||||||
?> Due to the way code works (no notion of words, just a stream of letters), the `typo` and `correct` strings are a best bet and could be "wrong". For example you may get `wordtpyo` & `wordtypo` instead of the expected `tpyo` & `typo`.
|
::: tip
|
||||||
|
Due to the way code works (no notion of words, just a stream of letters), the `typo` and `correct` strings are a best bet and could be "wrong". For example you may get `wordtpyo` & `wordtypo` instead of the expected `tpyo` & `typo`.
|
||||||
|
:::
|
||||||
|
|
||||||
#### Apply Autocorrect Example
|
#### Apply Autocorrect Example
|
||||||
|
|
||||||
|
@ -223,9 +231,13 @@ bool apply_autocorrect(uint8_t backspaces, const char *str, char *typo, char *co
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
?> In this callback function, `return false` will stop the normal processing of autocorrect, which requires manually handling of removing the "bad" characters and typing the new characters.
|
::: tip
|
||||||
|
In this callback function, `return false` will stop the normal processing of autocorrect, which requires manually handling of removing the "bad" characters and typing the new characters.
|
||||||
|
:::
|
||||||
|
|
||||||
!> ***IMPORTANT***: `str` is a pointer to `PROGMEM` data for the autocorrection. If you return false, and want to send the string, this needs to use `send_string_P` and not `send_string` nor `SEND_STRING`.
|
::: warning
|
||||||
|
***IMPORTANT***: `str` is a pointer to `PROGMEM` data for the autocorrection. If you return false, and want to send the string, this needs to use `send_string_P` and not `send_string` nor `SEND_STRING`.
|
||||||
|
:::
|
||||||
|
|
||||||
You can also use `apply_autocorrect` to detect and display the event but allow internal code to execute the autocorrection with `return true`:
|
You can also use `apply_autocorrect` to detect and display the event but allow internal code to execute the autocorrection with `return true`:
|
||||||
|
|
||||||
|
@ -253,13 +265,13 @@ Additional user callback functions to manipulate Autocorrect:
|
||||||
| `autocorrect_is_enabled()` | Returns true if Autocorrect is currently on. |
|
| `autocorrect_is_enabled()` | Returns true if Autocorrect is currently on. |
|
||||||
|
|
||||||
|
|
||||||
## Appendix: Trie binary data format :id=appendix
|
## Appendix: Trie binary data format {#appendix}
|
||||||
|
|
||||||
This section details how the trie is serialized to byte data in autocorrect_data. You don’t need to care about this to use this autocorrection implementation. But it is documented for the record in case anyone is interested in modifying the implementation, or just curious how it works.
|
This section details how the trie is serialized to byte data in autocorrect_data. You don’t need to care about this to use this autocorrection implementation. But it is documented for the record in case anyone is interested in modifying the implementation, or just curious how it works.
|
||||||
|
|
||||||
What I did here is fairly arbitrary, but it is simple to decode and gets the job done.
|
What I did here is fairly arbitrary, but it is simple to decode and gets the job done.
|
||||||
|
|
||||||
### Encoding :id=encoding
|
### Encoding {#encoding}
|
||||||
|
|
||||||
All autocorrection data is stored in a single flat array autocorrect_data. Each trie node is associated with a byte offset into this array, where data for that node is encoded, beginning with root at offset 0. There are three kinds of nodes. The highest two bits of the first byte of the node indicate what kind:
|
All autocorrection data is stored in a single flat array autocorrect_data. Each trie node is associated with a byte offset into this array, where data for that node is encoded, beginning with root at offset 0. There are three kinds of nodes. The highest two bits of the first byte of the node indicate what kind:
|
||||||
|
|
||||||
|
@ -299,7 +311,7 @@ If we were to encode this chain using the same format used for branching nodes,
|
||||||
+-------+-------+-------+-------+-------+-------+
|
+-------+-------+-------+-------+-------+-------+
|
||||||
```
|
```
|
||||||
|
|
||||||
### Decoding :id=decoding
|
### Decoding {#decoding}
|
||||||
|
|
||||||
This format is by design decodable with fairly simple logic. A 16-bit variable state represents our current position in the trie, initialized with 0 to start at the root node. Then, for each keycode, test the highest two bits in the byte at state to identify the kind of node.
|
This format is by design decodable with fairly simple logic. A 16-bit variable state represents our current position in the trie, initialized with 0 to start at the root node. Then, for each keycode, test the highest two bits in the byte at state to identify the kind of node.
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Backlighting :id=backlighting
|
# Backlighting {#backlighting}
|
||||||
|
|
||||||
Many keyboards support backlit keys by way of individual LEDs placed through or underneath the keyswitches. This feature is distinct from both the [RGB Underglow](feature_rgblight.md) and [RGB Matrix](feature_rgb_matrix.md) features as it usually allows for only a single colour per switch, though you can obviously install multiple different single coloured LEDs on a keyboard.
|
Many keyboards support backlit keys by way of individual LEDs placed through or underneath the keyswitches. This feature is distinct from both the [RGB Underglow](feature_rgblight) and [RGB Matrix](feature_rgb_matrix) features as it usually allows for only a single colour per switch, though you can obviously install multiple different single coloured LEDs on a keyboard.
|
||||||
|
|
||||||
QMK is able to control the brightness of these LEDs by switching them on and off rapidly in a certain ratio, a technique known as *Pulse Width Modulation*, or PWM. By altering the duty cycle of the PWM signal, it creates the illusion of dimming.
|
QMK is able to control the brightness of these LEDs by switching them on and off rapidly in a certain ratio, a technique known as *Pulse Width Modulation*, or PWM. By altering the duty cycle of the PWM signal, it creates the illusion of dimming.
|
||||||
|
|
||||||
## Usage :id=usage
|
## Usage {#usage}
|
||||||
|
|
||||||
Most keyboards have backlighting enabled by default if they support it, but if it is not working for you (or you have added support), check that your `rules.mk` includes the following:
|
Most keyboards have backlighting enabled by default if they support it, but if it is not working for you (or you have added support), check that your `rules.mk` includes the following:
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ Most keyboards have backlighting enabled by default if they support it, but if i
|
||||||
BACKLIGHT_ENABLE = yes
|
BACKLIGHT_ENABLE = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
## Keycodes :id=keycodes
|
## Keycodes {#keycodes}
|
||||||
|
|
||||||
|Key |Aliases |Description |
|
|Key |Aliases |Description |
|
||||||
|-------------------------------|---------|-----------------------------------|
|
|-------------------------------|---------|-----------------------------------|
|
||||||
|
@ -24,7 +24,7 @@ BACKLIGHT_ENABLE = yes
|
||||||
|`QK_BACKLIGHT_DOWN` |`BL_DOWN`|Decrease the backlight level |
|
|`QK_BACKLIGHT_DOWN` |`BL_DOWN`|Decrease the backlight level |
|
||||||
|`QK_BACKLIGHT_TOGGLE_BREATHING`|`BL_BRTG`|Toggle backlight breathing |
|
|`QK_BACKLIGHT_TOGGLE_BREATHING`|`BL_BRTG`|Toggle backlight breathing |
|
||||||
|
|
||||||
## Basic Configuration :id=basic-configuration
|
## Basic Configuration {#basic-configuration}
|
||||||
|
|
||||||
Add the following to your `config.h`:
|
Add the following to your `config.h`:
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ Add the following to your `config.h`:
|
||||||
|
|
||||||
Unless you are designing your own keyboard, you generally should not need to change the `BACKLIGHT_PIN` or `BACKLIGHT_ON_STATE`.
|
Unless you are designing your own keyboard, you generally should not need to change the `BACKLIGHT_PIN` or `BACKLIGHT_ON_STATE`.
|
||||||
|
|
||||||
### "On" State :id=on-state
|
### "On" State {#on-state}
|
||||||
|
|
||||||
Most backlight circuits are driven by an N-channel MOSFET or NPN transistor. This means that to turn the transistor *on* and light the LEDs, you must drive the backlight pin, connected to the gate or base, *high*.
|
Most backlight circuits are driven by an N-channel MOSFET or NPN transistor. This means that to turn the transistor *on* and light the LEDs, you must drive the backlight pin, connected to the gate or base, *high*.
|
||||||
Sometimes, however, a P-channel MOSFET, or a PNP transistor is used. In this case, when the transistor is on, the pin is driven *low* instead.
|
Sometimes, however, a P-channel MOSFET, or a PNP transistor is used. In this case, when the transistor is on, the pin is driven *low* instead.
|
||||||
|
@ -54,7 +54,7 @@ To configure the "on" state of the backlight circuit, add the following to your
|
||||||
#define BACKLIGHT_ON_STATE 0
|
#define BACKLIGHT_ON_STATE 0
|
||||||
```
|
```
|
||||||
|
|
||||||
### Multiple Backlight Pins :id=multiple-backlight-pins
|
### Multiple Backlight Pins {#multiple-backlight-pins}
|
||||||
|
|
||||||
Most keyboards have only one backlight pin which controls all backlight LEDs (especially if the backlight is connected to a hardware PWM pin).
|
Most keyboards have only one backlight pin which controls all backlight LEDs (especially if the backlight is connected to a hardware PWM pin).
|
||||||
The `timer` and `software` drivers allow you to define multiple backlight pins, which will be turned on and off at the same time during the PWM duty cycle.
|
The `timer` and `software` drivers allow you to define multiple backlight pins, which will be turned on and off at the same time during the PWM duty cycle.
|
||||||
|
@ -67,11 +67,11 @@ To configure multiple backlight pins, add something like this to your `config.h`
|
||||||
#define BACKLIGHT_PINS { F5, B2 }
|
#define BACKLIGHT_PINS { F5, B2 }
|
||||||
```
|
```
|
||||||
|
|
||||||
## Driver Configuration :id=driver-configuration
|
## Driver Configuration {#driver-configuration}
|
||||||
|
|
||||||
Backlight driver selection is configured in `rules.mk`. Valid drivers are `pwm` (default), `timer`, `software`, or `custom`. See below for information on individual drivers.
|
Backlight driver selection is configured in `rules.mk`. Valid drivers are `pwm` (default), `timer`, `software`, or `custom`. See below for information on individual drivers.
|
||||||
|
|
||||||
### PWM Driver :id=pwm-driver
|
### PWM Driver {#pwm-driver}
|
||||||
|
|
||||||
This is the default backlight driver, which leverages the hardware PWM output capability of the microcontroller.
|
This is the default backlight driver, which leverages the hardware PWM output capability of the microcontroller.
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ This is the default backlight driver, which leverages the hardware PWM output ca
|
||||||
BACKLIGHT_DRIVER = pwm
|
BACKLIGHT_DRIVER = pwm
|
||||||
```
|
```
|
||||||
|
|
||||||
### Timer Driver :id=timer-driver
|
### Timer Driver {#timer-driver}
|
||||||
|
|
||||||
This driver is similar to the PWM driver, but instead of directly configuring the pin to output a PWM signal, an interrupt handler is attached to the timer to turn the pin on and off as appropriate.
|
This driver is similar to the PWM driver, but instead of directly configuring the pin to output a PWM signal, an interrupt handler is attached to the timer to turn the pin on and off as appropriate.
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ This driver is similar to the PWM driver, but instead of directly configuring th
|
||||||
BACKLIGHT_DRIVER = timer
|
BACKLIGHT_DRIVER = timer
|
||||||
```
|
```
|
||||||
|
|
||||||
### Software Driver :id=software-driver
|
### Software Driver {#software-driver}
|
||||||
|
|
||||||
In this mode, PWM is "emulated" while running other keyboard tasks. It offers maximum hardware compatibility without extra platform configuration. However, breathing is not supported, and the backlight can flicker when the keyboard is busy.
|
In this mode, PWM is "emulated" while running other keyboard tasks. It offers maximum hardware compatibility without extra platform configuration. However, breathing is not supported, and the backlight can flicker when the keyboard is busy.
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ In this mode, PWM is "emulated" while running other keyboard tasks. It offers ma
|
||||||
BACKLIGHT_DRIVER = software
|
BACKLIGHT_DRIVER = software
|
||||||
```
|
```
|
||||||
|
|
||||||
### Custom Driver :id=custom-driver
|
### Custom Driver {#custom-driver}
|
||||||
|
|
||||||
If none of the above drivers apply to your board (for example, you are using a separate IC to control the backlight), you can implement a custom backlight driver using a simple API.
|
If none of the above drivers apply to your board (for example, you are using a separate IC to control the backlight), you can implement a custom backlight driver using a simple API.
|
||||||
|
|
||||||
|
@ -120,9 +120,9 @@ void backlight_task(void) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## AVR Configuration :id=avr-configuration
|
## AVR Configuration {#avr-configuration}
|
||||||
|
|
||||||
### PWM Driver :id=avr-pwm-driver
|
### PWM Driver {#avr-pwm-driver}
|
||||||
|
|
||||||
The following table describes the supported pins for the PWM driver. Only cells marked with a timer number are capable of hardware PWM output; any others must use the `timer` driver.
|
The following table describes the supported pins for the PWM driver. Only cells marked with a timer number are capable of hardware PWM output; any others must use the `timer` driver.
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ The following table describes the supported pins for the PWM driver. Only cells
|
||||||
|`D4` | | | | |Timer 1 | |
|
|`D4` | | | | |Timer 1 | |
|
||||||
|`D5` | | | | |Timer 1 | |
|
|`D5` | | | | |Timer 1 | |
|
||||||
|
|
||||||
### Timer Driver :id=avr-timer-driver
|
### Timer Driver {#avr-timer-driver}
|
||||||
|
|
||||||
Any GPIO pin can be used with this driver. The following table describes the supported timers:
|
Any GPIO pin can be used with this driver. The following table describes the supported timers:
|
||||||
|
|
||||||
|
@ -153,11 +153,11 @@ The following `#define`s apply only to the `timer` driver:
|
||||||
|-----------------------|-------|----------------|
|
|-----------------------|-------|----------------|
|
||||||
|`BACKLIGHT_PWM_TIMER` |`1` |The timer to use|
|
|`BACKLIGHT_PWM_TIMER` |`1` |The timer to use|
|
||||||
|
|
||||||
Note that the choice of timer may conflict with the [Audio](feature_audio.md) feature.
|
Note that the choice of timer may conflict with the [Audio](feature_audio) feature.
|
||||||
|
|
||||||
## ChibiOS/ARM Configuration :id=arm-configuration
|
## ChibiOS/ARM Configuration {#arm-configuration}
|
||||||
|
|
||||||
### PWM Driver :id=arm-pwm-driver
|
### PWM Driver {#arm-pwm-driver}
|
||||||
|
|
||||||
Depending on the ChibiOS board configuration, you may need to enable PWM at the keyboard level. For STM32, this would look like:
|
Depending on the ChibiOS board configuration, you may need to enable PWM at the keyboard level. For STM32, this would look like:
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ The following `#define`s apply only to the `pwm` driver:
|
||||||
|
|
||||||
Refer to the ST datasheet for your particular MCU to determine these values. For example, these defaults are set up for pin `B8` on a Proton-C (STM32F303) using `TIM4_CH3` on AF2. Unless you are designing your own keyboard, you generally should not need to change them.
|
Refer to the ST datasheet for your particular MCU to determine these values. For example, these defaults are set up for pin `B8` on a Proton-C (STM32F303) using `TIM4_CH3` on AF2. Unless you are designing your own keyboard, you generally should not need to change them.
|
||||||
|
|
||||||
### Timer Driver :id=arm-timer-driver
|
### Timer Driver {#arm-timer-driver}
|
||||||
|
|
||||||
Depending on the ChibiOS board configuration, you may need to enable general-purpose timers at the keyboard level. For STM32, this would look like:
|
Depending on the ChibiOS board configuration, you may need to enable general-purpose timers at the keyboard level. For STM32, this would look like:
|
||||||
|
|
||||||
|
@ -213,97 +213,97 @@ The values of these resistors are not critical - see [this Electronics StackExch
|
||||||
|
|
||||||
![Backlight example circuit](https://i.imgur.com/BmAvoUC.png)
|
![Backlight example circuit](https://i.imgur.com/BmAvoUC.png)
|
||||||
|
|
||||||
## API :id=api
|
## API {#api}
|
||||||
|
|
||||||
### `void backlight_toggle(void)` :id=api-backlight-toggle
|
### `void backlight_toggle(void)` {#api-backlight-toggle}
|
||||||
|
|
||||||
Toggle the backlight on or off.
|
Toggle the backlight on or off.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void backlight_enable(void)` :id=api-backlight-enable
|
### `void backlight_enable(void)` {#api-backlight-enable}
|
||||||
|
|
||||||
Turn the backlight on.
|
Turn the backlight on.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void backlight_disable(void)` :id=api-backlight-disable
|
### `void backlight_disable(void)` {#api-backlight-disable}
|
||||||
|
|
||||||
Turn the backlight off.
|
Turn the backlight off.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void backlight_step(void)` :id=api-backlight-step
|
### `void backlight_step(void)` {#api-backlight-step}
|
||||||
|
|
||||||
Cycle through backlight levels.
|
Cycle through backlight levels.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void backlight_increase(void)` :id=api-backlight-increase
|
### `void backlight_increase(void)` {#api-backlight-increase}
|
||||||
|
|
||||||
Increase the backlight level.
|
Increase the backlight level.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void backlight_decrease(void)` :id=api-backlight-decrease
|
### `void backlight_decrease(void)` {#api-backlight-decrease}
|
||||||
|
|
||||||
Decrease the backlight level.
|
Decrease the backlight level.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void backlight_level(uint8_t level)` :id=api-backlight-level
|
### `void backlight_level(uint8_t level)` {#api-backlight-level}
|
||||||
|
|
||||||
Set the backlight level.
|
Set the backlight level.
|
||||||
|
|
||||||
#### Arguments :id=api-backlight-level-arguments
|
#### Arguments {#api-backlight-level-arguments}
|
||||||
|
|
||||||
- `uint8_t level`
|
- `uint8_t level`
|
||||||
The level to set, from 0 to `BACKLIGHT_LEVELS`.
|
The level to set, from 0 to `BACKLIGHT_LEVELS`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `uint8_t get_backlight_level(void)` :id=api-get-backlight-level
|
### `uint8_t get_backlight_level(void)` {#api-get-backlight-level}
|
||||||
|
|
||||||
Get the current backlight level.
|
Get the current backlight level.
|
||||||
|
|
||||||
#### Return Value :id=api-get-backlight-level-return
|
#### Return Value {#api-get-backlight-level-return}
|
||||||
|
|
||||||
The current backlight level, from 0 to `BACKLIGHT_LEVELS`.
|
The current backlight level, from 0 to `BACKLIGHT_LEVELS`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool is_backlight_enabled(void)` :id=api-is-backlight-enabled
|
### `bool is_backlight_enabled(void)` {#api-is-backlight-enabled}
|
||||||
|
|
||||||
Get the current backlight state.
|
Get the current backlight state.
|
||||||
|
|
||||||
#### Return Value :id=api-is-backlight-enabled-return
|
#### Return Value {#api-is-backlight-enabled-return}
|
||||||
|
|
||||||
`true` if the backlight is enabled.
|
`true` if the backlight is enabled.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void backlight_toggle_breathing(void)` :id=api-backlight-toggle-breathing
|
### `void backlight_toggle_breathing(void)` {#api-backlight-toggle-breathing}
|
||||||
|
|
||||||
Toggle backlight breathing on or off.
|
Toggle backlight breathing on or off.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void backlight_enable_breathing(void)` :id=api-backlight-enable-breathing
|
### `void backlight_enable_breathing(void)` {#api-backlight-enable-breathing}
|
||||||
|
|
||||||
Turn backlight breathing on.
|
Turn backlight breathing on.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void backlight_disable_breathing(void)` :id=api-backlight-disable-breathing
|
### `void backlight_disable_breathing(void)` {#api-backlight-disable-breathing}
|
||||||
|
|
||||||
Turn backlight breathing off.
|
Turn backlight breathing off.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool is_backlight_breathing(void)` :id=api-is-backlight-breathing
|
### `bool is_backlight_breathing(void)` {#api-is-backlight-breathing}
|
||||||
|
|
||||||
Get the current backlight breathing state.
|
Get the current backlight breathing state.
|
||||||
|
|
||||||
#### Return Value :id=api-is-backlight-breathing-return
|
#### Return Value {#api-is-backlight-breathing-return}
|
||||||
|
|
||||||
`true` if backlight breathing is enabled.
|
`true` if backlight breathing is enabled.
|
||||||
|
|
|
@ -26,7 +26,7 @@ A Bluefruit UART friend can be converted to an SPI friend, however this [require
|
||||||
<!-- FIXME: Document bluetooth support more completely. -->
|
<!-- FIXME: Document bluetooth support more completely. -->
|
||||||
## Bluetooth Rules.mk Options
|
## Bluetooth Rules.mk Options
|
||||||
|
|
||||||
The currently supported Bluetooth chipsets do not support [N-Key Rollover (NKRO)](reference_glossary.md#n-key-rollover-nkro), so `rules.mk` must contain `NKRO_ENABLE = no`.
|
The currently supported Bluetooth chipsets do not support [N-Key Rollover (NKRO)](reference_glossary#n-key-rollover-nkro), so `rules.mk` must contain `NKRO_ENABLE = no`.
|
||||||
|
|
||||||
Add the following to your `rules.mk`:
|
Add the following to your `rules.mk`:
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Bootmagic :id=bootmagic
|
# Bootmagic {#bootmagic}
|
||||||
|
|
||||||
The Bootmagic feature that only handles jumping into the bootloader. This is great for boards that don't have a physical reset button, giving you a way to jump into the bootloader
|
The Bootmagic feature that only handles jumping into the bootloader. This is great for boards that don't have a physical reset button, giving you a way to jump into the bootloader
|
||||||
|
|
||||||
|
@ -19,11 +19,13 @@ By default, these are set to 0 and 0, which is usually the "ESC" key on a majori
|
||||||
|
|
||||||
And to trigger the bootloader, you hold this key down when plugging the keyboard in. Just the single key.
|
And to trigger the bootloader, you hold this key down when plugging the keyboard in. Just the single key.
|
||||||
|
|
||||||
!> Using Bootmagic will **always reset** the EEPROM, so you will lose any settings that have been saved.
|
::: warning
|
||||||
|
Using Bootmagic will **always reset** the EEPROM, so you will lose any settings that have been saved.
|
||||||
|
:::
|
||||||
|
|
||||||
## Split Keyboards
|
## Split Keyboards
|
||||||
|
|
||||||
When [handedness](feature_split_keyboard.md#setting-handedness) is predetermined via options like `SPLIT_HAND_PIN` or `EE_HANDS`, you might need to configure a different key between halves. To identify the correct key for the right half, examine the split key matrix defined in the `<keyboard>.h` file, e.g.:
|
When [handedness](feature_split_keyboard#setting-handedness) is predetermined via options like `SPLIT_HAND_PIN` or `EE_HANDS`, you might need to configure a different key between halves. To identify the correct key for the right half, examine the split key matrix defined in the `<keyboard>.h` file, e.g.:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define LAYOUT_split_3x5_2( \
|
#define LAYOUT_split_3x5_2( \
|
||||||
|
@ -51,7 +53,9 @@ If you pick the top right key for the right half, it is `R05` on the top layout.
|
||||||
#define BOOTMAGIC_COLUMN_RIGHT 4
|
#define BOOTMAGIC_COLUMN_RIGHT 4
|
||||||
```
|
```
|
||||||
|
|
||||||
?> These values are not set by default.
|
::: tip
|
||||||
|
These values are not set by default.
|
||||||
|
:::
|
||||||
|
|
||||||
## Advanced Bootmagic
|
## Advanced Bootmagic
|
||||||
|
|
||||||
|
@ -76,6 +80,6 @@ You can define additional logic here. For instance, resetting the EEPROM or requ
|
||||||
|
|
||||||
## Addenda
|
## Addenda
|
||||||
|
|
||||||
To manipulate settings that were formerly configured through the now-deprecated full Bootmagic feature, see [Magic Keycodes](keycodes_magic.md).
|
To manipulate settings that were formerly configured through the now-deprecated full Bootmagic feature, see [Magic Keycodes](keycodes_magic).
|
||||||
|
|
||||||
The Command feature, formerly known as Magic, also allows you to control different aspects of your keyboard. While it shares some functionality with Magic Keycodes, it also allows you to do things that Magic Keycodes cannot, such as printing version information to the console. For more information, see [Command](feature_command.md).
|
The Command feature, formerly known as Magic, also allows you to control different aspects of your keyboard. While it shares some functionality with Magic Keycodes, it also allows you to do things that Magic Keycodes cannot, such as printing version information to the console. For more information, see [Command](feature_command).
|
||||||
|
|
|
@ -32,7 +32,7 @@ a modern alternative to Caps Lock:
|
||||||
shift](#configure-which-keys-are-word-breaking).
|
shift](#configure-which-keys-are-word-breaking).
|
||||||
|
|
||||||
|
|
||||||
## How do I enable Caps Word :id=how-do-i-enable-caps-word
|
## How do I enable Caps Word {#how-do-i-enable-caps-word}
|
||||||
|
|
||||||
In your `rules.mk`, add:
|
In your `rules.mk`, add:
|
||||||
|
|
||||||
|
@ -62,16 +62,16 @@ Next, use one the following methods to activate Caps Word:
|
||||||
|
|
||||||
* **Custom activation**: You can activate Caps Word from code by calling
|
* **Custom activation**: You can activate Caps Word from code by calling
|
||||||
`caps_word_on()`. This may be used to activate Caps Word through [a
|
`caps_word_on()`. This may be used to activate Caps Word through [a
|
||||||
combo](feature_combo.md) or [tap dance](feature_tap_dance.md) or any means
|
combo](feature_combo) or [tap dance](feature_tap_dance) or any means
|
||||||
you like.
|
you like.
|
||||||
|
|
||||||
### Troubleshooting: Command :id=troubleshooting-command
|
### Troubleshooting: Command {#troubleshooting-command}
|
||||||
|
|
||||||
When using `BOTH_SHIFTS_TURNS_ON_CAPS_WORD`, you might see a compile message
|
When using `BOTH_SHIFTS_TURNS_ON_CAPS_WORD`, you might see a compile message
|
||||||
**"BOTH_SHIFTS_TURNS_ON_CAPS_WORD and Command should not be enabled at the same
|
**"BOTH_SHIFTS_TURNS_ON_CAPS_WORD and Command should not be enabled at the same
|
||||||
time, since both use the Left Shift + Right Shift key combination."**
|
time, since both use the Left Shift + Right Shift key combination."**
|
||||||
|
|
||||||
Many keyboards enable the [Command feature](feature_command.md), which by
|
Many keyboards enable the [Command feature](feature_command), which by
|
||||||
default is also activated using the Left Shift + Right Shift key combination. To
|
default is also activated using the Left Shift + Right Shift key combination. To
|
||||||
fix this conflict, please disable Command by adding in rules.mk:
|
fix this conflict, please disable Command by adding in rules.mk:
|
||||||
|
|
||||||
|
@ -88,9 +88,9 @@ by defining `IS_COMMAND()` in config.h:
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Customizing Caps Word :id=customizing-caps-word
|
## Customizing Caps Word {#customizing-caps-word}
|
||||||
|
|
||||||
### Invert on shift :id=invert-on-shift
|
### Invert on shift {#invert-on-shift}
|
||||||
|
|
||||||
By default, Caps Word turns off when Shift keys are pressed, considering them as
|
By default, Caps Word turns off when Shift keys are pressed, considering them as
|
||||||
word-breaking. Alternatively with the `CAPS_WORD_INVERT_ON_SHIFT` option,
|
word-breaking. Alternatively with the `CAPS_WORD_INVERT_ON_SHIFT` option,
|
||||||
|
@ -110,7 +110,7 @@ keys, and one-shot Shift keys. Note that while Caps Word is on, one-shot Shift
|
||||||
keys behave like regular Shift keys, and have effect only while they are held.
|
keys behave like regular Shift keys, and have effect only while they are held.
|
||||||
|
|
||||||
|
|
||||||
### Idle timeout :id=idle-timeout
|
### Idle timeout {#idle-timeout}
|
||||||
|
|
||||||
Caps Word turns off automatically if no keys are pressed for
|
Caps Word turns off automatically if no keys are pressed for
|
||||||
`CAPS_WORD_IDLE_TIMEOUT` milliseconds. The default is 5000 (5 seconds).
|
`CAPS_WORD_IDLE_TIMEOUT` milliseconds. The default is 5000 (5 seconds).
|
||||||
|
@ -124,7 +124,7 @@ Setting `CAPS_WORD_IDLE_TIMEOUT` to 0 configures Caps Word to never time out.
|
||||||
Caps Word then remains active indefinitely until a word breaking key is pressed.
|
Caps Word then remains active indefinitely until a word breaking key is pressed.
|
||||||
|
|
||||||
|
|
||||||
### Functions :id=functions
|
### Functions {#functions}
|
||||||
|
|
||||||
Functions to manipulate Caps Word:
|
Functions to manipulate Caps Word:
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ Functions to manipulate Caps Word:
|
||||||
| `is_caps_word_on()` | Returns true if Caps Word is currently on. |
|
| `is_caps_word_on()` | Returns true if Caps Word is currently on. |
|
||||||
|
|
||||||
|
|
||||||
### Configure which keys are "word breaking" :id=configure-which-keys-are-word-breaking
|
### Configure which keys are "word breaking" {#configure-which-keys-are-word-breaking}
|
||||||
|
|
||||||
You can define the `caps_word_press_user(uint16_t keycode)` callback to
|
You can define the `caps_word_press_user(uint16_t keycode)` callback to
|
||||||
configure which keys should be shifted and which keys are considered "word
|
configure which keys should be shifted and which keys are considered "word
|
||||||
|
@ -171,7 +171,7 @@ bool caps_word_press_user(uint16_t keycode) {
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Representing Caps Word state :id=representing-caps-word-state
|
### Representing Caps Word state {#representing-caps-word-state}
|
||||||
|
|
||||||
Define `caps_word_set_user(bool active)` to get callbacks when Caps Word turns
|
Define `caps_word_set_user(bool active)` to get callbacks when Caps Word turns
|
||||||
on or off. This is useful to represent the current Caps Word state, e.g. by
|
on or off. This is useful to represent the current Caps Word state, e.g. by
|
||||||
|
|
|
@ -18,7 +18,7 @@ combo_t key_combos[] = {
|
||||||
This will send "Escape" if you hit the A and B keys, and Ctrl+Z when you hit the C and D keys.
|
This will send "Escape" if you hit the A and B keys, and Ctrl+Z when you hit the C and D keys.
|
||||||
|
|
||||||
## Advanced Keycodes Support
|
## Advanced Keycodes Support
|
||||||
Advanced keycodes, such as [Mod-Tap](mod_tap.md) and [Tap Dance](feature_tap_dance.md) are also supported together with combos. If you use these advanced keycodes in your keymap, you will need to place the full keycode in the combo definition, e.g.:
|
Advanced keycodes, such as [Mod-Tap](mod_tap) and [Tap Dance](feature_tap_dance) are also supported together with combos. If you use these advanced keycodes in your keymap, you will need to place the full keycode in the combo definition, e.g.:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
const uint16_t PROGMEM test_combo1[] = {LSFT_T(KC_A), LT(1, KC_B), COMBO_END};
|
const uint16_t PROGMEM test_combo1[] = {LSFT_T(KC_A), LT(1, KC_B), COMBO_END};
|
||||||
|
@ -99,7 +99,7 @@ void process_combo_event(uint16_t combo_index, bool pressed) {
|
||||||
|
|
||||||
This will send "john.doe@example.com" if you chord E and M together, and clear the current line with Backspace and Left-Shift. You could change this to do stuff like play sounds or change settings.
|
This will send "john.doe@example.com" if you chord E and M together, and clear the current line with Backspace and Left-Shift. You could change this to do stuff like play sounds or change settings.
|
||||||
|
|
||||||
It is worth noting that `COMBO_ACTION`s are not needed anymore. As of [PR#8591](https://github.com/qmk/qmk_firmware/pull/8591/), it is possible to run your own custom keycodes from combos. Just define the custom keycode, program its functionality in `process_record_user`, and define a combo with `COMBO(<key_array>, <your_custom_keycode>)`. See the first example in [Macros](feature_macros.md).
|
It is worth noting that `COMBO_ACTION`s are not needed anymore. As of [PR#8591](https://github.com/qmk/qmk_firmware/pull/8591/), it is possible to run your own custom keycodes from combos. Just define the custom keycode, program its functionality in `process_record_user`, and define a combo with `COMBO(<key_array>, <your_custom_keycode>)`. See the first example in [Macros](feature_macros).
|
||||||
|
|
||||||
## Keycodes
|
## Keycodes
|
||||||
You can enable, disable and toggle the Combo feature on the fly. This is useful if you need to disable them temporarily, such as for a game. The following keycodes are available for use in your `keymap.c`
|
You can enable, disable and toggle the Combo feature on the fly. This is useful if you need to disable them temporarily, such as for a game. The following keycodes are available for use in your `keymap.c`
|
||||||
|
@ -373,7 +373,9 @@ In addition to the keycodes, there are a few functions that you can use to set t
|
||||||
Having 3 places to update when adding new combos or altering old ones does become cumbersome when you have a lot of combos. We can alleviate this with some magic! ... If you consider C macros magic.
|
Having 3 places to update when adding new combos or altering old ones does become cumbersome when you have a lot of combos. We can alleviate this with some magic! ... If you consider C macros magic.
|
||||||
First, you need to add `VPATH += keyboards/gboards` to your `rules.mk`. Next, include the file `g/keymap_combo.h` in your `keymap.c`.
|
First, you need to add `VPATH += keyboards/gboards` to your `rules.mk`. Next, include the file `g/keymap_combo.h` in your `keymap.c`.
|
||||||
|
|
||||||
!> This functionality uses the same `process_combo_event` function as `COMBO_ACTION` macros do, so you cannot use the function yourself in your keymap. Instead, you have to define the `case`s of the `switch` statement by themselves within `inject.h`, which `g/keymap_combo.h` will then include into the function.
|
::: warning
|
||||||
|
This functionality uses the same `process_combo_event` function as `COMBO_ACTION` macros do, so you cannot use the function yourself in your keymap. Instead, you have to define the `case`s of the `switch` statement by themselves within `inject.h`, which `g/keymap_combo.h` will then include into the function.
|
||||||
|
:::
|
||||||
|
|
||||||
Then, write your combos in `combos.def` file in the following manner:
|
Then, write your combos in `combos.def` file in the following manner:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Command
|
# Command
|
||||||
|
|
||||||
Command, formerly known as Magic, is a way to change your keyboard's behavior without having to flash or unplug it to use [Bootmagic Lite](feature_bootmagic.md). There is a lot of overlap between this functionality and the [Magic Keycodes](keycodes_magic.md). Wherever possible we encourage you to use that feature instead of Command.
|
Command, formerly known as Magic, is a way to change your keyboard's behavior without having to flash or unplug it to use [Bootmagic Lite](feature_bootmagic). There is a lot of overlap between this functionality and the [Magic Keycodes](keycodes_magic). Wherever possible we encourage you to use that feature instead of Command.
|
||||||
|
|
||||||
On some keyboards Command is disabled by default. If this is the case, it must be explicitly enabled in your `rules.mk`:
|
On some keyboards Command is disabled by default. If this is the case, it must be explicitly enabled in your `rules.mk`:
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,9 @@ qmk flash -c -kb keebio/bdn9/rev1 -km default -e CONVERT_TO=proton_c
|
||||||
|
|
||||||
You can also add the same `CONVERT_TO=<target>` to your keymap's `rules.mk`, which will accomplish the same thing.
|
You can also add the same `CONVERT_TO=<target>` to your keymap's `rules.mk`, which will accomplish the same thing.
|
||||||
|
|
||||||
?> If you get errors about `PORTB/DDRB`, etc not being defined, you'll need to convert the keyboard's code to use the [GPIO Controls](gpio_control.md) that will work for both ARM and AVR. This shouldn't affect the AVR builds at all.
|
::: tip
|
||||||
|
If you get errors about `PORTB/DDRB`, etc not being defined, you'll need to convert the keyboard's code to use the [GPIO Controls](gpio_control) that will work for both ARM and AVR. This shouldn't affect the AVR builds at all.
|
||||||
|
:::
|
||||||
|
|
||||||
### Conditional Configuration
|
### Conditional Configuration
|
||||||
|
|
||||||
|
@ -104,7 +106,7 @@ Converter summary:
|
||||||
| `imera` | `-e CONVERT_TO=imera` | `CONVERT_TO=imera` | `#ifdef CONVERT_TO_IMERA` |
|
| `imera` | `-e CONVERT_TO=imera` | `CONVERT_TO=imera` | `#ifdef CONVERT_TO_IMERA` |
|
||||||
| `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` |
|
| `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` |
|
||||||
|
|
||||||
### Proton C :id=proton_c
|
### Proton C {#proton_c}
|
||||||
|
|
||||||
The Proton C only has one on-board LED (C13), and by default, the TXLED (D5) is mapped to it. If you want the RXLED (B0) mapped to it instead, add this line to your `config.h`:
|
The Proton C only has one on-board LED (C13), and by default, the TXLED (D5) is mapped to it. If you want the RXLED (B0) mapped to it instead, add this line to your `config.h`:
|
||||||
|
|
||||||
|
@ -116,28 +118,28 @@ The following defaults are based on what has been implemented for STM32 boards.
|
||||||
|
|
||||||
| Feature | Notes |
|
| Feature | Notes |
|
||||||
|----------------------------------------------|------------------------------------------------------------------------------------------------------------------|
|
|----------------------------------------------|------------------------------------------------------------------------------------------------------------------|
|
||||||
| [Audio](feature_audio.md) | Enabled |
|
| [Audio](feature_audio) | Enabled |
|
||||||
| [RGB Lighting](feature_rgblight.md) | Disabled |
|
| [RGB Lighting](feature_rgblight) | Disabled |
|
||||||
| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
|
| [Backlight](feature_backlight) | Forces [task driven PWM](feature_backlight#software-pwm-driver) until ARM can provide automatic configuration |
|
||||||
| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
|
| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
|
||||||
| [Split keyboards](feature_split_keyboard.md) | Partial - heavily dependent on enabled features |
|
| [Split keyboards](feature_split_keyboard) | Partial - heavily dependent on enabled features |
|
||||||
|
|
||||||
### Adafruit KB2040 :id=kb2040
|
### Adafruit KB2040 {#kb2040}
|
||||||
|
|
||||||
The following defaults are based on what has been implemented for [RP2040](platformdev_rp2040.md) boards.
|
The following defaults are based on what has been implemented for [RP2040](platformdev_rp2040) boards.
|
||||||
|
|
||||||
| Feature | Notes |
|
| Feature | Notes |
|
||||||
|----------------------------------------------|------------------------------------------------------------------------------------------------------------------|
|
|----------------------------------------------|------------------------------------------------------------------------------------------------------------------|
|
||||||
| [RGB Lighting](feature_rgblight.md) | Enabled via `PIO` vendor driver |
|
| [RGB Lighting](feature_rgblight) | Enabled via `PIO` vendor driver |
|
||||||
| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
|
| [Backlight](feature_backlight) | Forces [task driven PWM](feature_backlight#software-pwm-driver) until ARM can provide automatic configuration |
|
||||||
| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
|
| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
|
||||||
| [Split keyboards](feature_split_keyboard.md) | Partial via `PIO` vendor driver - heavily dependent on enabled features |
|
| [Split keyboards](feature_split_keyboard) | Partial via `PIO` vendor driver - heavily dependent on enabled features |
|
||||||
|
|
||||||
### SparkFun Pro Micro - RP2040, Blok, Bit-C PRO and Michi :id=promicro_rp2040
|
### SparkFun Pro Micro - RP2040, Blok, Bit-C PRO and Michi {#promicro_rp2040 }
|
||||||
|
|
||||||
Feature set is identical to [Adafruit KB2040](#kb2040).
|
Feature set is identical to [Adafruit KB2040](#kb2040).
|
||||||
|
|
||||||
### STeMCell :id=stemcell
|
### STeMCell {#stemcell}
|
||||||
|
|
||||||
Feature set currently identical to [Proton C](#proton_c).
|
Feature set currently identical to [Proton C](#proton_c).
|
||||||
There are two versions of STeMCell available, with different pinouts:
|
There are two versions of STeMCell available, with different pinouts:
|
||||||
|
@ -154,7 +156,7 @@ STeMCell has support to swap UART and I2C pins to enable single-wire uart commun
|
||||||
| D1 | -e STMC_IS=yes|
|
| D1 | -e STMC_IS=yes|
|
||||||
| D0 | Not needed |
|
| D0 | Not needed |
|
||||||
|
|
||||||
### Bonsai C4 :id=bonsai_c4
|
### Bonsai C4 {#bonsai_c4}
|
||||||
|
|
||||||
The Bonsai C4 only has one on-board LED (B2), and by default, both the Pro Micro TXLED (D5) and RXLED (B0) are mapped to it. If you want only one of them mapped, you can undefine one and redefine it to another pin by adding these line to your `config.h`:
|
The Bonsai C4 only has one on-board LED (B2), and by default, both the Pro Micro TXLED (D5) and RXLED (B0) are mapped to it. If you want only one of them mapped, you can undefine one and redefine it to another pin by adding these line to your `config.h`:
|
||||||
|
|
||||||
|
@ -164,9 +166,9 @@ The Bonsai C4 only has one on-board LED (B2), and by default, both the Pro Micro
|
||||||
#define B0 PAL_LINE(GPIOA, 9)
|
#define B0 PAL_LINE(GPIOA, 9)
|
||||||
```
|
```
|
||||||
|
|
||||||
### RP2040 Community Edition - Elite-Pi, Helios, and Liatris :id=rp2040_ce
|
### RP2040 Community Edition - Elite-Pi, Helios, and Liatris {#rp2040_ce}
|
||||||
|
|
||||||
Feature set is identical to [Adafruit KB2040](#kb2040). VBUS detection is enabled by default for superior split keyboard support. For more information, refer to the [Community Edition pinout](platformdev_rp2040.md#rp2040_ce) docs.
|
Feature set is identical to [Adafruit KB2040](#kb2040). VBUS detection is enabled by default for superior split keyboard support. For more information, refer to the [Community Edition pinout](platformdev_rp2040#rp2040_ce) docs.
|
||||||
|
|
||||||
|
|
||||||
## Elite-C
|
## Elite-C
|
||||||
|
@ -190,10 +192,10 @@ Converter summary:
|
||||||
| `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` |
|
| `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` |
|
||||||
| `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` |
|
| `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` |
|
||||||
|
|
||||||
### STeMCell :id=stemcell_elite
|
### STeMCell {#stemcell}_elite
|
||||||
|
|
||||||
Identical to [Pro Micro - STeMCell](#stemcell) with support for the additional bottom row of pins.
|
Identical to [Pro Micro - STeMCell](#stemcell) with support for the additional bottom row of pins.
|
||||||
|
|
||||||
### RP2040 Community Edition :id=rp2040_ce_elite
|
### RP2040 Community Edition {#rp2040_ce_elite}
|
||||||
|
|
||||||
Identical to [Pro Micro - RP2040 Community Edition](#rp2040_ce) with support for the additional bottom row of pins.
|
Identical to [Pro Micro - RP2040 Community Edition](#rp2040_ce) with support for the additional bottom row of pins.
|
||||||
|
|
|
@ -99,7 +99,9 @@ Default debounce time is 5 milliseconds and it can be changed with the following
|
||||||
```
|
```
|
||||||
#define DEBOUNCE 10
|
#define DEBOUNCE 10
|
||||||
```
|
```
|
||||||
?> Setting `DEBOUNCE` to `0` will disable this feature.
|
::: tip
|
||||||
|
Setting `DEBOUNCE` to `0` will disable this feature.
|
||||||
|
:::
|
||||||
|
|
||||||
### Debounce Method
|
### Debounce Method
|
||||||
|
|
||||||
|
@ -118,9 +120,13 @@ Name of algorithm is one of:
|
||||||
| `sym_eager_pk` | Debouncing per key. On any state change, response is immediate, followed by `DEBOUNCE` milliseconds of no further input for that key. |
|
| `sym_eager_pk` | Debouncing per key. On any state change, response is immediate, followed by `DEBOUNCE` milliseconds of no further input for that key. |
|
||||||
| `asym_eager_defer_pk` | Debouncing per key. On a key-down state change, response is immediate, followed by `DEBOUNCE` milliseconds of no further input for that key. On a key-up state change, a per-key timer is set. When `DEBOUNCE` milliseconds of no changes have occurred on that key, the key-up status change is pushed. |
|
| `asym_eager_defer_pk` | Debouncing per key. On a key-down state change, response is immediate, followed by `DEBOUNCE` milliseconds of no further input for that key. On a key-up state change, a per-key timer is set. When `DEBOUNCE` milliseconds of no changes have occurred on that key, the key-up status change is pushed. |
|
||||||
|
|
||||||
?> `sym_defer_g` is the default if `DEBOUNCE_TYPE` is undefined.
|
::: tip
|
||||||
|
`sym_defer_g` is the default if `DEBOUNCE_TYPE` is undefined.
|
||||||
|
:::
|
||||||
|
|
||||||
?> `sym_eager_pr` is suitable for use in keyboards where refreshing `NUM_KEYS` 8-bit counters is computationally expensive or has low scan rate while fingers usually hit one row at a time. This could be appropriate for the ErgoDox models where the matrix is rotated 90°. Hence its "rows" are really columns and each finger only hits a single "row" at a time with normal usage.
|
::: tip
|
||||||
|
`sym_eager_pr` is suitable for use in keyboards where refreshing `NUM_KEYS` 8-bit counters is computationally expensive or has low scan rate while fingers usually hit one row at a time. This could be appropriate for the ErgoDox models where the matrix is rotated 90°. Hence its "rows" are really columns and each finger only hits a single "row" at a time with normal usage.
|
||||||
|
:::
|
||||||
|
|
||||||
### Implementing your own debouncing code
|
### Implementing your own debouncing code
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Digitizer :id=digitizer
|
# Digitizer {#digitizer}
|
||||||
|
|
||||||
Digitizers allow the mouse cursor to be placed at absolute coordinates, unlike the [Pointing Device](feature_pointing_device.md) feature which applies relative displacements.
|
Digitizers allow the mouse cursor to be placed at absolute coordinates, unlike the [Pointing Device](feature_pointing_device) feature which applies relative displacements.
|
||||||
|
|
||||||
This feature implements a stylus device with a tip switch and barrel switch (generally equivalent to the primary and secondary mouse buttons respectively). Tip pressure is not currently implemented.
|
This feature implements a stylus device with a tip switch and barrel switch (generally equivalent to the primary and secondary mouse buttons respectively). Tip pressure is not currently implemented.
|
||||||
|
|
||||||
## Usage :id=usage
|
## Usage {#usage}
|
||||||
|
|
||||||
Add the following to your `rules.mk`:
|
Add the following to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -12,13 +12,15 @@ Add the following to your `rules.mk`:
|
||||||
DIGITIZER_ENABLE = yes
|
DIGITIZER_ENABLE = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
## Positioning :id=positioning
|
## Positioning {#positioning}
|
||||||
|
|
||||||
The X and Y coordinates are normalized, meaning their value must be set between 0 and 1. For the X component, the value `0` is the leftmost position, whereas the value `1` is the rightmost position. Similarly for the Y component, `0` is at the top and `1` at the bottom.
|
The X and Y coordinates are normalized, meaning their value must be set between 0 and 1. For the X component, the value `0` is the leftmost position, whereas the value `1` is the rightmost position. Similarly for the Y component, `0` is at the top and `1` at the bottom.
|
||||||
|
|
||||||
?> Since there is no display attached, the OS will likely map these coordinates to the virtual desktop. This may be important to know if you have multiple monitors.
|
::: tip
|
||||||
|
Since there is no display attached, the OS will likely map these coordinates to the virtual desktop. This may be important to know if you have multiple monitors.
|
||||||
|
:::
|
||||||
|
|
||||||
## Examples :id=examples
|
## Examples {#examples}
|
||||||
|
|
||||||
This example simply places the cursor in the middle of the screen:
|
This example simply places the cursor in the middle of the screen:
|
||||||
|
|
||||||
|
@ -40,13 +42,13 @@ digitizer_flush();
|
||||||
`digitizer_state` is a struct of type `digitizer_t`.
|
`digitizer_state` is a struct of type `digitizer_t`.
|
||||||
|
|
||||||
|
|
||||||
## API :id=api
|
## API {#api}
|
||||||
|
|
||||||
### `struct digitizer_t` :id=api-digitizer-t
|
### `struct digitizer_t` {#api-digitizer-t}
|
||||||
|
|
||||||
Contains the state of the digitizer.
|
Contains the state of the digitizer.
|
||||||
|
|
||||||
#### Members :id=api-digitizer-t-members
|
#### Members {#api-digitizer-t-members}
|
||||||
|
|
||||||
- `bool in_range`
|
- `bool in_range`
|
||||||
Indicates to the host that the contact is within range (ie. close to or in contact with the digitizer surface).
|
Indicates to the host that the contact is within range (ie. close to or in contact with the digitizer surface).
|
||||||
|
@ -63,7 +65,7 @@ Contains the state of the digitizer.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void digitizer_flush(void)` :id=api-digitizer-flush
|
### `void digitizer_flush(void)` {#api-digitizer-flush}
|
||||||
|
|
||||||
Send the digitizer report to the host if it is marked as dirty.
|
Send the digitizer report to the host if it is marked as dirty.
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ Deassert the barrel switch, and flush the report.
|
||||||
|
|
||||||
Set the absolute X and Y position of the digitizer contact, and flush the report.
|
Set the absolute X and Y position of the digitizer contact, and flush the report.
|
||||||
|
|
||||||
#### Arguments :id=api-digitizer-set-position-arguments
|
#### Arguments {#api-digitizer-set-position-arguments}
|
||||||
|
|
||||||
- `float x`
|
- `float x`
|
||||||
The X value of the contact position, from 0 to 1.
|
The X value of the contact position, from 0 to 1.
|
||||||
|
|
|
@ -20,7 +20,7 @@ or
|
||||||
#define DIP_SWITCH_MATRIX_GRID { {0,6}, {1,6}, {2,6} } // List of row and col pairs
|
#define DIP_SWITCH_MATRIX_GRID { {0,6}, {1,6}, {2,6} } // List of row and col pairs
|
||||||
```
|
```
|
||||||
|
|
||||||
## DIP Switch map :id=dip-switch-map
|
## DIP Switch map {#dip-switch-map}
|
||||||
|
|
||||||
DIP Switch mapping may be added to your `keymap.c`, which replicates the normal keyswitch functionality, but with dip switches. Add this to your keymap's `rules.mk`:
|
DIP Switch mapping may be added to your `keymap.c`, which replicates the normal keyswitch functionality, but with dip switches. Add this to your keymap's `rules.mk`:
|
||||||
|
|
||||||
|
@ -39,7 +39,9 @@ const uint16_t PROGMEM dip_switch_map[NUM_DIP_SWITCHES][NUM_DIP_STATES] = {
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
?> This should only be enabled at the keymap level.
|
::: tip
|
||||||
|
This should only be enabled at the keymap level.
|
||||||
|
:::
|
||||||
|
|
||||||
## Callbacks
|
## Callbacks
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,9 @@ To replay the macro, press either `DM_PLY1` or `DM_PLY2`.
|
||||||
|
|
||||||
It is possible to replay a macro as part of a macro. It's ok to replay macro 2 while recording macro 1 and vice versa but never create recursive macros i.e. macro 1 that replays macro 1. If you do so and the keyboard will get unresponsive, unplug the keyboard and plug it again. You can disable this completely by defining `DYNAMIC_MACRO_NO_NESTING` in your `config.h` file.
|
It is possible to replay a macro as part of a macro. It's ok to replay macro 2 while recording macro 1 and vice versa but never create recursive macros i.e. macro 1 that replays macro 1. If you do so and the keyboard will get unresponsive, unplug the keyboard and plug it again. You can disable this completely by defining `DYNAMIC_MACRO_NO_NESTING` in your `config.h` file.
|
||||||
|
|
||||||
?> For the details about the internals of the dynamic macros, please read the comments in the `process_dynamic_macro.h` and `process_dynamic_macro.c` files.
|
::: tip
|
||||||
|
For the details about the internals of the dynamic macros, please read the comments in the `process_dynamic_macro.h` and `process_dynamic_macro.c` files.
|
||||||
|
:::
|
||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EE_CLR` keycode or [Bootmagic Lite](feature_bootmagic.md) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued.
|
And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EE_CLR` keycode or [Bootmagic Lite](feature_bootmagic) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void eeconfig_init_user(void) { // EEPROM is getting reset!
|
void eeconfig_init_user(void) { // EEPROM is getting reset!
|
||||||
|
|
|
@ -67,9 +67,11 @@ Additionally, if one side does not have an encoder, you can specify `{}` for the
|
||||||
#define ENCODER_RESOLUTIONS_RIGHT { 4 }
|
#define ENCODER_RESOLUTIONS_RIGHT { 4 }
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Keep in mind that whenver you change the encoder resolution, you will need to reflash the half that has the encoder affected by the change.
|
::: warning
|
||||||
|
Keep in mind that whenver you change the encoder resolution, you will need to reflash the half that has the encoder affected by the change.
|
||||||
|
:::
|
||||||
|
|
||||||
## Encoder map :id=encoder-map
|
## Encoder map {#encoder-map}
|
||||||
|
|
||||||
Encoder mapping may be added to your `keymap.c`, which replicates the normal keyswitch layer handling functionality, but with encoders. Add this to your keymap's `rules.mk`:
|
Encoder mapping may be added to your `keymap.c`, which replicates the normal keyswitch layer handling functionality, but with encoders. Add this to your keymap's `rules.mk`:
|
||||||
|
|
||||||
|
@ -90,7 +92,9 @@ const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
?> This should only be enabled at the keymap level.
|
::: tip
|
||||||
|
This should only be enabled at the keymap level.
|
||||||
|
:::
|
||||||
|
|
||||||
Using encoder mapping pumps events through the normal QMK keycode processing pipeline, resulting in a _keydown/keyup_ combination pushed through `process_record_xxxxx()`. To configure the amount of time between the encoder "keyup" and "keydown", you can add the following to your `config.h`:
|
Using encoder mapping pumps events through the normal QMK keycode processing pipeline, resulting in a _keydown/keyup_ combination pushed through `process_record_xxxxx()`. To configure the amount of time between the encoder "keyup" and "keydown", you can add the following to your `config.h`:
|
||||||
|
|
||||||
|
@ -98,11 +102,15 @@ Using encoder mapping pumps events through the normal QMK keycode processing pip
|
||||||
#define ENCODER_MAP_KEY_DELAY 10
|
#define ENCODER_MAP_KEY_DELAY 10
|
||||||
```
|
```
|
||||||
|
|
||||||
?> By default, the encoder map delay matches the value of `TAP_CODE_DELAY`.
|
::: tip
|
||||||
|
By default, the encoder map delay matches the value of `TAP_CODE_DELAY`.
|
||||||
|
:::
|
||||||
|
|
||||||
## Callbacks
|
## Callbacks
|
||||||
|
|
||||||
?> [**Default Behaviour**](https://github.com/qmk/qmk_firmware/blob/master/quantum/encoder.c#L79-#L98): all encoders installed will function as volume up (`KC_VOLU`) on clockwise rotation and volume down (`KC_VOLD`) on counter-clockwise rotation. If you do not wish to override this, no further configuration is necessary.
|
::: tip
|
||||||
|
[**Default Behaviour**](https://github.com/qmk/qmk_firmware/blob/master/quantum/encoder.c#L79-): all encoders installed will function as volume up (`KC_VOLU`) on clockwise rotation and volume down (`KC_VOLD`) on counter-clockwise rotation. If you do not wish to override this, no further configuration is necessary.
|
||||||
|
:::
|
||||||
|
|
||||||
If you would like the alter the default behaviour, and are not using `ENCODER_MAP_ENABLE = yes`, the callback functions can be inserted into your `<keyboard>.c`:
|
If you would like the alter the default behaviour, and are not using `ENCODER_MAP_ENABLE = yes`, the callback functions can be inserted into your `<keyboard>.c`:
|
||||||
|
|
||||||
|
@ -149,7 +157,9 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
!> If you return `true` in the keymap level `_user` function, it will allow the keyboard/core level encoder code to run on top of your own. Returning `false` will override the keyboard level function, if setup correctly. This is generally the safest option to avoid confusion.
|
::: warning
|
||||||
|
If you return `true` in the keymap level `_user` function, it will allow the keyboard/core level encoder code to run on top of your own. Returning `false` will override the keyboard level function, if setup correctly. This is generally the safest option to avoid confusion.
|
||||||
|
:::
|
||||||
|
|
||||||
## Hardware
|
## Hardware
|
||||||
|
|
||||||
|
|
|
@ -192,11 +192,11 @@ The Haptic Exclusion is implemented as `__attribute__((weak)) bool get_haptic_en
|
||||||
With the entry of `#define NO_HAPTIC_MOD` in config.h, the following keys will not trigger feedback:
|
With the entry of `#define NO_HAPTIC_MOD` in config.h, the following keys will not trigger feedback:
|
||||||
|
|
||||||
* Usual modifier keys such as Control/Shift/Alt/Gui (For example `KC_LCTL`)
|
* Usual modifier keys such as Control/Shift/Alt/Gui (For example `KC_LCTL`)
|
||||||
* `MO()` momentary keys. See also [Layers](feature_layers.md).
|
* `MO()` momentary keys. See also [Layers](feature_layers).
|
||||||
* `LM()` momentary keys with mod active.
|
* `LM()` momentary keys with mod active.
|
||||||
* `LT()` layer tap keys, when held to activate a layer. However when tapped, and the key is quickly released, and sends a keycode, haptic feedback is still triggered.
|
* `LT()` layer tap keys, when held to activate a layer. However when tapped, and the key is quickly released, and sends a keycode, haptic feedback is still triggered.
|
||||||
* `TT()` layer tap toggle keys, when held to activate a layer. However when tapped `TAPPING_TOGGLE` times to permanently toggle the layer, on the last tap haptic feedback is still triggered.
|
* `TT()` layer tap toggle keys, when held to activate a layer. However when tapped `TAPPING_TOGGLE` times to permanently toggle the layer, on the last tap haptic feedback is still triggered.
|
||||||
* `MT()` mod tap keys, when held to keep a usual modifier key pressed. However when tapped, and the key is quickly released, and sends a keycode, haptic feedback is still triggered. See also [Mod-Tap](mod_tap.md).
|
* `MT()` mod tap keys, when held to keep a usual modifier key pressed. However when tapped, and the key is quickly released, and sends a keycode, haptic feedback is still triggered. See also [Mod-Tap](mod_tap).
|
||||||
|
|
||||||
### NO_HAPTIC_ALPHA
|
### NO_HAPTIC_ALPHA
|
||||||
With the entry of `#define NO_HAPTIC_ALPHA` in config.h, none of the alpha keys (A ... Z) will trigger a feedback.
|
With the entry of `#define NO_HAPTIC_ALPHA` in config.h, none of the alpha keys (A ... Z) will trigger a feedback.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# HD44780 LCD Driver :id=hd44780-lcd-driver
|
# HD44780 LCD Driver {#hd44780-lcd-driver}
|
||||||
|
|
||||||
## Supported Hardware :id=supported-hardware
|
## Supported Hardware {#supported-hardware}
|
||||||
|
|
||||||
LCD modules using [HD44780U](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) IC or equivalent, communicating in 4-bit mode.
|
LCD modules using [HD44780U](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) IC or equivalent, communicating in 4-bit mode.
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ LCD modules using [HD44780U](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
|
||||||
|
|
||||||
To run these modules at 3.3V, an additional MAX660 voltage converter IC must be soldered on, along with two 10µF capacitors. See [this page](https://www.codrey.com/electronic-circuits/hack-your-16x2-lcd/) for more details.
|
To run these modules at 3.3V, an additional MAX660 voltage converter IC must be soldered on, along with two 10µF capacitors. See [this page](https://www.codrey.com/electronic-circuits/hack-your-16x2-lcd/) for more details.
|
||||||
|
|
||||||
## Usage :id=usage
|
## Usage {#usage}
|
||||||
|
|
||||||
Add the following to your `rules.mk`:
|
Add the following to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ Add the following to your `rules.mk`:
|
||||||
HD44780_ENABLE = yes
|
HD44780_ENABLE = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
## Basic Configuration :id=basic-configuration
|
## Basic Configuration {#basic-configuration}
|
||||||
|
|
||||||
Add the following to your `config.h`:
|
Add the following to your `config.h`:
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ Add the following to your `config.h`:
|
||||||
|`HD44780_DISPLAY_LINES`|`2` |The number of visible lines on the display |
|
|`HD44780_DISPLAY_LINES`|`2` |The number of visible lines on the display |
|
||||||
|`HD44780_WRAP_LINES` |*Not defined* |If defined, input characters will wrap to the next line |
|
|`HD44780_WRAP_LINES` |*Not defined* |If defined, input characters will wrap to the next line |
|
||||||
|
|
||||||
## Examples :id=examples
|
## Examples {#examples}
|
||||||
|
|
||||||
### Hello World :id=example-hello-world
|
### Hello World {#example-hello-world}
|
||||||
|
|
||||||
Add the following to your `keymap.c`:
|
Add the following to your `keymap.c`:
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ void keyboard_post_init_user(void) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Custom Character Definition :id=example-custom-character
|
### Custom Character Definition {#example-custom-character}
|
||||||
|
|
||||||
Up to eight custom characters can be defined. This data is stored in the Character Generator RAM (CGRAM), and is not persistent across power cycles.
|
Up to eight custom characters can be defined. This data is stored in the Character Generator RAM (CGRAM), and is not persistent across power cycles.
|
||||||
|
|
||||||
|
@ -77,15 +77,15 @@ void keyboard_post_init_user(void) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## API :id=api
|
## API {#api}
|
||||||
|
|
||||||
### `void hd44780_init(bool cursor, bool blink)` :id=api-hd44780-init
|
### `void hd44780_init(bool cursor, bool blink)` {#api-hd44780-init}
|
||||||
|
|
||||||
Initialize the display.
|
Initialize the display.
|
||||||
|
|
||||||
This function should be called only once, before any of the other functions can be called.
|
This function should be called only once, before any of the other functions can be called.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-init-arguments
|
#### Arguments {#api-hd44780-init-arguments}
|
||||||
|
|
||||||
- `bool cursor`
|
- `bool cursor`
|
||||||
Whether to show the cursor.
|
Whether to show the cursor.
|
||||||
|
@ -94,7 +94,7 @@ This function should be called only once, before any of the other functions can
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_clear(void)` :id=api-hd44780-clear
|
### `void hd44780_clear(void)` {#api-hd44780-clear}
|
||||||
|
|
||||||
Clear the display.
|
Clear the display.
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ This function is called on init.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_home(void)` :id=api-hd44780-home
|
### `void hd44780_home(void)` {#api-hd44780-home}
|
||||||
|
|
||||||
Move the cursor to the home position.
|
Move the cursor to the home position.
|
||||||
|
|
||||||
|
@ -110,13 +110,13 @@ This function is called on init.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_on(bool cursor, bool blink)` :id=api-hd44780-on
|
### `void hd44780_on(bool cursor, bool blink)` {#api-hd44780-on}
|
||||||
|
|
||||||
Turn the display on, and/or set the cursor properties.
|
Turn the display on, and/or set the cursor properties.
|
||||||
|
|
||||||
This function is called on init.
|
This function is called on init.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-on-arguments
|
#### Arguments {#api-hd44780-on-arguments}
|
||||||
|
|
||||||
- `bool cursor`
|
- `bool cursor`
|
||||||
Whether to show the cursor.
|
Whether to show the cursor.
|
||||||
|
@ -125,17 +125,17 @@ This function is called on init.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_off(void)` :id=api-hd44780-off
|
### `void hd44780_off(void)` {#api-hd44780-off}
|
||||||
|
|
||||||
Turn the display off.
|
Turn the display off.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_set_cursor(uint8_t col, uint8_t line)` :id=api-hd44780-set-cursor
|
### `void hd44780_set_cursor(uint8_t col, uint8_t line)` {#api-hd44780-set-cursor}
|
||||||
|
|
||||||
Move the cursor to the specified position on the display.
|
Move the cursor to the specified position on the display.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-set-cursor-arguments
|
#### Arguments {#api-hd44780-set-cursor-arguments}
|
||||||
|
|
||||||
- `uint8_t col`
|
- `uint8_t col`
|
||||||
The column number to move to, from 0 to 15 on 16x2 displays.
|
The column number to move to, from 0 to 15 on 16x2 displays.
|
||||||
|
@ -144,48 +144,48 @@ Move the cursor to the specified position on the display.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_putc(char c)` :id=api-hd44780-putc
|
### `void hd44780_putc(char c)` {#api-hd44780-putc}
|
||||||
|
|
||||||
Print a character to the display. The newline character `\n` will move the cursor to the start of the next line.
|
Print a character to the display. The newline character `\n` will move the cursor to the start of the next line.
|
||||||
|
|
||||||
The exact character shown may depend on the ROM code of your particular display - refer to the datasheet for the full character set.
|
The exact character shown may depend on the ROM code of your particular display - refer to the datasheet for the full character set.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-putc-arguments
|
#### Arguments {#api-hd44780-putc-arguments}
|
||||||
|
|
||||||
- `char c`
|
- `char c`
|
||||||
The character to print.
|
The character to print.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_puts(const char *s)` :id=api-hd44780-puts
|
### `void hd44780_puts(const char *s)` {#api-hd44780-puts}
|
||||||
|
|
||||||
Print a string of characters to the display.
|
Print a string of characters to the display.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-puts-arguments
|
#### Arguments {#api-hd44780-puts-arguments}
|
||||||
|
|
||||||
- `const char *s`
|
- `const char *s`
|
||||||
The string to print.
|
The string to print.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_puts_P(const char *s)` :id=api-hd44780-puts-p
|
### `void hd44780_puts_P(const char *s)` {#api-hd44780-puts-p}
|
||||||
|
|
||||||
Print a string of characters from PROGMEM to the display.
|
Print a string of characters from PROGMEM to the display.
|
||||||
|
|
||||||
On ARM devices, this function is simply an alias of `hd44780_puts()`.
|
On ARM devices, this function is simply an alias of `hd44780_puts()`.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-puts-p-arguments
|
#### Arguments {#api-hd44780-puts-p-arguments}
|
||||||
|
|
||||||
- `const char *s`
|
- `const char *s`
|
||||||
The PROGMEM string to print (ie. `PSTR("Hello")`).
|
The PROGMEM string to print (ie. `PSTR("Hello")`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_define_char(uint8_t index, uint8_t *data)` :id=api-hd44780-define-char
|
### `void hd44780_define_char(uint8_t index, uint8_t *data)` {#api-hd44780-define-char}
|
||||||
|
|
||||||
Define a custom character.
|
Define a custom character.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-define-char-arguments
|
#### Arguments {#api-hd44780-define-char-arguments}
|
||||||
|
|
||||||
- `uint8_t index`
|
- `uint8_t index`
|
||||||
The index of the custom character to define, from 0 to 7.
|
The index of the custom character to define, from 0 to 7.
|
||||||
|
@ -194,13 +194,13 @@ Define a custom character.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_define_char_P(uint8_t index, const uint8_t *data)` :id=api-hd44780-define-char-p
|
### `void hd44780_define_char_P(uint8_t index, const uint8_t *data)` {#api-hd44780-define-char-p}
|
||||||
|
|
||||||
Define a custom character from PROGMEM.
|
Define a custom character from PROGMEM.
|
||||||
|
|
||||||
On ARM devices, this function is simply an alias of `hd44780_define_char()`.
|
On ARM devices, this function is simply an alias of `hd44780_define_char()`.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-define-char-p-arguments
|
#### Arguments {#api-hd44780-define-char-p-arguments}
|
||||||
|
|
||||||
- `uint8_t index`
|
- `uint8_t index`
|
||||||
The index of the custom character to define, from 0 to 7.
|
The index of the custom character to define, from 0 to 7.
|
||||||
|
@ -209,21 +209,21 @@ On ARM devices, this function is simply an alias of `hd44780_define_char()`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool hd44780_busy(void)` :id=api-hd44780-busy
|
### `bool hd44780_busy(void)` {#api-hd44780-busy}
|
||||||
|
|
||||||
Indicates whether the display is currently processing, and cannot accept instructions.
|
Indicates whether the display is currently processing, and cannot accept instructions.
|
||||||
|
|
||||||
#### Return Value :id=api-hd44780-busy-arguments
|
#### Return Value {#api-hd44780-busy-arguments}
|
||||||
|
|
||||||
`true` if the display is busy.
|
`true` if the display is busy.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_write(uint8_t data, bool isData)` :id=api-hd44780-write
|
### `void hd44780_write(uint8_t data, bool isData)` {#api-hd44780-write}
|
||||||
|
|
||||||
Write a byte to the display.
|
Write a byte to the display.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-write-arguments
|
#### Arguments {#api-hd44780-write-arguments}
|
||||||
|
|
||||||
- `uint8_t data`
|
- `uint8_t data`
|
||||||
The byte to send to the display.
|
The byte to send to the display.
|
||||||
|
@ -232,67 +232,67 @@ Write a byte to the display.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `uint8_t hd44780_read(bool isData)` :id=api-hd44780-read
|
### `uint8_t hd44780_read(bool isData)` {#api-hd44780-read}
|
||||||
|
|
||||||
Read a byte from the display.
|
Read a byte from the display.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-read-arguments
|
#### Arguments {#api-hd44780-read-arguments}
|
||||||
|
|
||||||
- `bool isData`
|
- `bool isData`
|
||||||
Whether to read the current cursor position, or the character at the cursor.
|
Whether to read the current cursor position, or the character at the cursor.
|
||||||
|
|
||||||
#### Return Value :id=api-hd44780-read-return
|
#### Return Value {#api-hd44780-read-return}
|
||||||
|
|
||||||
If `isData` is `true`, the returned byte will be the character at the current DDRAM address. Otherwise, it will be the current DDRAM address and the busy flag.
|
If `isData` is `true`, the returned byte will be the character at the current DDRAM address. Otherwise, it will be the current DDRAM address and the busy flag.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_command(uint8_t command)` :id=api-hd44780-command
|
### `void hd44780_command(uint8_t command)` {#api-hd44780-command}
|
||||||
|
|
||||||
Send a command to the display. Refer to the datasheet and `hd44780.h` for the valid commands and defines.
|
Send a command to the display. Refer to the datasheet and `hd44780.h` for the valid commands and defines.
|
||||||
|
|
||||||
This function waits for the display to clear the busy flag before sending the command.
|
This function waits for the display to clear the busy flag before sending the command.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-command-arguments
|
#### Arguments {#api-hd44780-command-arguments}
|
||||||
|
|
||||||
- `uint8_t command`
|
- `uint8_t command`
|
||||||
The command to send.
|
The command to send.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_data(uint8_t data)` :id=api-hd44780-data
|
### `void hd44780_data(uint8_t data)` {#api-hd44780-data}
|
||||||
|
|
||||||
Send a byte of data to the display.
|
Send a byte of data to the display.
|
||||||
|
|
||||||
This function waits for the display to clear the busy flag before sending the data.
|
This function waits for the display to clear the busy flag before sending the data.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-data-arguments
|
#### Arguments {#api-hd44780-data-arguments}
|
||||||
|
|
||||||
- `uint8_t data`
|
- `uint8_t data`
|
||||||
The byte of data to send.
|
The byte of data to send.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_set_cgram_address(uint8_t address)` :id=api-hd44780-set-cgram-address
|
### `void hd44780_set_cgram_address(uint8_t address)` {#api-hd44780-set-cgram-address}
|
||||||
|
|
||||||
Set the CGRAM address.
|
Set the CGRAM address.
|
||||||
|
|
||||||
This function is used when defining custom characters.
|
This function is used when defining custom characters.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-set-cgram-address-arguments
|
#### Arguments {#api-hd44780-set-cgram-address-arguments}
|
||||||
|
|
||||||
- `uint8_t address`
|
- `uint8_t address`
|
||||||
The CGRAM address to move to, from `0x00` to `0x3F`.
|
The CGRAM address to move to, from `0x00` to `0x3F`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void hd44780_set_ddram_address(uint8_t address)` :id=api-hd44780-set-ddram-address
|
### `void hd44780_set_ddram_address(uint8_t address)` {#api-hd44780-set-ddram-address}
|
||||||
|
|
||||||
Set the DDRAM address.
|
Set the DDRAM address.
|
||||||
|
|
||||||
This function is used when printing characters to the display, and setting the cursor.
|
This function is used when printing characters to the display, and setting the cursor.
|
||||||
|
|
||||||
#### Arguments :id=api-hd44780-set-ddram-address-arguments
|
#### Arguments {#api-hd44780-set-ddram-address-arguments}
|
||||||
|
|
||||||
- `uint8_t address`
|
- `uint8_t address`
|
||||||
The DDRAM address to move to, from `0x00` to `0x7F`.
|
The DDRAM address to move to, from `0x00` to `0x7F`.
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Joystick :id=joystick
|
# Joystick {#joystick}
|
||||||
|
|
||||||
This feature provides game controller input as a joystick device supporting up to 6 axes and 32 buttons. Axes can be read either from an [ADC-capable input pin](adc_driver.md), or can be virtual, so that its value is provided by your code.
|
This feature provides game controller input as a joystick device supporting up to 6 axes and 32 buttons. Axes can be read either from an [ADC-capable input pin](adc_driver), or can be virtual, so that its value is provided by your code.
|
||||||
|
|
||||||
An analog device such as a [potentiometer](https://en.wikipedia.org/wiki/Potentiometer) found on an analog joystick's axes is based on a voltage divider, where adjusting the movable wiper controls the output voltage which can then be read by the microcontroller's ADC.
|
An analog device such as a [potentiometer](https://en.wikipedia.org/wiki/Potentiometer) found on an analog joystick's axes is based on a voltage divider, where adjusting the movable wiper controls the output voltage which can then be read by the microcontroller's ADC.
|
||||||
|
|
||||||
## Usage :id=usage
|
## Usage {#usage}
|
||||||
|
|
||||||
Add the following to your `rules.mk`:
|
Add the following to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ By default the joystick driver is `analog`, but you can change this with:
|
||||||
JOYSTICK_DRIVER = digital
|
JOYSTICK_DRIVER = digital
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration :id=configuration
|
## Configuration {#configuration}
|
||||||
|
|
||||||
By default, two axes and eight buttons are defined, with a reported resolution of 8 bits (-127 to +127). This can be changed in your `config.h`:
|
By default, two axes and eight buttons are defined, with a reported resolution of 8 bits (-127 to +127). This can be changed in your `config.h`:
|
||||||
|
|
||||||
|
@ -31,9 +31,11 @@ By default, two axes and eight buttons are defined, with a reported resolution o
|
||||||
#define JOYSTICK_AXIS_RESOLUTION 10
|
#define JOYSTICK_AXIS_RESOLUTION 10
|
||||||
```
|
```
|
||||||
|
|
||||||
?> You must define at least one button or axis. Also note that the maximum ADC resolution of the supported AVR MCUs is 10-bit, and 12-bit for most STM32 MCUs.
|
::: tip
|
||||||
|
You must define at least one button or axis. Also note that the maximum ADC resolution of the supported AVR MCUs is 10-bit, and 12-bit for most STM32 MCUs.
|
||||||
|
:::
|
||||||
|
|
||||||
### Axes :id=axes
|
### Axes {#axes}
|
||||||
|
|
||||||
When defining axes for your joystick, you must provide a definition array typically in your `keymap.c`.
|
When defining axes for your joystick, you must provide a definition array typically in your `keymap.c`.
|
||||||
|
|
||||||
|
@ -55,7 +57,7 @@ Axes can be configured using one of the following macros:
|
||||||
|
|
||||||
The `low` and `high` values can be swapped to effectively invert the axis.
|
The `low` and `high` values can be swapped to effectively invert the axis.
|
||||||
|
|
||||||
#### Virtual Axes :id=virtual-axes
|
#### Virtual Axes {#virtual-axes}
|
||||||
|
|
||||||
The following example adjusts two virtual axes (X and Y) based on keypad presses, with `KC_P0` as a precision modifier:
|
The following example adjusts two virtual axes (X and Y) based on keypad presses, with `KC_P0` as a precision modifier:
|
||||||
|
|
||||||
|
@ -96,7 +98,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Keycodes :id=keycodes
|
## Keycodes {#keycodes}
|
||||||
|
|
||||||
|Key |Aliases|Description|
|
|Key |Aliases|Description|
|
||||||
|-----------------------|-------|-----------|
|
|-----------------------|-------|-----------|
|
||||||
|
@ -133,13 +135,13 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|`QK_JOYSTICK_BUTTON_30`|`JS_30`|Button 30 |
|
|`QK_JOYSTICK_BUTTON_30`|`JS_30`|Button 30 |
|
||||||
|`QK_JOYSTICK_BUTTON_31`|`JS_31`|Button 31 |
|
|`QK_JOYSTICK_BUTTON_31`|`JS_31`|Button 31 |
|
||||||
|
|
||||||
## API :id=api
|
## API {#api}
|
||||||
|
|
||||||
### `struct joystick_t` :id=api-joystick-t
|
### `struct joystick_t` {#api-joystick-t}
|
||||||
|
|
||||||
Contains the state of the joystick.
|
Contains the state of the joystick.
|
||||||
|
|
||||||
#### Members :id=api-joystick-t-members
|
#### Members {#api-joystick-t-members}
|
||||||
|
|
||||||
- `uint8_t buttons[]`
|
- `uint8_t buttons[]`
|
||||||
A bit-packed array containing the joystick button states. The size is calculated as `(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1`.
|
A bit-packed array containing the joystick button states. The size is calculated as `(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1`.
|
||||||
|
@ -150,11 +152,11 @@ Contains the state of the joystick.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `struct joystick_config_t` :id=api-joystick-config-t
|
### `struct joystick_config_t` {#api-joystick-config-t}
|
||||||
|
|
||||||
Describes a single axis.
|
Describes a single axis.
|
||||||
|
|
||||||
#### Members :id=api-joystick-config-t-members
|
#### Members {#api-joystick-config-t-members}
|
||||||
|
|
||||||
- `pin_t input_pin`
|
- `pin_t input_pin`
|
||||||
The pin to read the analog value from, or `JS_VIRTUAL_AXIS`.
|
The pin to read the analog value from, or `JS_VIRTUAL_AXIS`.
|
||||||
|
@ -167,52 +169,52 @@ Describes a single axis.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void joystick_flush(void)` :id=api-joystick-flush
|
### `void joystick_flush(void)` {#api-joystick-flush}
|
||||||
|
|
||||||
Send the joystick report to the host, if it has been marked as dirty.
|
Send the joystick report to the host, if it has been marked as dirty.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void register_joystick_button(uint8_t button)` :id=api-register-joystick-button
|
### `void register_joystick_button(uint8_t button)` {#api-register-joystick-button}
|
||||||
|
|
||||||
Set the state of a button, and flush the report.
|
Set the state of a button, and flush the report.
|
||||||
|
|
||||||
#### Arguments :id=api-register-joystick-button-arguments
|
#### Arguments {#api-register-joystick-button-arguments}
|
||||||
|
|
||||||
- `uint8_t button`
|
- `uint8_t button`
|
||||||
The index of the button to press, from 0 to 31.
|
The index of the button to press, from 0 to 31.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void unregister_joystick_button(uint8_t button)` :id=api-unregister-joystick-button
|
### `void unregister_joystick_button(uint8_t button)` {#api-unregister-joystick-button}
|
||||||
|
|
||||||
Reset the state of a button, and flush the report.
|
Reset the state of a button, and flush the report.
|
||||||
|
|
||||||
#### Arguments :id=api-unregister-joystick-button-arguments
|
#### Arguments {#api-unregister-joystick-button-arguments}
|
||||||
|
|
||||||
- `uint8_t button`
|
- `uint8_t button`
|
||||||
The index of the button to release, from 0 to 31.
|
The index of the button to release, from 0 to 31.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `int16_t joystick_read_axis(uint8_t axis)` :id=api-joystick-read-axis
|
### `int16_t joystick_read_axis(uint8_t axis)` {#api-joystick-read-axis}
|
||||||
|
|
||||||
Sample and process the analog value of the given axis.
|
Sample and process the analog value of the given axis.
|
||||||
|
|
||||||
#### Arguments :id=api-joystick-read-axis-arguments
|
#### Arguments {#api-joystick-read-axis-arguments}
|
||||||
|
|
||||||
- `uint8_t axis`
|
- `uint8_t axis`
|
||||||
The axis to read.
|
The axis to read.
|
||||||
|
|
||||||
#### Return Value :id=api-joystick-read-axis-return
|
#### Return Value {#api-joystick-read-axis-return}
|
||||||
|
|
||||||
A signed 16-bit integer, where 0 is the resting or mid point.
|
A signed 16-bit integer, where 0 is the resting or mid point.
|
||||||
|
|
||||||
### `void joystick_set_axis(uint8_t axis, int16_t value)` :id=api-joystick-set-axis
|
### `void joystick_set_axis(uint8_t axis, int16_t value)` {#api-joystick-set-axis}
|
||||||
|
|
||||||
Set the value of the given axis.
|
Set the value of the given axis.
|
||||||
|
|
||||||
#### Arguments :id=api-joystick-set-axis-arguments
|
#### Arguments {#api-joystick-set-axis-arguments}
|
||||||
|
|
||||||
- `uint8_t axis`
|
- `uint8_t axis`
|
||||||
The axis to set the value of.
|
The axis to set the value of.
|
||||||
|
|
|
@ -16,8 +16,8 @@ First, enable Key Lock by setting `KEY_LOCK_ENABLE = yes` in your `rules.mk`. Th
|
||||||
|
|
||||||
## Caveats
|
## Caveats
|
||||||
|
|
||||||
Key Lock is only able to hold standard action keys and [One Shot modifier](one_shot_keys.md) keys (for example, if you have your Shift defined as `OSM(MOD_LSFT)`).
|
Key Lock is only able to hold standard action keys and [One Shot modifier](one_shot_keys) keys (for example, if you have your Shift defined as `OSM(MOD_LSFT)`).
|
||||||
This does not include any of the QMK special functions (except One Shot modifiers), or shifted versions of keys such as `KC_LPRN`. If it's in the [Basic Keycodes](keycodes_basic.md) list, it can be held.
|
This does not include any of the QMK special functions (except One Shot modifiers), or shifted versions of keys such as `KC_LPRN`. If it's in the [Basic Keycodes](keycodes_basic) list, it can be held.
|
||||||
|
|
||||||
Switching layers will not cancel the Key Lock. The Key Lock can be cancelled by calling the `cancel_key_lock()` function.
|
Switching layers will not cancel the Key Lock. The Key Lock can be cancelled by calling the `cancel_key_lock()` function.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Key Overrides :id=key-overrides
|
# Key Overrides {#key-overrides}
|
||||||
|
|
||||||
Key overrides allow you to override modifier-key combinations to send a different modifier-key combination or perform completely custom actions. Don't want `shift` + `1` to type `!` on your computer? Use a key override to make your keyboard type something different when you press `shift` + `1`. The general behavior is like this: If `modifiers w` + `key x` are pressed, replace these keys with `modifiers y` + `key z` in the keyboard report.
|
Key overrides allow you to override modifier-key combinations to send a different modifier-key combination or perform completely custom actions. Don't want `shift` + `1` to type `!` on your computer? Use a key override to make your keyboard type something different when you press `shift` + `1`. The general behavior is like this: If `modifiers w` + `key x` are pressed, replace these keys with `modifiers y` + `key z` in the keyboard report.
|
||||||
|
|
||||||
|
@ -10,13 +10,13 @@ You can use key overrides in a similar way to momentary layer/fn keys to activat
|
||||||
- Create custom shortcuts or change existing ones: E.g. Send `ctrl`+`shift`+`z` when `ctrl`+`y` is pressed.
|
- Create custom shortcuts or change existing ones: E.g. Send `ctrl`+`shift`+`z` when `ctrl`+`y` is pressed.
|
||||||
- Run custom code when `ctrl` + `alt` + `esc` is pressed.
|
- Run custom code when `ctrl` + `alt` + `esc` is pressed.
|
||||||
|
|
||||||
## Setup :id=setup
|
## Setup {#setup}
|
||||||
|
|
||||||
To enable this feature, you need to add `KEY_OVERRIDE_ENABLE = yes` to your `rules.mk`.
|
To enable this feature, you need to add `KEY_OVERRIDE_ENABLE = yes` to your `rules.mk`.
|
||||||
|
|
||||||
Then, in your `keymap.c` file, you'll need to define the array `key_overrides`, which defines all key overrides to be used. Each override is a value of type `key_override_t`. The array `key_overrides` is `NULL`-terminated and contains pointers to `key_override_t` values (`const key_override_t **`).
|
Then, in your `keymap.c` file, you'll need to define the array `key_overrides`, which defines all key overrides to be used. Each override is a value of type `key_override_t`. The array `key_overrides` is `NULL`-terminated and contains pointers to `key_override_t` values (`const key_override_t **`).
|
||||||
|
|
||||||
## Creating Key Overrides :id=creating-key-overrides
|
## Creating Key Overrides {#creating-key-overrides}
|
||||||
|
|
||||||
The `key_override_t` struct has many options that allow you to precisely tune your overrides. The full reference is shown below. Instead of manually creating a `key_override_t` value, it is recommended to use these dedicated initializers:
|
The `key_override_t` struct has many options that allow you to precisely tune your overrides. The full reference is shown below. Instead of manually creating a `key_override_t` value, it is recommended to use these dedicated initializers:
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ Additionally takes a bitmask `options` that specifies additional options. See `k
|
||||||
|
|
||||||
For more customization possibilities, you may directly create a `key_override_t`, which allows you to customize even more behavior. Read further below for details and examples.
|
For more customization possibilities, you may directly create a `key_override_t`, which allows you to customize even more behavior. Read further below for details and examples.
|
||||||
|
|
||||||
## Simple Example :id=simple-example
|
## Simple Example {#simple-example}
|
||||||
|
|
||||||
This shows how the mentioned example of sending `delete` when `shift` + `backspace` are pressed is realized:
|
This shows how the mentioned example of sending `delete` when `shift` + `backspace` are pressed is realized:
|
||||||
|
|
||||||
|
@ -48,9 +48,9 @@ const key_override_t **key_overrides = (const key_override_t *[]){
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
## Intermediate Difficulty Examples :id=intermediate-difficulty-examples
|
## Intermediate Difficulty Examples {#intermediate-difficulty-examples}
|
||||||
|
|
||||||
### Media Controls & Screen Brightness :id=media-controls-amp-screen-brightness
|
### Media Controls & Screen Brightness {#media-controls-amp-screen-brightness}
|
||||||
|
|
||||||
In this example a single key is configured to control media, volume and screen brightness by using key overrides.
|
In this example a single key is configured to control media, volume and screen brightness by using key overrides.
|
||||||
|
|
||||||
|
@ -102,8 +102,8 @@ const key_override_t **key_overrides = (const key_override_t *[]){
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### Flexible macOS-friendly Grave Escape :id=flexible-macos-friendly-grave-escape
|
### Flexible macOS-friendly Grave Escape {#flexible-macos-friendly-grave-escape}
|
||||||
The [Grave Escape feature](feature_grave_esc.md) is limited in its configurability and has [bugs when used on macOS](feature_grave_esc.md#caveats). Key overrides can be used to achieve a similar functionality as Grave Escape, but with more customization and without bugs on macOS.
|
The [Grave Escape feature](feature_grave_esc) is limited in its configurability and has [bugs when used on macOS](feature_grave_esc#caveats). Key overrides can be used to achieve a similar functionality as Grave Escape, but with more customization and without bugs on macOS.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// Shift + esc = ~
|
// Shift + esc = ~
|
||||||
|
@ -121,8 +121,8 @@ const key_override_t **key_overrides = (const key_override_t *[]){
|
||||||
|
|
||||||
In addition to not encountering unexpected bugs on macOS, you can also change the behavior as you wish. Instead setting `GUI` + `ESC` = `` ` `` you may change it to an arbitrary other modifier, for example `Ctrl` + `ESC` = `` ` ``.
|
In addition to not encountering unexpected bugs on macOS, you can also change the behavior as you wish. Instead setting `GUI` + `ESC` = `` ` `` you may change it to an arbitrary other modifier, for example `Ctrl` + `ESC` = `` ` ``.
|
||||||
|
|
||||||
## Advanced Examples :id=advanced-examples
|
## Advanced Examples {#advanced-examples}
|
||||||
### Modifiers as Layer Keys :id=modifiers-as-layer-keys
|
### Modifiers as Layer Keys {#modifiers-as-layer-keys}
|
||||||
|
|
||||||
Do you really need a dedicated key to toggle your fn layer? With key overrides, perhaps not. This example shows how you can configure to use `rGUI` + `rAlt` (right GUI and right alt) to access a momentary layer like an fn layer. With this you completely eliminate the need to use a dedicated layer key. Of course the choice of modifier keys can be changed as needed, `rGUI` + `rAlt` is just an example here.
|
Do you really need a dedicated key to toggle your fn layer? With key overrides, perhaps not. This example shows how you can configure to use `rGUI` + `rAlt` (right GUI and right alt) to access a momentary layer like an fn layer. With this you completely eliminate the need to use a dedicated layer key. Of course the choice of modifier keys can be changed as needed, `rGUI` + `rAlt` is just an example here.
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ const key_override_t fn_override = {.trigger_mods = MOD_BIT(KC_RGUI) |
|
||||||
.enabled = NULL};
|
.enabled = NULL};
|
||||||
```
|
```
|
||||||
|
|
||||||
## Keycodes :id=keycodes
|
## Keycodes {#keycodes}
|
||||||
|
|
||||||
|Keycode |Aliases |Description |
|
|Keycode |Aliases |Description |
|
||||||
|------------------------|---------|----------------------|
|
|------------------------|---------|----------------------|
|
||||||
|
@ -158,7 +158,7 @@ const key_override_t fn_override = {.trigger_mods = MOD_BIT(KC_RGUI) |
|
||||||
|`QK_KEY_OVERRIDE_ON` |`KO_ON` |Turn on key overrides |
|
|`QK_KEY_OVERRIDE_ON` |`KO_ON` |Turn on key overrides |
|
||||||
|`QK_KEY_OVERRIDE_OFF` |`KO_OFF` |Turn off key overrides|
|
|`QK_KEY_OVERRIDE_OFF` |`KO_OFF` |Turn off key overrides|
|
||||||
|
|
||||||
## Reference for `key_override_t` :id=reference-for-key_override_t
|
## Reference for `key_override_t` {#reference-for-key_override_t}
|
||||||
|
|
||||||
Advanced users may need more customization than what is offered by the simple `ko_make` initializers. For this, directly create a `key_override_t` value and set all members. Below is a reference for all members of `key_override_t`.
|
Advanced users may need more customization than what is offered by the simple `ko_make` initializers. For this, directly create a `key_override_t` value and set all members. Below is a reference for all members of `key_override_t`.
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ Advanced users may need more customization than what is offered by the simple `k
|
||||||
| `void *context` | A context that will be passed to the custom action function. |
|
| `void *context` | A context that will be passed to the custom action function. |
|
||||||
| `bool *enabled` | If this points to false this override will not be used. Set to NULL to always have this override enabled. |
|
| `bool *enabled` | If this points to false this override will not be used. Set to NULL to always have this override enabled. |
|
||||||
|
|
||||||
## Reference for `ko_option_t` :id=reference-for-ko_option_t
|
## Reference for `ko_option_t` {#reference-for-ko_option_t}
|
||||||
|
|
||||||
Bitfield with various options controlling the behavior of a key override.
|
Bitfield with various options controlling the behavior of a key override.
|
||||||
|
|
||||||
|
@ -189,11 +189,11 @@ Bitfield with various options controlling the behavior of a key override.
|
||||||
| `ko_option_no_reregister_trigger` | If set, the trigger key will never be registered again after the override is deactivated. |
|
| `ko_option_no_reregister_trigger` | If set, the trigger key will never be registered again after the override is deactivated. |
|
||||||
| `ko_options_default` | The default options used by the `ko_make_xxx` functions |
|
| `ko_options_default` | The default options used by the `ko_make_xxx` functions |
|
||||||
|
|
||||||
## For Advanced Users: Inner Workings :id=for-advanced-users-inner-workings
|
## For Advanced Users: Inner Workings {#for-advanced-users-inner-workings}
|
||||||
|
|
||||||
This section explains how a key override works in detail, explaining where each member of `key_override_t` comes into play. Understanding this is essential to be able to take full advantage of all the options offered by key overrides.
|
This section explains how a key override works in detail, explaining where each member of `key_override_t` comes into play. Understanding this is essential to be able to take full advantage of all the options offered by key overrides.
|
||||||
|
|
||||||
#### Activation :id=activation
|
#### Activation {#activation}
|
||||||
|
|
||||||
When the necessary keys are pressed (`trigger_mods` + `trigger`), the override is 'activated' and the replacement key is registered in the keyboard report (`replacement`), while the `trigger` key is removed from the keyboard report. The trigger modifiers may also be removed from the keyboard report upon activation of an override (`suppressed_mods`). The override will not activate if any of the `negative_modifiers` are pressed.
|
When the necessary keys are pressed (`trigger_mods` + `trigger`), the override is 'activated' and the replacement key is registered in the keyboard report (`replacement`), while the `trigger` key is removed from the keyboard report. The trigger modifiers may also be removed from the keyboard report upon activation of an override (`suppressed_mods`). The override will not activate if any of the `negative_modifiers` are pressed.
|
||||||
|
|
||||||
|
@ -207,11 +207,11 @@ Use the `option` member to customize which of these events are allowed to activa
|
||||||
|
|
||||||
In any case, a key override can only activate if the `trigger` key is the _last_ non-modifier key that was pressed down. This emulates the behavior of how standard OSes (macOS, Windows, Linux) handle normal key input (to understand: Hold down `a`, then also hold down `b`, then hold down `shift`; `B` will be typed but not `A`).
|
In any case, a key override can only activate if the `trigger` key is the _last_ non-modifier key that was pressed down. This emulates the behavior of how standard OSes (macOS, Windows, Linux) handle normal key input (to understand: Hold down `a`, then also hold down `b`, then hold down `shift`; `B` will be typed but not `A`).
|
||||||
|
|
||||||
#### Deactivation :id=deactivation
|
#### Deactivation {#deactivation}
|
||||||
|
|
||||||
An override is 'deactivated' when one of the trigger keys (`trigger_mods`, `trigger`) is lifted, another non-modifier key is pressed down, or one of the `negative_modifiers` is pressed down. When an override deactivates, the `replacement` key is removed from the keyboard report, while the `suppressed_mods` that are still held down are re-added to the keyboard report. By default, the `trigger` key is re-added to the keyboard report if it is still held down and no other non-modifier key has been pressed since. This again emulates the behavior of how standard OSes handle normal key input (To understand: hold down `a`, then also hold down `b`, then also `shift`, then release `b`; `A` will not be typed even though you are holding the `a` and `shift` keys). Use the `option` field `ko_option_no_reregister_trigger` to prevent re-registering the trigger key in all cases.
|
An override is 'deactivated' when one of the trigger keys (`trigger_mods`, `trigger`) is lifted, another non-modifier key is pressed down, or one of the `negative_modifiers` is pressed down. When an override deactivates, the `replacement` key is removed from the keyboard report, while the `suppressed_mods` that are still held down are re-added to the keyboard report. By default, the `trigger` key is re-added to the keyboard report if it is still held down and no other non-modifier key has been pressed since. This again emulates the behavior of how standard OSes handle normal key input (To understand: hold down `a`, then also hold down `b`, then also `shift`, then release `b`; `A` will not be typed even though you are holding the `a` and `shift` keys). Use the `option` field `ko_option_no_reregister_trigger` to prevent re-registering the trigger key in all cases.
|
||||||
|
|
||||||
#### Key Repeat Delay :id=key-repeat-delay
|
#### Key Repeat Delay {#key-repeat-delay}
|
||||||
|
|
||||||
A third way in which standard OS-handling of modifier-key input is emulated in key overrides is with a ['key repeat delay'](https://www.dummies.com/computers/pcs/set-your-keyboards-repeat-delay-and-repeat-rate/). To explain what this is, let's look at how normal keyboard input is handled by mainstream OSes again: If you hold down `a`, followed by `shift`, you will see the letter `a` is first typed, then for a short moment nothing is typed and then repeating `A`s are typed. Take note that, although shift is pressed down just after `a` is pressed, it takes a moment until `A` is typed. This is caused by the aforementioned key repeat delay, and it is a feature that prevents unwanted repeated characters from being typed.
|
A third way in which standard OS-handling of modifier-key input is emulated in key overrides is with a ['key repeat delay'](https://www.dummies.com/computers/pcs/set-your-keyboards-repeat-delay-and-repeat-rate/). To explain what this is, let's look at how normal keyboard input is handled by mainstream OSes again: If you hold down `a`, followed by `shift`, you will see the letter `a` is first typed, then for a short moment nothing is typed and then repeating `A`s are typed. Take note that, although shift is pressed down just after `a` is pressed, it takes a moment until `A` is typed. This is caused by the aforementioned key repeat delay, and it is a feature that prevents unwanted repeated characters from being typed.
|
||||||
|
|
||||||
|
@ -222,11 +222,11 @@ This applies equally to releasing a modifier: When you hold `shift`, then press
|
||||||
The duration of the key repeat delay is controlled with the `KEY_OVERRIDE_REPEAT_DELAY` macro. Define this value in your `config.h` file to change it. It is 500ms by default.
|
The duration of the key repeat delay is controlled with the `KEY_OVERRIDE_REPEAT_DELAY` macro. Define this value in your `config.h` file to change it. It is 500ms by default.
|
||||||
|
|
||||||
|
|
||||||
## Difference to Combos :id=difference-to-combos
|
## Difference to Combos {#difference-to-combos}
|
||||||
|
|
||||||
Note that key overrides are very different from [combos](https://docs.qmk.fm/#/feature_combo). Combos require that you press down several keys almost _at the same time_ and can work with any combination of non-modifier keys. Key overrides work like keyboard shortcuts (e.g. `ctrl` + `z`): They take combinations of _multiple_ modifiers and _one_ non-modifier key to then perform some custom action. Key overrides are implemented with much care to behave just like normal keyboard shortcuts would in regards to the order of pressed keys, timing, and interaction with other pressed keys. There are a number of optional settings that can be used to really fine-tune the behavior of each key override as well. Using key overrides also does not delay key input for regular key presses, which inherently happens in combos and may be undesirable.
|
Note that key overrides are very different from [combos](feature_combo). Combos require that you press down several keys almost _at the same time_ and can work with any combination of non-modifier keys. Key overrides work like keyboard shortcuts (e.g. `ctrl` + `z`): They take combinations of _multiple_ modifiers and _one_ non-modifier key to then perform some custom action. Key overrides are implemented with much care to behave just like normal keyboard shortcuts would in regards to the order of pressed keys, timing, and interaction with other pressed keys. There are a number of optional settings that can be used to really fine-tune the behavior of each key override as well. Using key overrides also does not delay key input for regular key presses, which inherently happens in combos and may be undesirable.
|
||||||
|
|
||||||
## Solution to the problem of flashing modifiers :id=neutralize-flashing-modifiers
|
## Solution to the problem of flashing modifiers {#neutralize-flashing-modifiers}
|
||||||
|
|
||||||
If the programs you use bind an action to taps of modifier keys (e.g. tapping left GUI to bring up the applications menu or tapping left Alt to focus the menu bar), you may find that using key overrides with suppressed mods falsely triggers those actions. To counteract this, you can define a `DUMMY_MOD_NEUTRALIZER_KEYCODE` in `config.h` that will get sent in between the register and unregister events of a suppressed modifier. That way, the programs on your computer will no longer interpret the mod suppression induced by key overrides as a lone tap of a modifier key and will thus not falsely trigger the undesired action.
|
If the programs you use bind an action to taps of modifier keys (e.g. tapping left GUI to bring up the applications menu or tapping left Alt to focus the menu bar), you may find that using key overrides with suppressed mods falsely triggers those actions. To counteract this, you can define a `DUMMY_MOD_NEUTRALIZER_KEYCODE` in `config.h` that will get sent in between the register and unregister events of a suppressed modifier. That way, the programs on your computer will no longer interpret the mod suppression induced by key overrides as a lone tap of a modifier key and will thus not falsely trigger the undesired action.
|
||||||
|
|
||||||
|
@ -251,4 +251,6 @@ Examples:
|
||||||
#define MODS_TO_NEUTRALIZE { MOD_BIT(KC_LEFT_ALT), MOD_BIT(KC_LEFT_GUI), MOD_BIT(KC_RIGHT_GUI), MOD_BIT(KC_LEFT_CTRL)|MOD_BIT(KC_LEFT_SHIFT) }
|
#define MODS_TO_NEUTRALIZE { MOD_BIT(KC_LEFT_ALT), MOD_BIT(KC_LEFT_GUI), MOD_BIT(KC_RIGHT_GUI), MOD_BIT(KC_LEFT_CTRL)|MOD_BIT(KC_LEFT_SHIFT) }
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Do not use `MOD_xxx` constants like `MOD_LSFT` or `MOD_RALT`, since they're 5-bit packed bit-arrays while `MODS_TO_NEUTRALIZE` expects a list of 8-bit packed bit-arrays. Use `MOD_BIT(<kc>)` or `MOD_MASK_xxx` instead.
|
::: warning
|
||||||
|
Do not use `MOD_xxx` constants like `MOD_LSFT` or `MOD_RALT`, since they're 5-bit packed bit-arrays while `MODS_TO_NEUTRALIZE` expects a list of 8-bit packed bit-arrays. Use `MOD_BIT(<kc>)` or `MOD_MASK_xxx` instead.
|
||||||
|
:::
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
# Layers :id=layers
|
# Layers {#layers}
|
||||||
|
|
||||||
One of the most powerful and well used features of QMK Firmware is the ability to use layers. For most people, this amounts to a function key that allows for different keys, much like what you would see on a laptop or tablet keyboard.
|
One of the most powerful and well used features of QMK Firmware is the ability to use layers. For most people, this amounts to a function key that allows for different keys, much like what you would see on a laptop or tablet keyboard.
|
||||||
|
|
||||||
For a detailed explanation of how the layer stack works, checkout [Keymap Overview](keymap.md#keymap-and-layers).
|
For a detailed explanation of how the layer stack works, checkout [Keymap Overview](keymap#keymap-and-layers).
|
||||||
|
|
||||||
## Switching and Toggling Layers :id=switching-and-toggling-layers
|
## Switching and Toggling Layers {#switching-and-toggling-layers}
|
||||||
|
|
||||||
These functions allow you to activate layers in various ways. Note that layers are not generally independent layouts -- multiple layers can be activated at once, and it's typical for layers to use `KC_TRNS` to allow keypresses to pass through to lower layers. When using momentary layer switching with MO(), LM(), TT(), or LT(), make sure to leave the key on the above layers transparent or it may not work as intended.
|
These functions allow you to activate layers in various ways. Note that layers are not generally independent layouts -- multiple layers can be activated at once, and it's typical for layers to use `KC_TRNS` to allow keypresses to pass through to lower layers. When using momentary layer switching with MO(), LM(), TT(), or LT(), make sure to leave the key on the above layers transparent or it may not work as intended.
|
||||||
|
|
||||||
* `DF(layer)` - switches the default layer. The default layer is the always-active base layer that other layers stack on top of. See below for more about the default layer. This might be used to switch from QWERTY to Dvorak layout. (Note that this is a temporary switch that only persists until the keyboard loses power. To modify the default layer in a persistent way requires deeper customization, such as calling the `set_single_persistent_default_layer` function inside of [process_record_user](custom_quantum_functions.md#programming-the-behavior-of-any-keycode).)
|
* `DF(layer)` - switches the default layer. The default layer is the always-active base layer that other layers stack on top of. See below for more about the default layer. This might be used to switch from QWERTY to Dvorak layout. (Note that this is a temporary switch that only persists until the keyboard loses power. To modify the default layer in a persistent way requires deeper customization, such as calling the `set_single_persistent_default_layer` function inside of [process_record_user](custom_quantum_functions#programming-the-behavior-of-any-keycode).)
|
||||||
* `MO(layer)` - momentarily activates *layer*. As soon as you let go of the key, the layer is deactivated.
|
* `MO(layer)` - momentarily activates *layer*. As soon as you let go of the key, the layer is deactivated.
|
||||||
* `LM(layer, mod)` - Momentarily activates *layer* (like `MO`), but with modifier(s) *mod* active. Only supports layers 0-15. The modifiers this keycode accept are prefixed with `MOD_`, not `KC_`. These modifiers can be combined using bitwise OR, e.g. `LM(_RAISE, MOD_LCTL | MOD_LALT)`.
|
* `LM(layer, mod)` - Momentarily activates *layer* (like `MO`), but with modifier(s) *mod* active. Only supports layers 0-15. The modifiers this keycode accept are prefixed with `MOD_`, not `KC_`. These modifiers can be combined using bitwise OR, e.g. `LM(_RAISE, MOD_LCTL | MOD_LALT)`.
|
||||||
* `LT(layer, kc)` - momentarily activates *layer* when held, and sends *kc* when tapped. Only supports layers 0-15.
|
* `LT(layer, kc)` - momentarily activates *layer* when held, and sends *kc* when tapped. Only supports layers 0-15.
|
||||||
* `OSL(layer)` - momentarily activates *layer* until the next key is pressed. See [One Shot Keys](one_shot_keys.md) for details and additional functionality.
|
* `OSL(layer)` - momentarily activates *layer* until the next key is pressed. See [One Shot Keys](one_shot_keys) for details and additional functionality.
|
||||||
* `TG(layer)` - toggles *layer*, activating it if it's inactive and vice versa
|
* `TG(layer)` - toggles *layer*, activating it if it's inactive and vice versa
|
||||||
* `TO(layer)` - activates *layer* and de-activates all other layers (except your default layer). This function is special, because instead of just adding/removing one layer to your active layer stack, it will completely replace your current active layers, uniquely allowing you to replace higher layers with a lower one. This is activated on keydown (as soon as the key is pressed).
|
* `TO(layer)` - activates *layer* and de-activates all other layers (except your default layer). This function is special, because instead of just adding/removing one layer to your active layer stack, it will completely replace your current active layers, uniquely allowing you to replace higher layers with a lower one. This is activated on keydown (as soon as the key is pressed).
|
||||||
* `TT(layer)` - Layer Tap-Toggle. If you hold the key down, *layer* is activated, and then is de-activated when you let go (like `MO`). If you repeatedly tap it, the layer will be toggled on or off (like `TG`). It needs 5 taps by default, but you can change this by defining `TAPPING_TOGGLE` -- for example, `#define TAPPING_TOGGLE 2` to toggle on just two taps.
|
* `TT(layer)` - Layer Tap-Toggle. If you hold the key down, *layer* is activated, and then is de-activated when you let go (like `MO`). If you repeatedly tap it, the layer will be toggled on or off (like `TG`). It needs 5 taps by default, but you can change this by defining `TAPPING_TOGGLE` -- for example, `#define TAPPING_TOGGLE 2` to toggle on just two taps.
|
||||||
|
|
||||||
### Caveats :id=caveats
|
### Caveats {#caveats}
|
||||||
|
|
||||||
Currently, the `layer` argument of `LT()` is limited to layers 0-15, and the `kc` argument to the [Basic Keycode set](keycodes_basic.md), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. This is because QMK uses 16-bit keycodes, of which 4 bits are used for the function identifier and 4 bits for the layer, leaving only 8 bits for the keycode.
|
Currently, the `layer` argument of `LT()` is limited to layers 0-15, and the `kc` argument to the [Basic Keycode set](keycodes_basic), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. This is because QMK uses 16-bit keycodes, of which 4 bits are used for the function identifier and 4 bits for the layer, leaving only 8 bits for the keycode.
|
||||||
|
|
||||||
For a similar reason, the `layer` argument of `LM()` is also limited to layers 0-15 and the `mod` argument must fit within 5 bits. As a consequence, although left and right modifiers are supported by `LM()`, it is impossible to mix and match left and right modifiers. Specifying at least one right-hand modifier in a combination such as `MOD_RALT|MOD_LSFT` will convert *all* the listed modifiers to their right-hand counterpart. So, using the aforementionned mod-mask will actually send <kbd>Right Alt</kbd>+<kbd>Right Shift</kbd>. Make sure to use the `MOD_xxx` constants over alternative ways of specifying modifiers when defining your layer-mod key.
|
For a similar reason, the `layer` argument of `LM()` is also limited to layers 0-15 and the `mod` argument must fit within 5 bits. As a consequence, although left and right modifiers are supported by `LM()`, it is impossible to mix and match left and right modifiers. Specifying at least one right-hand modifier in a combination such as `MOD_RALT|MOD_LSFT` will convert *all* the listed modifiers to their right-hand counterpart. So, using the aforementionned mod-mask will actually send <kbd>Right Alt</kbd>+<kbd>Right Shift</kbd>. Make sure to use the `MOD_xxx` constants over alternative ways of specifying modifiers when defining your layer-mod key.
|
||||||
|
|
||||||
|
@ -27,13 +27,13 @@ For a similar reason, the `layer` argument of `LM()` is also limited to layers 0
|
||||||
|:---------------:|:----------------------:|:------------------------:|:----------------:|
|
|:---------------:|:----------------------:|:------------------------:|:----------------:|
|
||||||
| ❌ | ❌ | ❌ | ✅ |
|
| ❌ | ❌ | ❌ | ✅ |
|
||||||
|
|
||||||
Expanding this would be complicated, at best. Moving to a 32-bit keycode would solve a lot of this, but would double the amount of space that the keymap matrix uses. And it could potentially cause issues, too. If you need to apply modifiers to your tapped keycode, [Tap Dance](feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys) can be used to accomplish this.
|
Expanding this would be complicated, at best. Moving to a 32-bit keycode would solve a lot of this, but would double the amount of space that the keymap matrix uses. And it could potentially cause issues, too. If you need to apply modifiers to your tapped keycode, [Tap Dance](feature_tap_dance#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys) can be used to accomplish this.
|
||||||
|
|
||||||
## Working with Layers :id=working-with-layers
|
## Working with Layers {#working-with-layers}
|
||||||
|
|
||||||
Care must be taken when switching layers, it's possible to lock yourself into a layer with no way to deactivate that layer (without unplugging your keyboard.) We've created some guidelines to help users avoid the most common problems.
|
Care must be taken when switching layers, it's possible to lock yourself into a layer with no way to deactivate that layer (without unplugging your keyboard.) We've created some guidelines to help users avoid the most common problems.
|
||||||
|
|
||||||
### Beginners :id=beginners
|
### Beginners {#beginners}
|
||||||
|
|
||||||
If you are just getting started with QMK you will want to keep everything simple. Follow these guidelines when setting up your layers:
|
If you are just getting started with QMK you will want to keep everything simple. Follow these guidelines when setting up your layers:
|
||||||
|
|
||||||
|
@ -41,11 +41,11 @@ If you are just getting started with QMK you will want to keep everything simple
|
||||||
* Arrange your layers in a "tree" layout, with layer 0 as the root. Do not try to enter the same layer from more than one other layer.
|
* Arrange your layers in a "tree" layout, with layer 0 as the root. Do not try to enter the same layer from more than one other layer.
|
||||||
* In a layer's keymap, only reference higher-numbered layers. Because layers are processed from the highest-numbered (topmost) active layer down, modifying the state of lower layers can be tricky and error-prone.
|
* In a layer's keymap, only reference higher-numbered layers. Because layers are processed from the highest-numbered (topmost) active layer down, modifying the state of lower layers can be tricky and error-prone.
|
||||||
|
|
||||||
### Intermediate Users :id=intermediate-users
|
### Intermediate Users {#intermediate-users}
|
||||||
|
|
||||||
Sometimes you need more than one base layer. For example, if you want to switch between QWERTY and Dvorak, switch between layouts for different countries, or switch your layout for different videogames. Your base layers should always be the lowest numbered layers. When you have multiple base layers you should always treat them as mutually exclusive. When one base layer is on the others are off.
|
Sometimes you need more than one base layer. For example, if you want to switch between QWERTY and Dvorak, switch between layouts for different countries, or switch your layout for different videogames. Your base layers should always be the lowest numbered layers. When you have multiple base layers you should always treat them as mutually exclusive. When one base layer is on the others are off.
|
||||||
|
|
||||||
### Advanced Users :id=advanced-users
|
### Advanced Users {#advanced-users}
|
||||||
|
|
||||||
Once you have a good feel for how layers work and what you can do, you can get more creative. The rules listed in the beginner section will help you be successful by avoiding some of the tricker details but they can be constraining, especially for ultra-compact keyboard users. Understanding how layers work will allow you to use them in more advanced ways.
|
Once you have a good feel for how layers work and what you can do, you can get more creative. The rules listed in the beginner section will help you be successful by avoiding some of the tricker details but they can be constraining, especially for ultra-compact keyboard users. Understanding how layers work will allow you to use them in more advanced ways.
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ Layers stack on top of each other in numerical order. When determining what a ke
|
||||||
|
|
||||||
Sometimes, you might want to switch between layers in a macro or as part of a tap dance routine. `layer_on` activates a layer, and `layer_off` deactivates it. More layer-related functions can be found in [action_layer.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/action_layer.h).
|
Sometimes, you might want to switch between layers in a macro or as part of a tap dance routine. `layer_on` activates a layer, and `layer_off` deactivates it. More layer-related functions can be found in [action_layer.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/action_layer.h).
|
||||||
|
|
||||||
## Functions :id=functions
|
## Functions {#functions}
|
||||||
|
|
||||||
There are a number of functions (and variables) related to how you can use or manipulate the layers.
|
There are a number of functions (and variables) related to how you can use or manipulate the layers.
|
||||||
|
|
||||||
|
@ -87,7 +87,9 @@ In addition to the functions that you can call, there are a number of callback f
|
||||||
| `default_layer_state_set_kb(layer_state_t state)` | Callback for default layer functions, for keyboard. Called on keyboard initialization. |
|
| `default_layer_state_set_kb(layer_state_t state)` | Callback for default layer functions, for keyboard. Called on keyboard initialization. |
|
||||||
| `default_layer_state_set_user(layer_state_t state)` | Callback for default layer functions, for users. Called on keyboard initialization. |
|
| `default_layer_state_set_user(layer_state_t state)` | Callback for default layer functions, for users. Called on keyboard initialization. |
|
||||||
|
|
||||||
?> For additional details on how you can use these callbacks, check out the [Layer Change Code](custom_quantum_functions.md#layer-change-code) document.
|
::: tip
|
||||||
|
For additional details on how you can use these callbacks, check out the [Layer Change Code](custom_quantum_functions#layer-change-code) document.
|
||||||
|
:::
|
||||||
|
|
||||||
It is also possible to check the state of a particular layer using the following functions and macros.
|
It is also possible to check the state of a particular layer using the following functions and macros.
|
||||||
|
|
||||||
|
@ -96,13 +98,13 @@ It is also possible to check the state of a particular layer using the following
|
||||||
| `layer_state_is(layer)` | Checks if the specified `layer` is enabled globally. | `IS_LAYER_ON(layer)`, `IS_LAYER_OFF(layer)` |
|
| `layer_state_is(layer)` | Checks if the specified `layer` is enabled globally. | `IS_LAYER_ON(layer)`, `IS_LAYER_OFF(layer)` |
|
||||||
| `layer_state_cmp(state, layer)` | Checks `state` to see if the specified `layer` is enabled. Intended for use in layer callbacks. | `IS_LAYER_ON_STATE(state, layer)`, `IS_LAYER_OFF_STATE(state, layer)` |
|
| `layer_state_cmp(state, layer)` | Checks `state` to see if the specified `layer` is enabled. Intended for use in layer callbacks. | `IS_LAYER_ON_STATE(state, layer)`, `IS_LAYER_OFF_STATE(state, layer)` |
|
||||||
|
|
||||||
## Layer Change Code :id=layer-change-code
|
## Layer Change Code {#layer-change-code}
|
||||||
|
|
||||||
This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling.
|
This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling.
|
||||||
|
|
||||||
### Example `layer_state_set_*` Implementation
|
### Example `layer_state_set_*` Implementation
|
||||||
|
|
||||||
This example shows how to set the [RGB Underglow](feature_rgblight.md) lights based on the layer, using the Planck as an example.
|
This example shows how to set the [RGB Underglow](feature_rgblight) lights based on the layer, using the Planck as an example.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
layer_state_t layer_state_set_user(layer_state_t state) {
|
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||||
|
@ -185,4 +187,4 @@ Outside of `layer_state_set_*` functions, you can use the `IS_LAYER_ON(layer)` a
|
||||||
* Keymap: `layer_state_t layer_state_set_user(layer_state_t state)`
|
* Keymap: `layer_state_t layer_state_set_user(layer_state_t state)`
|
||||||
|
|
||||||
|
|
||||||
The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap.md#keymap-layer-status)
|
The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap#keymap-layer-status)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# The Leader Key: A New Kind of Modifier :id=the-leader-key
|
# The Leader Key: A New Kind of Modifier {#the-leader-key}
|
||||||
|
|
||||||
If you're a Vim user, you probably know what a Leader key is. In contrast to [Combos](feature_combo.md), the Leader key allows you to hit a *sequence* of up to five keys instead, which triggers some custom functionality once complete.
|
If you're a Vim user, you probably know what a Leader key is. In contrast to [Combos](feature_combo), the Leader key allows you to hit a *sequence* of up to five keys instead, which triggers some custom functionality once complete.
|
||||||
|
|
||||||
## Usage :id=usage
|
## Usage {#usage}
|
||||||
|
|
||||||
Add the following to your `rules.mk`:
|
Add the following to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ LEADER_ENABLE = yes
|
||||||
|
|
||||||
Then add the `QK_LEAD` keycode to your keymap.
|
Then add the `QK_LEAD` keycode to your keymap.
|
||||||
|
|
||||||
## Callbacks :id=callbacks
|
## Callbacks {#callbacks}
|
||||||
|
|
||||||
These callbacks are invoked when the leader sequence begins and ends. In the latter you can implement your custom functionality based on the contents of the sequence buffer.
|
These callbacks are invoked when the leader sequence begins and ends. In the latter you can implement your custom functionality based on the contents of the sequence buffer.
|
||||||
|
|
||||||
|
@ -38,9 +38,9 @@ void leader_end_user(void) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Basic Configuration :id=basic-configuration
|
## Basic Configuration {#basic-configuration}
|
||||||
|
|
||||||
### Timeout :id=timeout
|
### Timeout {#timeout}
|
||||||
|
|
||||||
This is the amount of time you have to complete a sequence once the leader key has been pressed. The default value is 300 milliseconds, but you can change this by adding the following to your `config.h`:
|
This is the amount of time you have to complete a sequence once the leader key has been pressed. The default value is 300 milliseconds, but you can change this by adding the following to your `config.h`:
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ This is the amount of time you have to complete a sequence once the leader key h
|
||||||
#define LEADER_TIMEOUT 350
|
#define LEADER_TIMEOUT 350
|
||||||
```
|
```
|
||||||
|
|
||||||
### Per-Key Timeout :id=per-key-timeout
|
### Per-Key Timeout {#per-key-timeout}
|
||||||
|
|
||||||
Rather than relying on an incredibly high timeout for long leader key strings or those of us without 200 wpm typing skills, you can enable per-key timing to ensure that each key pressed provides you with more time to finish the sequence. This is incredibly helpful with leader key emulation of tap dance (such as multiple taps of the same key like C, C, C).
|
Rather than relying on an incredibly high timeout for long leader key strings or those of us without 200 wpm typing skills, you can enable per-key timing to ensure that each key pressed provides you with more time to finish the sequence. This is incredibly helpful with leader key emulation of tap dance (such as multiple taps of the same key like C, C, C).
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ if (leader_sequence_three_keys(KC_C, KC_C, KC_C)) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Disabling Initial Timeout :id=disabling-initial-timeout
|
### Disabling Initial Timeout {#disabling-initial-timeout}
|
||||||
|
|
||||||
Sometimes your leader key may be too far away from the rest of the keys in the sequence. Imagine that your leader key is one of your outer top right keys - you may need to reposition your hand just to reach your leader key. This can make typing the entire sequence on time hard difficult if you are able to type most of the sequence fast. For example, if your sequence is `Leader + asd`, typing `asd` fast is very easy once you have your hands in your home row, but starting the sequence in time after moving your hand out of the home row to reach the leader key and back is not.
|
Sometimes your leader key may be too far away from the rest of the keys in the sequence. Imagine that your leader key is one of your outer top right keys - you may need to reposition your hand just to reach your leader key. This can make typing the entire sequence on time hard difficult if you are able to type most of the sequence fast. For example, if your sequence is `Leader + asd`, typing `asd` fast is very easy once you have your hands in your home row, but starting the sequence in time after moving your hand out of the home row to reach the leader key and back is not.
|
||||||
|
|
||||||
|
@ -84,9 +84,9 @@ To remove the stress this situation produces to your hands, you can disable the
|
||||||
|
|
||||||
Now, after you hit the leader key, you will have an infinite amount of time to start the rest of the sequence, allowing you to properly position your hands to type the rest of the sequence comfortably. This way you can configure a very short `LEADER_TIMEOUT`, but still have plenty of time to position your hands.
|
Now, after you hit the leader key, you will have an infinite amount of time to start the rest of the sequence, allowing you to properly position your hands to type the rest of the sequence comfortably. This way you can configure a very short `LEADER_TIMEOUT`, but still have plenty of time to position your hands.
|
||||||
|
|
||||||
### Strict Key Processing :id=strict-key-processing
|
### Strict Key Processing {#strict-key-processing}
|
||||||
|
|
||||||
By default, only the "tap keycode" portions of [Mod-Taps](mod_tap.md) and [Layer Taps](feature_layers.md#switching-and-toggling-layers) are added to the sequence buffer. This means if you press eg. `LT(3, KC_A)` as part of a sequence, `KC_A` will be added to the buffer, rather than the entire `LT(3, KC_A)` keycode.
|
By default, only the "tap keycode" portions of [Mod-Taps](mod_tap) and [Layer Taps](feature_layers#switching-and-toggling-layers) are added to the sequence buffer. This means if you press eg. `LT(3, KC_A)` as part of a sequence, `KC_A` will be added to the buffer, rather than the entire `LT(3, KC_A)` keycode.
|
||||||
|
|
||||||
This gives a more expected behaviour for most users, however you may want to change this.
|
This gives a more expected behaviour for most users, however you may want to change this.
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ To enable this, add the following to your `config.h`:
|
||||||
#define LEADER_KEY_STRICT_KEY_PROCESSING
|
#define LEADER_KEY_STRICT_KEY_PROCESSING
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example :id=example
|
## Example {#example}
|
||||||
|
|
||||||
This example will play the Mario "One Up" sound when you hit `QK_LEAD` to start the leader sequence. When the sequence ends, it will play "All Star" if it completes successfully or "Rick Roll" you if it fails (in other words, no sequence matched).
|
This example will play the Mario "One Up" sound when you hit `QK_LEAD` to start the leader sequence. When the sequence ends, it will play "All Star" if it completes successfully or "Rick Roll" you if it fails (in other words, no sequence matched).
|
||||||
|
|
||||||
|
@ -134,62 +134,62 @@ void leader_end_user(void) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Keycodes :id=keycodes
|
## Keycodes {#keycodes}
|
||||||
|
|
||||||
|Key |Aliases |Description |
|
|Key |Aliases |Description |
|
||||||
|-----------------------|---------|-------------------------|
|
|-----------------------|---------|-------------------------|
|
||||||
|`QK_LEADER` |`QK_LEAD`|Begin the leader sequence|
|
|`QK_LEADER` |`QK_LEAD`|Begin the leader sequence|
|
||||||
|
|
||||||
## API :id=api
|
## API {#api}
|
||||||
|
|
||||||
### `void leader_start_user(void)` :id=api-leader-start-user
|
### `void leader_start_user(void)` {#api-leader-start-user}
|
||||||
|
|
||||||
User callback, invoked when the leader sequence begins.
|
User callback, invoked when the leader sequence begins.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void leader_end_user(void)` :id=api-leader-end-user
|
### `void leader_end_user(void)` {#api-leader-end-user}
|
||||||
|
|
||||||
User callback, invoked when the leader sequence ends.
|
User callback, invoked when the leader sequence ends.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void leader_start(void)` :id=api-leader-start
|
### `void leader_start(void)` {#api-leader-start}
|
||||||
|
|
||||||
Begin the leader sequence, resetting the buffer and timer.
|
Begin the leader sequence, resetting the buffer and timer.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void leader_end(void)` :id=api-leader-end
|
### `void leader_end(void)` {#api-leader-end}
|
||||||
|
|
||||||
End the leader sequence.
|
End the leader sequence.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool leader_sequence_active(void)` :id=api-leader-sequence-active
|
### `bool leader_sequence_active(void)` {#api-leader-sequence-active}
|
||||||
|
|
||||||
Whether the leader sequence is active.
|
Whether the leader sequence is active.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool leader_sequence_add(uint16_t keycode)` :id=api-leader-sequence-add
|
### `bool leader_sequence_add(uint16_t keycode)` {#api-leader-sequence-add}
|
||||||
|
|
||||||
Add the given keycode to the sequence buffer.
|
Add the given keycode to the sequence buffer.
|
||||||
|
|
||||||
If `LEADER_NO_TIMEOUT` is defined, the timer is reset if the buffer is empty.
|
If `LEADER_NO_TIMEOUT` is defined, the timer is reset if the buffer is empty.
|
||||||
|
|
||||||
#### Arguments :id=api-leader-sequence-add-arguments
|
#### Arguments {#api-leader-sequence-add-arguments}
|
||||||
|
|
||||||
- `uint16_t keycode`
|
- `uint16_t keycode`
|
||||||
The keycode to add.
|
The keycode to add.
|
||||||
|
|
||||||
#### Return Value :id=api-leader-sequence-add-return
|
#### Return Value {#api-leader-sequence-add-return}
|
||||||
|
|
||||||
`true` if the keycode was added, `false` if the buffer is full.
|
`true` if the keycode was added, `false` if the buffer is full.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool leader_sequence_timed_out(void)` :id=api-leader-sequence-timed-out
|
### `bool leader_sequence_timed_out(void)` {#api-leader-sequence-timed-out}
|
||||||
|
|
||||||
Whether the leader sequence has reached the timeout.
|
Whether the leader sequence has reached the timeout.
|
||||||
|
|
||||||
|
@ -197,49 +197,49 @@ If `LEADER_NO_TIMEOUT` is defined, the buffer must also contain at least one key
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool leader_reset_timer(void)` :id=api-leader-reset-timer
|
### `bool leader_reset_timer(void)` {#api-leader-reset-timer}
|
||||||
|
|
||||||
Reset the leader sequence timer.
|
Reset the leader sequence timer.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool leader_sequence_one_key(uint16_t kc)` :id=api-leader-sequence-one-key
|
### `bool leader_sequence_one_key(uint16_t kc)` {#api-leader-sequence-one-key}
|
||||||
|
|
||||||
Check the sequence buffer for the given keycode.
|
Check the sequence buffer for the given keycode.
|
||||||
|
|
||||||
#### Arguments :id=api-leader-sequence-one-key-arguments
|
#### Arguments {#api-leader-sequence-one-key-arguments}
|
||||||
|
|
||||||
- `uint16_t kc`
|
- `uint16_t kc`
|
||||||
The keycode to check.
|
The keycode to check.
|
||||||
|
|
||||||
#### Return Value :id=api-leader-sequence-one-key-return
|
#### Return Value {#api-leader-sequence-one-key-return}
|
||||||
|
|
||||||
`true` if the sequence buffer matches.
|
`true` if the sequence buffer matches.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool leader_sequence_two_keys(uint16_t kc1, uint16_t kc2)` :id=api-leader-sequence-two-keys
|
### `bool leader_sequence_two_keys(uint16_t kc1, uint16_t kc2)` {#api-leader-sequence-two-keys}
|
||||||
|
|
||||||
Check the sequence buffer for the given keycodes.
|
Check the sequence buffer for the given keycodes.
|
||||||
|
|
||||||
#### Arguments :id=api-leader-sequence-two-keys-arguments
|
#### Arguments {#api-leader-sequence-two-keys-arguments}
|
||||||
|
|
||||||
- `uint16_t kc1`
|
- `uint16_t kc1`
|
||||||
The first keycode to check.
|
The first keycode to check.
|
||||||
- `uint16_t kc2`
|
- `uint16_t kc2`
|
||||||
The second keycode to check.
|
The second keycode to check.
|
||||||
|
|
||||||
#### Return Value :id=api-leader-sequence-two-keys-return
|
#### Return Value {#api-leader-sequence-two-keys-return}
|
||||||
|
|
||||||
`true` if the sequence buffer matches.
|
`true` if the sequence buffer matches.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool leader_sequence_three_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3)` :id=api-leader-sequence-three-keys
|
### `bool leader_sequence_three_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3)` {#api-leader-sequence-three-keys}
|
||||||
|
|
||||||
Check the sequence buffer for the given keycodes.
|
Check the sequence buffer for the given keycodes.
|
||||||
|
|
||||||
#### Arguments :id=api-leader-sequence-three-keys-arguments
|
#### Arguments {#api-leader-sequence-three-keys-arguments}
|
||||||
|
|
||||||
- `uint16_t kc1`
|
- `uint16_t kc1`
|
||||||
The first keycode to check.
|
The first keycode to check.
|
||||||
|
@ -248,17 +248,17 @@ Check the sequence buffer for the given keycodes.
|
||||||
- `uint16_t kc3`
|
- `uint16_t kc3`
|
||||||
The third keycode to check.
|
The third keycode to check.
|
||||||
|
|
||||||
#### Return Value :id=api-leader-sequence-three-keys-return
|
#### Return Value {#api-leader-sequence-three-keys-return}
|
||||||
|
|
||||||
`true` if the sequence buffer matches.
|
`true` if the sequence buffer matches.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool leader_sequence_four_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4)` :id=api-leader-sequence-four-keys
|
### `bool leader_sequence_four_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4)` {#api-leader-sequence-four-keys}
|
||||||
|
|
||||||
Check the sequence buffer for the given keycodes.
|
Check the sequence buffer for the given keycodes.
|
||||||
|
|
||||||
#### Arguments :id=api-leader-sequence-four-keys-arguments
|
#### Arguments {#api-leader-sequence-four-keys-arguments}
|
||||||
|
|
||||||
- `uint16_t kc1`
|
- `uint16_t kc1`
|
||||||
The first keycode to check.
|
The first keycode to check.
|
||||||
|
@ -269,17 +269,17 @@ Check the sequence buffer for the given keycodes.
|
||||||
- `uint16_t kc4`
|
- `uint16_t kc4`
|
||||||
The fourth keycode to check.
|
The fourth keycode to check.
|
||||||
|
|
||||||
#### Return Value :id=api-leader-sequence-four-keys-return
|
#### Return Value {#api-leader-sequence-four-keys-return}
|
||||||
|
|
||||||
`true` if the sequence buffer matches.
|
`true` if the sequence buffer matches.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool leader_sequence_five_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4, uint16_t kc5)` :id=api-leader-sequence-five-keys
|
### `bool leader_sequence_five_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4, uint16_t kc5)` {#api-leader-sequence-five-keys}
|
||||||
|
|
||||||
Check the sequence buffer for the given keycodes.
|
Check the sequence buffer for the given keycodes.
|
||||||
|
|
||||||
#### Arguments :id=api-leader-sequence-five-keys-arguments
|
#### Arguments {#api-leader-sequence-five-keys-arguments}
|
||||||
|
|
||||||
- `uint16_t kc1`
|
- `uint16_t kc1`
|
||||||
The first keycode to check.
|
The first keycode to check.
|
||||||
|
@ -292,6 +292,6 @@ Check the sequence buffer for the given keycodes.
|
||||||
- `uint16_t kc5`
|
- `uint16_t kc5`
|
||||||
The fifth keycode to check.
|
The fifth keycode to check.
|
||||||
|
|
||||||
#### Return Value :id=api-leader-sequence-five-keys-return
|
#### Return Value {#api-leader-sequence-five-keys-return}
|
||||||
|
|
||||||
`true` if the sequence buffer matches.
|
`true` if the sequence buffer matches.
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# LED Indicators
|
# LED Indicators
|
||||||
|
|
||||||
?> LED indicators on split keyboards will require state information synced to the slave half (e.g. `#define SPLIT_LED_STATE_ENABLE`). See [data sync options](feature_split_keyboard.md#data-sync-options) for more details.
|
::: tip
|
||||||
|
LED indicators on split keyboards will require state information synced to the slave half (e.g. `#define SPLIT_LED_STATE_ENABLE`). See [data sync options](feature_split_keyboard#data-sync-options) for more details.
|
||||||
|
:::
|
||||||
|
|
||||||
QMK provides methods to read 5 of the LEDs defined in the HID spec:
|
QMK provides methods to read 5 of the LEDs defined in the HID spec:
|
||||||
|
|
||||||
|
@ -15,7 +17,9 @@ There are three ways to get the lock LED state:
|
||||||
* Implement `led_update_*` function
|
* Implement `led_update_*` function
|
||||||
* Call `led_t host_keyboard_led_state()`
|
* Call `led_t host_keyboard_led_state()`
|
||||||
|
|
||||||
!> The `host_keyboard_led_state()` may reflect an updated state before `led_update_user()` is called.
|
::: warning
|
||||||
|
The `host_keyboard_led_state()` may reflect an updated state before `led_update_user()` is called.
|
||||||
|
:::
|
||||||
|
|
||||||
Two deprecated functions that provide the LED state as `uint8_t`:
|
Two deprecated functions that provide the LED state as `uint8_t`:
|
||||||
|
|
||||||
|
@ -46,7 +50,9 @@ When the configuration options do not provide enough flexibility, the following
|
||||||
|
|
||||||
Both receives LED state as a struct parameter. Returning `true` in `led_update_user()` will allow the keyboard level code in `led_update_kb()` to run as well. Returning `false` will override the keyboard level code, depending on how the keyboard level function is set up.
|
Both receives LED state as a struct parameter. Returning `true` in `led_update_user()` will allow the keyboard level code in `led_update_kb()` to run as well. Returning `false` will override the keyboard level code, depending on how the keyboard level function is set up.
|
||||||
|
|
||||||
?> This boolean return type of `led_update_user` allows for overriding keyboard LED controls, and is thus recommended over the void `led_set_user` function.
|
::: tip
|
||||||
|
This boolean return type of `led_update_user` allows for overriding keyboard LED controls, and is thus recommended over the void `led_set_user` function.
|
||||||
|
:::
|
||||||
|
|
||||||
### Example of keyboard LED update implementation
|
### Example of keyboard LED update implementation
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# LED Matrix Lighting :id=led-matrix-lighting
|
# LED Matrix Lighting {#led-matrix-lighting}
|
||||||
|
|
||||||
This feature allows you to use LED matrices driven by external drivers. It hooks into the backlight system so you can use the same keycodes as backlighting to control it.
|
This feature allows you to use LED matrices driven by external drivers. It hooks into the backlight system so you can use the same keycodes as backlighting to control it.
|
||||||
|
|
||||||
If you want to use RGB LED's you should use the [RGB Matrix Subsystem](feature_rgb_matrix.md) instead.
|
If you want to use RGB LED's you should use the [RGB Matrix Subsystem](feature_rgb_matrix) instead.
|
||||||
|
|
||||||
## Driver configuration :id=driver-configuration
|
## Driver configuration {#driver-configuration}
|
||||||
---
|
---
|
||||||
### IS31FL3731 :id=is31fl3731
|
### IS31FL3731 {#is31fl3731}
|
||||||
|
|
||||||
There is basic support for addressable LED matrix lighting with the I2C IS31FL3731 LED controller. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable LED matrix lighting with the I2C IS31FL3731 LED controller. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -47,7 +47,9 @@ Here is an example using 2 drivers.
|
||||||
#define LED_MATRIX_LED_COUNT (LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL)
|
#define LED_MATRIX_LED_COUNT (LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL)
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Note the parentheses, this is so when `LED_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL)` will give very different results than `rand() % LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL`.
|
::: warning
|
||||||
|
Note the parentheses, this is so when `LED_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL)` will give very different results than `rand() % LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL`.
|
||||||
|
:::
|
||||||
|
|
||||||
For split keyboards using `LED_MATRIX_SPLIT` with an LED driver, you can either have the same driver address or different driver addresses. If using different addresses, use `IS31FL3731_I2C_ADDRESS_1` for one and `IS31FL3731_I2C_ADDRESS_2` for the other one. Then, in `g_is31fl3731_leds`, fill out the correct driver index (0 or 1). If using one address, use `IS31FL3731_I2C_ADDRESS_1` for both, and use index 0 for `g_is31fl3731_leds`.
|
For split keyboards using `LED_MATRIX_SPLIT` with an LED driver, you can either have the same driver address or different driver addresses. If using different addresses, use `IS31FL3731_I2C_ADDRESS_1` for one and `IS31FL3731_I2C_ADDRESS_2` for the other one. Then, in `g_is31fl3731_leds`, fill out the correct driver index (0 or 1). If using one address, use `IS31FL3731_I2C_ADDRESS_1` for both, and use index 0 for `g_is31fl3731_leds`.
|
||||||
|
|
||||||
|
@ -68,7 +70,7 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
||||||
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/led/issi/is31fl3731-mono.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` ).
|
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/led/issi/is31fl3731-mono.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` ).
|
||||||
|
|
||||||
---
|
---
|
||||||
### IS31FLCOMMON :id=is31flcommon
|
### IS31FLCOMMON {#is31flcommon}
|
||||||
|
|
||||||
There is basic support for addressable LED matrix lighting with a selection of I2C ISSI Lumissil LED controllers through a shared common driver. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable LED matrix lighting with a selection of I2C ISSI Lumissil LED controllers through a shared common driver. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -130,7 +132,9 @@ Here is an example using 2 drivers.
|
||||||
#define DRIVER_2_LED_TOTAL 42
|
#define DRIVER_2_LED_TOTAL 42
|
||||||
#define LED_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
#define LED_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
||||||
```
|
```
|
||||||
!> Note the parentheses, this is so when `LED_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
::: warning
|
||||||
|
Note the parentheses, this is so when `LED_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
||||||
|
:::
|
||||||
|
|
||||||
Currently only 4 drivers are supported, but it would be trivial to support for more. Note that using a combination of different drivers is not supported. All drivers must be of the same model.
|
Currently only 4 drivers are supported, but it would be trivial to support for more. Note that using a combination of different drivers is not supported. All drivers must be of the same model.
|
||||||
|
|
||||||
|
@ -170,7 +174,7 @@ Where LED Index is the position of the LED in the `g_is31_leds` array. The `scal
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Common Configuration :id=common-configuration
|
## Common Configuration {#common-configuration}
|
||||||
|
|
||||||
From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example:
|
From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example:
|
||||||
|
|
||||||
|
@ -203,7 +207,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
||||||
|
|
||||||
`// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type.
|
`// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type.
|
||||||
|
|
||||||
## Flags :id=flags
|
## Flags {#flags}
|
||||||
|
|
||||||
|Define |Value |Description |
|
|Define |Value |Description |
|
||||||
|----------------------------|------|-------------------------------------------------|
|
|----------------------------|------|-------------------------------------------------|
|
||||||
|
@ -215,7 +219,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
||||||
|`LED_FLAG_KEYLIGHT` |`0x04`|If the LED is for key backlight |
|
|`LED_FLAG_KEYLIGHT` |`0x04`|If the LED is for key backlight |
|
||||||
|`LED_FLAG_INDICATOR` |`0x08`|If the LED is for keyboard state indication |
|
|`LED_FLAG_INDICATOR` |`0x08`|If the LED is for keyboard state indication |
|
||||||
|
|
||||||
## Keycodes :id=keycodes
|
## Keycodes {#keycodes}
|
||||||
|
|
||||||
|Key |Aliases |Description |
|
|Key |Aliases |Description |
|
||||||
|-------------------------------|---------|-----------------------------------|
|
|-------------------------------|---------|-----------------------------------|
|
||||||
|
@ -229,7 +233,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
||||||
|`QK_LED_MATRIX_SPEED_UP` |`LM_SPDU`|Increase the animation speed |
|
|`QK_LED_MATRIX_SPEED_UP` |`LM_SPDU`|Increase the animation speed |
|
||||||
|`QK_LED_MATRIX_SPEED_DOWN` |`LM_SPDD`|Decrease the animation speed |
|
|`QK_LED_MATRIX_SPEED_DOWN` |`LM_SPDD`|Decrease the animation speed |
|
||||||
|
|
||||||
## LED Matrix Effects :id=led-matrix-effects
|
## LED Matrix Effects {#led-matrix-effects}
|
||||||
|
|
||||||
These are the effects that are currently available:
|
These are the effects that are currently available:
|
||||||
|
|
||||||
|
@ -290,9 +294,11 @@ You can enable a single effect by defining `ENABLE_[EFFECT_NAME]` in your `confi
|
||||||
|`#define ENABLE_LED_MATRIX_SOLID_SPLASH` |Enables `LED_MATRIX_SOLID_SPLASH` |
|
|`#define ENABLE_LED_MATRIX_SOLID_SPLASH` |Enables `LED_MATRIX_SOLID_SPLASH` |
|
||||||
|`#define ENABLE_LED_MATRIX_SOLID_MULTISPLASH` |Enables `LED_MATRIX_SOLID_MULTISPLASH` |
|
|`#define ENABLE_LED_MATRIX_SOLID_MULTISPLASH` |Enables `LED_MATRIX_SOLID_MULTISPLASH` |
|
||||||
|
|
||||||
?> These modes introduce additional logic that can increase firmware size.
|
::: tip
|
||||||
|
These modes introduce additional logic that can increase firmware size.
|
||||||
|
:::
|
||||||
|
|
||||||
## Custom LED Matrix Effects :id=custom-led-matrix-effects
|
## Custom LED Matrix Effects {#custom-led-matrix-effects}
|
||||||
|
|
||||||
By setting `LED_MATRIX_CUSTOM_USER` (and/or `LED_MATRIX_CUSTOM_KB`) in `rules.mk`, new effects can be defined directly from userspace, without having to edit any QMK core files.
|
By setting `LED_MATRIX_CUSTOM_USER` (and/or `LED_MATRIX_CUSTOM_KB`) in `rules.mk`, new effects can be defined directly from userspace, without having to edit any QMK core files.
|
||||||
|
|
||||||
|
@ -353,7 +359,7 @@ static bool my_cool_effect2(effect_params_t* params) {
|
||||||
For inspiration and examples, check out the built-in effects under `quantum/led_matrix/animations/`.
|
For inspiration and examples, check out the built-in effects under `quantum/led_matrix/animations/`.
|
||||||
|
|
||||||
|
|
||||||
## Additional `config.h` Options :id=additional-configh-options
|
## Additional `config.h` Options {#additional-configh-options}
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define LED_MATRIX_KEYRELEASES // reactive effects respond to keyreleases (instead of keypresses)
|
#define LED_MATRIX_KEYRELEASES // reactive effects respond to keyreleases (instead of keypresses)
|
||||||
|
@ -371,17 +377,17 @@ For inspiration and examples, check out the built-in effects under `quantum/led_
|
||||||
// If reactive effects are enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR
|
// If reactive effects are enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR
|
||||||
```
|
```
|
||||||
|
|
||||||
## EEPROM storage :id=eeprom-storage
|
## EEPROM storage {#eeprom-storage}
|
||||||
|
|
||||||
The EEPROM for it is currently shared with the RGB Matrix system (it's generally assumed only one feature would be used at a time).
|
The EEPROM for it is currently shared with the RGB Matrix system (it's generally assumed only one feature would be used at a time).
|
||||||
|
|
||||||
### Direct Operation :id=direct-operation
|
### Direct Operation {#direct-operation}
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|--------------------------------------------|-------------|
|
|--------------------------------------------|-------------|
|
||||||
|`led_matrix_set_value_all(v)` |Set all of the LEDs to the given value, where `v` is between 0 and 255 (not written to EEPROM) |
|
|`led_matrix_set_value_all(v)` |Set all of the LEDs to the given value, where `v` is between 0 and 255 (not written to EEPROM) |
|
||||||
|`led_matrix_set_value(index, v)` |Set a single LED to the given value, where `v` is between 0 and 255, and `index` is between 0 and `LED_MATRIX_LED_COUNT` (not written to EEPROM) |
|
|`led_matrix_set_value(index, v)` |Set a single LED to the given value, where `v` is between 0 and 255, and `index` is between 0 and `LED_MATRIX_LED_COUNT` (not written to EEPROM) |
|
||||||
|
|
||||||
### Disable/Enable Effects :id=disable-enable-effects
|
### Disable/Enable Effects {#disable-enable-effects}
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|--------------------------------------------|-------------|
|
|--------------------------------------------|-------------|
|
||||||
|`led_matrix_toggle()` |Toggle effect range LEDs between on and off |
|
|`led_matrix_toggle()` |Toggle effect range LEDs between on and off |
|
||||||
|
@ -391,7 +397,7 @@ The EEPROM for it is currently shared with the RGB Matrix system (it's generally
|
||||||
|`led_matrix_disable()` |Turn effect range LEDs off, based on their previous state |
|
|`led_matrix_disable()` |Turn effect range LEDs off, based on their previous state |
|
||||||
|`led_matrix_disable_noeeprom()` |Turn effect range LEDs off, based on their previous state (not written to EEPROM) |
|
|`led_matrix_disable_noeeprom()` |Turn effect range LEDs off, based on their previous state (not written to EEPROM) |
|
||||||
|
|
||||||
### Change Effect Mode :id=change-effect-mode
|
### Change Effect Mode {#change-effect-mode}
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|--------------------------------------------|-------------|
|
|--------------------------------------------|-------------|
|
||||||
|`led_matrix_mode(mode)` |Set the mode, if LED animations are enabled |
|
|`led_matrix_mode(mode)` |Set the mode, if LED animations are enabled |
|
||||||
|
@ -407,7 +413,7 @@ The EEPROM for it is currently shared with the RGB Matrix system (it's generally
|
||||||
|`led_matrix_set_speed(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 |
|
|`led_matrix_set_speed(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 |
|
||||||
|`led_matrix_set_speed_noeeprom(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 (not written to EEPROM) |
|
|`led_matrix_set_speed_noeeprom(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 (not written to EEPROM) |
|
||||||
|
|
||||||
### Change Value :id=change-value
|
### Change Value {#change-value}
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|--------------------------------------------|-------------|
|
|--------------------------------------------|-------------|
|
||||||
|`led_matrix_increase_val()` |Increase the value for effect range LEDs. This wraps around at maximum value |
|
|`led_matrix_increase_val()` |Increase the value for effect range LEDs. This wraps around at maximum value |
|
||||||
|
@ -415,7 +421,7 @@ The EEPROM for it is currently shared with the RGB Matrix system (it's generally
|
||||||
|`led_matrix_decrease_val()` |Decrease the value for effect range LEDs. This wraps around at minimum value |
|
|`led_matrix_decrease_val()` |Decrease the value for effect range LEDs. This wraps around at minimum value |
|
||||||
|`led_matrix_decrease_val_noeeprom()` |Decrease the value for effect range LEDs. This wraps around at minimum value (not written to EEPROM) |
|
|`led_matrix_decrease_val_noeeprom()` |Decrease the value for effect range LEDs. This wraps around at minimum value (not written to EEPROM) |
|
||||||
|
|
||||||
### Query Current Status :id=query-current-status
|
### Query Current Status {#query-current-status}
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|---------------------------------|---------------------------|
|
|---------------------------------|---------------------------|
|
||||||
|`led_matrix_is_enabled()` |Gets current on/off status |
|
|`led_matrix_is_enabled()` |Gets current on/off status |
|
||||||
|
@ -424,9 +430,9 @@ The EEPROM for it is currently shared with the RGB Matrix system (it's generally
|
||||||
|`led_matrix_get_speed()` |Gets current speed |
|
|`led_matrix_get_speed()` |Gets current speed |
|
||||||
|`led_matrix_get_suspend_state()` |Gets current suspend state |
|
|`led_matrix_get_suspend_state()` |Gets current suspend state |
|
||||||
|
|
||||||
## Callbacks :id=callbacks
|
## Callbacks {#callbacks}
|
||||||
|
|
||||||
### Indicators :id=indicators
|
### Indicators {#indicators}
|
||||||
|
|
||||||
If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, then you can use the `led_matrix_indicators_kb` function on the keyboard level source file, or `led_matrix_indicators_user` function in the user `keymap.c`.
|
If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, then you can use the `led_matrix_indicators_kb` function on the keyboard level source file, or `led_matrix_indicators_user` function in the user `keymap.c`.
|
||||||
```c
|
```c
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
|
|
||||||
Macros allow you to send multiple keystrokes when pressing just one key. QMK has a number of ways to define and use macros. These can do anything you want: type common phrases for you, copypasta, repetitive game movements, or even help you code.
|
Macros allow you to send multiple keystrokes when pressing just one key. QMK has a number of ways to define and use macros. These can do anything you want: type common phrases for you, copypasta, repetitive game movements, or even help you code.
|
||||||
|
|
||||||
!> **Security Note**: While it is possible to use macros to send passwords, credit card numbers, and other sensitive information it is a supremely bad idea to do so. Anyone who gets a hold of your keyboard will be able to access that information by opening a text editor.
|
::: warning
|
||||||
|
**Security Note**: While it is possible to use macros to send passwords, credit card numbers, and other sensitive information it is a supremely bad idea to do so. Anyone who gets a hold of your keyboard will be able to access that information by opening a text editor.
|
||||||
|
:::
|
||||||
|
|
||||||
## Using Macros In JSON Keymaps
|
## Using Macros In JSON Keymaps
|
||||||
|
|
||||||
You can define up to 32 macros in a `keymap.json` file, as used by [Configurator](newbs_building_firmware_configurator.md), and `qmk compile`. You can define these macros in a list under the `macros` keyword, like this:
|
You can define up to 32 macros in a `keymap.json` file, as used by [Configurator](newbs_building_firmware_configurator), and `qmk compile`. You can define these macros in a list under the `macros` keyword, like this:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -84,7 +86,7 @@ All objects have one required key: `action`. This tells QMK what the object does
|
||||||
Only basic keycodes (prefixed by `KC_`) are supported. Do not include the `KC_` prefix when listing keycodes.
|
Only basic keycodes (prefixed by `KC_`) are supported. Do not include the `KC_` prefix when listing keycodes.
|
||||||
|
|
||||||
* `beep`
|
* `beep`
|
||||||
* Play a bell if the keyboard has [audio enabled](feature_audio.md).
|
* Play a bell if the keyboard has [audio enabled](feature_audio).
|
||||||
* Example: `{"action": "beep"}`
|
* Example: `{"action": "beep"}`
|
||||||
* `delay`
|
* `delay`
|
||||||
* Pause macro playback. Duration is specified in milliseconds (ms).
|
* Pause macro playback. Duration is specified in milliseconds (ms).
|
||||||
|
@ -106,7 +108,7 @@ Only basic keycodes (prefixed by `KC_`) are supported. Do not include the `KC_`
|
||||||
|
|
||||||
### `SEND_STRING()` & `process_record_user`
|
### `SEND_STRING()` & `process_record_user`
|
||||||
|
|
||||||
See also: [Send String](feature_send_string.md)
|
See also: [Send String](feature_send_string)
|
||||||
|
|
||||||
Sometimes you want a key to type out words or phrases. For the most common situations, we've provided `SEND_STRING()`, which will type out a string (i.e. a sequence of characters) for you. All ASCII characters that are easily translatable to a keycode are supported (e.g. `qmk 123\n\t`).
|
Sometimes you want a key to type out words or phrases. For the most common situations, we've provided `SEND_STRING()`, which will type out a string (i.e. a sequence of characters) for you. All ASCII characters that are easily translatable to a keycode are supported (e.g. `qmk 123\n\t`).
|
||||||
|
|
||||||
|
@ -146,7 +148,7 @@ If yes, we send the string `"QMK is the best thing ever!"` to the computer via t
|
||||||
We return `true` to indicate to the caller that the key press we just processed should continue to be processed as normal (as we didn't replace or alter the functionality).
|
We return `true` to indicate to the caller that the key press we just processed should continue to be processed as normal (as we didn't replace or alter the functionality).
|
||||||
Finally, we define the keymap so that the first button activates our macro and the second button is just an escape button.
|
Finally, we define the keymap so that the first button activates our macro and the second button is just an escape button.
|
||||||
|
|
||||||
?>It is recommended to use the SAFE_RANGE macro as per [Customizing Functionality](custom_quantum_functions.md).
|
?>It is recommended to use the SAFE_RANGE macro as per [Customizing Functionality](custom_quantum_functions).
|
||||||
|
|
||||||
You might want to add more than one macro.
|
You might want to add more than one macro.
|
||||||
You can do that by adding another keycode and adding another case to the switch statement, like so:
|
You can do that by adding another keycode and adding another case to the switch statement, like so:
|
||||||
|
@ -195,7 +197,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
?> An enumerated list of custom keycodes (`enum custom_keycodes`) must be declared before `keymaps[]` array, `process_record_user()` and any other function that use the list for the compiler to recognise it.
|
::: tip
|
||||||
|
An enumerated list of custom keycodes (`enum custom_keycodes`) must be declared before `keymaps[]` array, `process_record_user()` and any other function that use the list for the compiler to recognise it.
|
||||||
|
:::
|
||||||
|
|
||||||
#### Advanced Macros
|
#### Advanced Macros
|
||||||
|
|
||||||
|
@ -315,7 +319,9 @@ SEND_STRING(".."SS_TAP(X_END));
|
||||||
|
|
||||||
There are some functions you may find useful in macro-writing. Keep in mind that while you can write some fairly advanced code within a macro, if your functionality gets too complex you may want to define a custom keycode instead. Macros are meant to be simple.
|
There are some functions you may find useful in macro-writing. Keep in mind that while you can write some fairly advanced code within a macro, if your functionality gets too complex you may want to define a custom keycode instead. Macros are meant to be simple.
|
||||||
|
|
||||||
?> You can also use the functions described in [Useful function](ref_functions.md) and [Checking modifier state](feature_advanced_keycodes#checking-modifier-state) for additional functionality. For example, `reset_keyboard()` allows you to reset the keyboard as part of a macro and `get_mods() & MOD_MASK_SHIFT` lets you check for the existence of active shift modifiers.
|
::: tip
|
||||||
|
You can also use the functions described in [Useful function](ref_functions) and [Checking modifier state](feature_advanced_keycodes#checking-modifier-state) for additional functionality. For example, `reset_keyboard()` allows you to reset the keyboard as part of a macro and `get_mods() & MOD_MASK_SHIFT` lets you check for the existence of active shift modifiers.
|
||||||
|
:::
|
||||||
|
|
||||||
#### `record->event.pressed`
|
#### `record->event.pressed`
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ To enable advanced MIDI, add the following to your `config.h`:
|
||||||
|
|
||||||
If you're aiming to emulate the features of something like a Launchpad or other MIDI controller you'll need to access the internal MIDI device directly.
|
If you're aiming to emulate the features of something like a Launchpad or other MIDI controller you'll need to access the internal MIDI device directly.
|
||||||
|
|
||||||
Because there are so many possible CC messages, not all of them are implemented as keycodes. Additionally, you might need to provide more than just two values that you would get from a keycode (pressed and released) - for example, the analog values from a fader or a potentiometer. So, you will need to implement [custom keycodes](feature_macros.md) if you want to use them in your keymap directly using `process_record_user()`.
|
Because there are so many possible CC messages, not all of them are implemented as keycodes. Additionally, you might need to provide more than just two values that you would get from a keycode (pressed and released) - for example, the analog values from a fader or a potentiometer. So, you will need to implement [custom keycodes](feature_macros) if you want to use them in your keymap directly using `process_record_user()`.
|
||||||
|
|
||||||
|
|
||||||
For reference of all the possible control code numbers see [MIDI Specification](#midi-specification)
|
For reference of all the possible control code numbers see [MIDI Specification](#midi-specification)
|
||||||
|
@ -258,7 +258,7 @@ For the above, the `MI_C` keycode will produce a C3 (note number 48), and so on.
|
||||||
<!--
|
<!--
|
||||||
#### QMK Internals (Autogenerated)
|
#### QMK Internals (Autogenerated)
|
||||||
|
|
||||||
* [Internals/MIDI Device Setup Process](internals/midi_device_setup_process.md)
|
* [Internals/MIDI Device Setup Process](internals/midi_device_setup_process)
|
||||||
* [Internals/MIDI Device](internals/midi_device.md)
|
* [Internals/MIDI Device](internals/midi_device)
|
||||||
* [Internals/MIDI Util](internals/midi_util.md)
|
* [Internals/MIDI Util](internals/midi_util)
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -205,4 +205,4 @@ Tips:
|
||||||
|
|
||||||
## Use with PS/2 Mouse and Pointing Device
|
## Use with PS/2 Mouse and Pointing Device
|
||||||
|
|
||||||
Mouse keys button state is shared with [PS/2 mouse](feature_ps2_mouse.md) and [pointing device](feature_pointing_device.md) so mouse keys button presses can be used for clicks and drags.
|
Mouse keys button state is shared with [PS/2 mouse](feature_ps2_mouse) and [pointing device](feature_pointing_device) so mouse keys button presses can be used for clicks and drags.
|
||||||
|
|
|
@ -102,7 +102,9 @@ bool oled_task_user(void) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
?> The default font file is located at `drivers/oled/glcdfont.c` and its location can be overwritten with the `OLED_FONT_H` configuration option. Font file content can be edited with external tools such as [Helix Font Editor](https://helixfonteditor.netlify.app/) and [Logo Editor](https://joric.github.io/qle/).
|
::: tip
|
||||||
|
The default font file is located at `drivers/oled/glcdfont.c` and its location can be overwritten with the `OLED_FONT_H` configuration option. Font file content can be edited with external tools such as [Helix Font Editor](https://helixfonteditor.netlify.app/) and [Logo Editor](https://joric.github.io/qle/).
|
||||||
|
:::
|
||||||
|
|
||||||
## Buffer Read Example
|
## Buffer Read Example
|
||||||
For some purposes, you may need to read the current state of the OLED display
|
For some purposes, you may need to read the current state of the OLED display
|
||||||
|
@ -243,7 +245,9 @@ These configuration options should be placed in `config.h`. Example:
|
||||||
|`OLED_DISPLAY_128X128`|*Not defined* |Changes the display defines for use with 128x128 displays. |
|
|`OLED_DISPLAY_128X128`|*Not defined* |Changes the display defines for use with 128x128 displays. |
|
||||||
|`OLED_DISPLAY_CUSTOM` |*Not defined* |Changes the display defines for use with custom displays.<br>Requires user to implement the below defines. |
|
|`OLED_DISPLAY_CUSTOM` |*Not defined* |Changes the display defines for use with custom displays.<br>Requires user to implement the below defines. |
|
||||||
|
|
||||||
!> 64x128 and 128x128 displays default to the SH1107 IC type, as these heights are not supported by the other IC types.
|
::: warning
|
||||||
|
64x128 and 128x128 displays default to the SH1107 IC type, as these heights are not supported by the other IC types.
|
||||||
|
:::
|
||||||
|
|
||||||
|Define |Default |Description |
|
|Define |Default |Description |
|
||||||
| --------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
| --------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
@ -391,9 +395,9 @@ void oled_write_ln_P(const char *data, bool invert);
|
||||||
// Writes a PROGMEM string to the buffer at current cursor position
|
// Writes a PROGMEM string to the buffer at current cursor position
|
||||||
void oled_write_raw_P(const char *data, uint16_t size);
|
void oled_write_raw_P(const char *data, uint16_t size);
|
||||||
#else
|
#else
|
||||||
# define oled_write_P(data, invert) oled_write(data, invert)
|
# define oled_write_P(data, invert) oled_write(data, invert)
|
||||||
# define oled_write_ln_P(data, invert) oled_write_ln(data, invert)
|
# define oled_write_ln_P(data, invert) oled_write_ln(data, invert)
|
||||||
# define oled_write_raw_P(data, size) oled_write_raw(data, size)
|
# define oled_write_raw_P(data, size) oled_write_raw(data, size)
|
||||||
#endif // defined(__AVR__)
|
#endif // defined(__AVR__)
|
||||||
|
|
||||||
// Can be used to manually turn on the screen if it is off
|
// Can be used to manually turn on the screen if it is off
|
||||||
|
@ -462,9 +466,13 @@ uint8_t oled_max_chars(void);
|
||||||
uint8_t oled_max_lines(void);
|
uint8_t oled_max_lines(void);
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Scrolling is unsupported on the SH1106 and SH1107.
|
::: warning
|
||||||
|
Scrolling is unsupported on the SH1106 and SH1107.
|
||||||
|
:::
|
||||||
|
|
||||||
!> Scrolling does not work properly on the SSD1306 if the display width is smaller than 128.
|
::: warning
|
||||||
|
Scrolling does not work properly on the SSD1306 if the display width is smaller than 128.
|
||||||
|
:::
|
||||||
|
|
||||||
## SSD1306.h Driver Conversion Guide
|
## SSD1306.h Driver Conversion Guide
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,12 @@ enum {
|
||||||
} os_variant_t;
|
} os_variant_t;
|
||||||
```
|
```
|
||||||
|
|
||||||
?> Note that it takes some time after firmware is booted to detect the OS.
|
::: tip
|
||||||
|
Note that it takes some time after firmware is booted to detect the OS.
|
||||||
|
:::
|
||||||
This time is quite short, probably hundreds of milliseconds, but this data may be not ready in keyboard and layout setup functions which run very early during firmware startup.
|
This time is quite short, probably hundreds of milliseconds, but this data may be not ready in keyboard and layout setup functions which run very early during firmware startup.
|
||||||
|
|
||||||
## Callbacks :id=callbacks
|
## Callbacks {#callbacks}
|
||||||
|
|
||||||
If you want to perform custom actions when the OS is detected, then you can use the `process_detected_host_os_kb` function on the keyboard level source file, or `process_detected_host_os_user` function in the user `keymap.c`.
|
If you want to perform custom actions when the OS is detected, then you can use the `process_detected_host_os_kb` function on the keyboard level source file, or `process_detected_host_os_user` function in the user `keymap.c`.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Pointing Device :id=pointing-device
|
# Pointing Device {#pointing-device}
|
||||||
|
|
||||||
Pointing Device is a generic name for a feature intended to be generic: moving the system pointer around. There are certainly other options for it - like mousekeys - but this aims to be easily modifiable and hardware driven. You can implement custom keys to control functionality, or you can gather information from other peripherals and insert it directly here - let QMK handle the processing for you.
|
Pointing Device is a generic name for a feature intended to be generic: moving the system pointer around. There are certainly other options for it - like mousekeys - but this aims to be easily modifiable and hardware driven. You can implement custom keys to control functionality, or you can gather information from other peripherals and insert it directly here - let QMK handle the processing for you.
|
||||||
|
|
||||||
|
@ -112,7 +112,9 @@ Specific device profiles are provided which set the required values for dimensio
|
||||||
| `AZOTEQ_IQS5XX_TPS43` | (Pick One) Sets resolution/mm to TPS43 specifications. |
|
| `AZOTEQ_IQS5XX_TPS43` | (Pick One) Sets resolution/mm to TPS43 specifications. |
|
||||||
| `AZOTEQ_IQS5XX_TPS65` | (Pick One) Sets resolution/mm to TPS65 specifications. |
|
| `AZOTEQ_IQS5XX_TPS65` | (Pick One) Sets resolution/mm to TPS65 specifications. |
|
||||||
|
|
||||||
?> If using one of the above defines you can skip to gesture settings.
|
::: tip
|
||||||
|
If using one of the above defines you can skip to gesture settings.
|
||||||
|
:::
|
||||||
|
|
||||||
| Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
| -------------------------------- | ---------------------------------------------------------- | ------------- |
|
| -------------------------------- | ---------------------------------------------------------- | ------------- |
|
||||||
|
@ -383,7 +385,9 @@ uint16_t pointing_device_driver_get_cpi(void) { return 0; }
|
||||||
void pointing_device_driver_set_cpi(uint16_t cpi) {}
|
void pointing_device_driver_set_cpi(uint16_t cpi) {}
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Ideally, new sensor hardware should be added to `drivers/sensors/` and `quantum/pointing_device_drivers.c`, but there may be cases where it's very specific to the hardware. So these functions are provided, just in case.
|
::: warning
|
||||||
|
Ideally, new sensor hardware should be added to `drivers/sensors/` and `quantum/pointing_device_drivers.c`, but there may be cases where it's very specific to the hardware. So these functions are provided, just in case.
|
||||||
|
:::
|
||||||
|
|
||||||
## Common Configuration
|
## Common Configuration
|
||||||
|
|
||||||
|
@ -404,15 +408,19 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {}
|
||||||
| `POINTING_DEVICE_SDIO_PIN` | (Optional) Provides a default SDIO pin, useful for supporting multiple sensor configs. | _not defined_ |
|
| `POINTING_DEVICE_SDIO_PIN` | (Optional) Provides a default SDIO pin, useful for supporting multiple sensor configs. | _not defined_ |
|
||||||
| `POINTING_DEVICE_SCLK_PIN` | (Optional) Provides a default SCLK pin, useful for supporting multiple sensor configs. | _not defined_ |
|
| `POINTING_DEVICE_SCLK_PIN` | (Optional) Provides a default SCLK pin, useful for supporting multiple sensor configs. | _not defined_ |
|
||||||
|
|
||||||
!> When using `SPLIT_POINTING_ENABLE` the `POINTING_DEVICE_MOTION_PIN` functionality is not supported and `POINTING_DEVICE_TASK_THROTTLE_MS` will default to `1`. Increasing this value will increase transport performance at the cost of possible mouse responsiveness.
|
::: warning
|
||||||
|
When using `SPLIT_POINTING_ENABLE` the `POINTING_DEVICE_MOTION_PIN` functionality is not supported and `POINTING_DEVICE_TASK_THROTTLE_MS` will default to `1`. Increasing this value will increase transport performance at the cost of possible mouse responsiveness.
|
||||||
|
:::
|
||||||
|
|
||||||
The `POINTING_DEVICE_CS_PIN`, `POINTING_DEVICE_SDIO_PIN`, and `POINTING_DEVICE_SCLK_PIN` provide a convenient way to define a single pin that can be used for an interchangeable sensor config. This allows you to have a single config, without defining each device. Each sensor allows for this to be overridden with their own defines.
|
The `POINTING_DEVICE_CS_PIN`, `POINTING_DEVICE_SDIO_PIN`, and `POINTING_DEVICE_SCLK_PIN` provide a convenient way to define a single pin that can be used for an interchangeable sensor config. This allows you to have a single config, without defining each device. Each sensor allows for this to be overridden with their own defines.
|
||||||
|
|
||||||
!> Any pointing device with a lift/contact status can integrate inertial cursor feature into its driver, controlled by `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE`. e.g. PMW3360 can use Lift_Stat from Motion register. Note that `POINTING_DEVICE_MOTION_PIN` cannot be used with this feature; continuous polling of `get_report()` is needed to generate glide reports.
|
::: warning
|
||||||
|
Any pointing device with a lift/contact status can integrate inertial cursor feature into its driver, controlled by `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE`. e.g. PMW3360 can use Lift_Stat from Motion register. Note that `POINTING_DEVICE_MOTION_PIN` cannot be used with this feature; continuous polling of `get_report()` is needed to generate glide reports.
|
||||||
|
:::
|
||||||
|
|
||||||
## Split Keyboard Configuration
|
## Split Keyboard Configuration
|
||||||
|
|
||||||
The following configuration options are only available when using `SPLIT_POINTING_ENABLE` see [data sync options](feature_split_keyboard.md?id=data-sync-options). The rotation and invert `*_RIGHT` options are only used with `POINTING_DEVICE_COMBINED`. If using `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` use the common configuration above to configure your pointing device.
|
The following configuration options are only available when using `SPLIT_POINTING_ENABLE` see [data sync options](feature_split_keyboard#data-sync-options). The rotation and invert `*_RIGHT` options are only used with `POINTING_DEVICE_COMBINED`. If using `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` use the common configuration above to configure your pointing device.
|
||||||
|
|
||||||
| Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
| ------------------------------------ | ----------------------------------------------------------------------------------------------------- | ------------- |
|
| ------------------------------------ | ----------------------------------------------------------------------------------------------------- | ------------- |
|
||||||
|
@ -425,7 +433,9 @@ The following configuration options are only available when using `SPLIT_POINTIN
|
||||||
| `POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ |
|
| `POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ |
|
||||||
| `POINTING_DEVICE_INVERT_Y_RIGHT` | (Optional) Inverts the Y axis report. | _not defined_ |
|
| `POINTING_DEVICE_INVERT_Y_RIGHT` | (Optional) Inverts the Y axis report. | _not defined_ |
|
||||||
|
|
||||||
!> If there is a `_RIGHT` configuration option or callback, the [common configuration](feature_pointing_device.md?id=common-configuration) option will work for the left. For correct left/right detection you should setup a [handedness option](feature_split_keyboard?id=setting-handedness), `EE_HANDS` is usually a good option for an existing board that doesn't do handedness by hardware.
|
::: warning
|
||||||
|
If there is a `_RIGHT` configuration option or callback, the [common configuration](feature_pointing_device#common-configuration) option will work for the left. For correct left/right detection you should setup a [handedness option](feature_split_keyboard#setting-handedness), `EE_HANDS` is usually a good option for an existing board that doesn't do handedness by hardware.
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
## Callbacks and Functions
|
## Callbacks and Functions
|
||||||
|
@ -448,7 +458,7 @@ The following configuration options are only available when using `SPLIT_POINTIN
|
||||||
|
|
||||||
## Split Keyboard Callbacks and Functions
|
## Split Keyboard Callbacks and Functions
|
||||||
|
|
||||||
The combined functions below are only available when using `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED`. The 2 callbacks `pointing_device_task_combined_*` replace the single sided equivalents above. See the [combined pointing devices example](feature_pointing_device.md?id=combined-pointing-devices)
|
The combined functions below are only available when using `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED`. The 2 callbacks `pointing_device_task_combined_*` replace the single sided equivalents above. See the [combined pointing devices example](feature_pointing_device#combined-pointing-devices)
|
||||||
|
|
||||||
| Function | Description |
|
| Function | Description |
|
||||||
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||||
|
@ -673,11 +683,13 @@ If you are having issues with pointing device drivers debug messages can be enab
|
||||||
#define POINTING_DEVICE_DEBUG
|
#define POINTING_DEVICE_DEBUG
|
||||||
```
|
```
|
||||||
|
|
||||||
?> The messages will be printed out to the `CONSOLE` output. For additional information, refer to [Debugging/Troubleshooting QMK](faq_debug.md).
|
::: tip
|
||||||
|
The messages will be printed out to the `CONSOLE` output. For additional information, refer to [Debugging/Troubleshooting QMK](faq_debug).
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
# Automatic Mouse Layer :id=pointing-device-auto-mouse
|
# Automatic Mouse Layer {#pointing-device-auto-mouse}
|
||||||
|
|
||||||
When using a pointing device combined with a keyboard the mouse buttons are often kept on a separate layer from the default keyboard layer, which requires pressing or holding a key to change layers before using the mouse. To make this easier and more efficient an additional pointing device feature may be enabled that will automatically activate a target layer as soon as the pointing device is active _(in motion, mouse button pressed etc.)_ and deactivate the target layer after a set time.
|
When using a pointing device combined with a keyboard the mouse buttons are often kept on a separate layer from the default keyboard layer, which requires pressing or holding a key to change layers before using the mouse. To make this easier and more efficient an additional pointing device feature may be enabled that will automatically activate a target layer as soon as the pointing device is active _(in motion, mouse button pressed etc.)_ and deactivate the target layer after a set time.
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
# Programmable Button :id=programmable-button
|
# Programmable Button {#programmable-button}
|
||||||
|
|
||||||
Programmable Buttons are keys that have no predefined meaning. This means they can be processed on the host side by custom software without the operating system trying to interpret them.
|
Programmable Buttons are keys that have no predefined meaning. This means they can be processed on the host side by custom software without the operating system trying to interpret them.
|
||||||
|
|
||||||
The keycodes are emitted according to the HID Telephony Device page (`0x0B`), Programmable Button usage (`0x09`). On Linux (> 5.14) they are handled automatically and translated to `KEY_MACRO#` keycodes (up to `KEY_MACRO30`).
|
The keycodes are emitted according to the HID Telephony Device page (`0x0B`), Programmable Button usage (`0x09`). On Linux (> 5.14) they are handled automatically and translated to `KEY_MACRO#` keycodes (up to `KEY_MACRO30`).
|
||||||
|
|
||||||
?> Currently there is no known support in Windows or macOS. It may be possible to write a custom HID driver to receive these usages, but this is out of the scope of the QMK documentation.
|
::: tip
|
||||||
|
Currently there is no known support in Windows or macOS. It may be possible to write a custom HID driver to receive these usages, but this is out of the scope of the QMK documentation.
|
||||||
|
:::
|
||||||
|
|
||||||
## Usage :id=usage
|
## Usage {#usage}
|
||||||
|
|
||||||
Add the following to your `rules.mk`:
|
Add the following to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -14,7 +16,7 @@ Add the following to your `rules.mk`:
|
||||||
PROGRAMMABLE_BUTTON_ENABLE = yes
|
PROGRAMMABLE_BUTTON_ENABLE = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
## Keycodes :id=keycodes
|
## Keycodes {#keycodes}
|
||||||
|
|
||||||
|Key |Aliases|Description |
|
|Key |Aliases|Description |
|
||||||
|---------------------------|-------|----------------------|
|
|---------------------------|-------|----------------------|
|
||||||
|
@ -51,94 +53,94 @@ PROGRAMMABLE_BUTTON_ENABLE = yes
|
||||||
|`QK_PROGRAMMABLE_BUTTON_31`|`PB_31`|Programmable button 31|
|
|`QK_PROGRAMMABLE_BUTTON_31`|`PB_31`|Programmable button 31|
|
||||||
|`QK_PROGRAMMABLE_BUTTON_32`|`PB_32`|Programmable button 32|
|
|`QK_PROGRAMMABLE_BUTTON_32`|`PB_32`|Programmable button 32|
|
||||||
|
|
||||||
## API :id=api
|
## API {#api}
|
||||||
|
|
||||||
### `void programmable_button_clear(void)` :id=api-programmable-button-clear
|
### `void programmable_button_clear(void)` {#api-programmable-button-clear}
|
||||||
|
|
||||||
Clear the programmable button report.
|
Clear the programmable button report.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void programmable_button_add(uint8_t index)` :id=api-programmable-button-add
|
### `void programmable_button_add(uint8_t index)` {#api-programmable-button-add}
|
||||||
|
|
||||||
Set the state of a button.
|
Set the state of a button.
|
||||||
|
|
||||||
#### Arguments :id=api-programmable-button-add-arguments
|
#### Arguments {#api-programmable-button-add-arguments}
|
||||||
|
|
||||||
- `uint8_t index`
|
- `uint8_t index`
|
||||||
The index of the button to press, from 0 to 31.
|
The index of the button to press, from 0 to 31.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void programmable_button_remove(uint8_t index)` :id=api-programmable-button-remove
|
### `void programmable_button_remove(uint8_t index)` {#api-programmable-button-remove}
|
||||||
|
|
||||||
Reset the state of a button.
|
Reset the state of a button.
|
||||||
|
|
||||||
#### Arguments :id=api-programmable-button-remove-arguments
|
#### Arguments {#api-programmable-button-remove-arguments}
|
||||||
|
|
||||||
- `uint8_t index`
|
- `uint8_t index`
|
||||||
The index of the button to release, from 0 to 31.
|
The index of the button to release, from 0 to 31.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void programmable_button_register(uint8_t index)` :id=api-programmable-button-register
|
### `void programmable_button_register(uint8_t index)` {#api-programmable-button-register}
|
||||||
|
|
||||||
Set the state of a button, and flush the report.
|
Set the state of a button, and flush the report.
|
||||||
|
|
||||||
#### Arguments :id=api-programmable-button-register-arguments
|
#### Arguments {#api-programmable-button-register-arguments}
|
||||||
|
|
||||||
- `uint8_t index`
|
- `uint8_t index`
|
||||||
The index of the button to press, from 0 to 31.
|
The index of the button to press, from 0 to 31.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void programmable_button_unregister(uint8_t index)` :id=api-programmable-button-unregister
|
### `void programmable_button_unregister(uint8_t index)` {#api-programmable-button-unregister}
|
||||||
|
|
||||||
Reset the state of a button, and flush the report.
|
Reset the state of a button, and flush the report.
|
||||||
|
|
||||||
#### Arguments :id=api-programmable-button-unregister-arguments
|
#### Arguments {#api-programmable-button-unregister-arguments}
|
||||||
|
|
||||||
- `uint8_t index`
|
- `uint8_t index`
|
||||||
The index of the button to release, from 0 to 31.
|
The index of the button to release, from 0 to 31.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `bool programmable_button_is_on(uint8_t index)` :id=api-programmable-button-is-on
|
### `bool programmable_button_is_on(uint8_t index)` {#api-programmable-button-is-on}
|
||||||
|
|
||||||
Get the state of a button.
|
Get the state of a button.
|
||||||
|
|
||||||
#### Arguments :id=api-programmable-button-is-on-arguments
|
#### Arguments {#api-programmable-button-is-on-arguments}
|
||||||
|
|
||||||
- `uint8_t index`
|
- `uint8_t index`
|
||||||
The index of the button to check, from 0 to 31.
|
The index of the button to check, from 0 to 31.
|
||||||
|
|
||||||
#### Return Value :id=api-programmable-button-is-on-return
|
#### Return Value {#api-programmable-button-is-on-return}
|
||||||
|
|
||||||
`true` if the button is pressed.
|
`true` if the button is pressed.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void programmable_button_flush(void)` :id=api-programmable-button-flush
|
### `void programmable_button_flush(void)` {#api-programmable-button-flush}
|
||||||
|
|
||||||
Send the programmable button report to the host.
|
Send the programmable button report to the host.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `uint32_t programmable_button_get_report(void)` :id=api-programmable-button-get-report
|
### `uint32_t programmable_button_get_report(void)` {#api-programmable-button-get-report}
|
||||||
|
|
||||||
Get the programmable button report.
|
Get the programmable button report.
|
||||||
|
|
||||||
#### Return Value :id=api-programmable-button-get-report-return
|
#### Return Value {#api-programmable-button-get-report-return}
|
||||||
|
|
||||||
The bitmask of programmable button states.
|
The bitmask of programmable button states.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void programmable_button_set_report(uint32_t report)` :id=api-programmable-button-set-report
|
### `void programmable_button_set_report(uint32_t report)` {#api-programmable-button-set-report}
|
||||||
|
|
||||||
Set the programmable button report.
|
Set the programmable button report.
|
||||||
|
|
||||||
#### Arguments :id=api-programmable-button-set-report-arguments
|
#### Arguments {#api-programmable-button-set-report-arguments}
|
||||||
|
|
||||||
- `uint32_t report`
|
- `uint32_t report`
|
||||||
A bitmask of programmable button states.
|
A bitmask of programmable button states.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# PS/2 Mouse Support :id=ps2-mouse-support
|
# PS/2 Mouse Support {#ps2-mouse-support}
|
||||||
|
|
||||||
Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device.
|
Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device.
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ To hook up a Trackpoint, you need to obtain a Trackpoint module (i.e. harvest fr
|
||||||
|
|
||||||
There are three available modes for hooking up PS/2 devices: USART (best), interrupts (better) or busywait (not recommended).
|
There are three available modes for hooking up PS/2 devices: USART (best), interrupts (better) or busywait (not recommended).
|
||||||
|
|
||||||
## The Circuitry between Trackpoint and Controller :id=the-circuitry-between-trackpoint-and-controller
|
## The Circuitry between Trackpoint and Controller {#the-circuitry-between-trackpoint-and-controller}
|
||||||
|
|
||||||
To get the things working, a 4.7K drag is needed between the two lines DATA and CLK and the line 5+.
|
To get the things working, a 4.7K drag is needed between the two lines DATA and CLK and the line 5+.
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ MODULE 5+ --------+--+--------- PWR CONTROLLER
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Busywait Version :id=busywait-version
|
## Busywait Version {#busywait-version}
|
||||||
|
|
||||||
Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible.
|
Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible.
|
||||||
|
|
||||||
|
@ -40,12 +40,12 @@ In your keyboard config.h:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#ifdef PS2_DRIVER_BUSYWAIT
|
#ifdef PS2_DRIVER_BUSYWAIT
|
||||||
# define PS2_CLOCK_PIN D1
|
# define PS2_CLOCK_PIN D1
|
||||||
# define PS2_DATA_PIN D2
|
# define PS2_DATA_PIN D2
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
### Interrupt Version (AVR/ATMega32u4) :id=interrupt-version-avr
|
### Interrupt Version (AVR/ATMega32u4) {#interrupt-version-avr}
|
||||||
|
|
||||||
The following example uses D2 for clock and D5 for data. You can use any INT or PCINT pin for clock, and any pin for data.
|
The following example uses D2 for clock and D5 for data. You can use any INT or PCINT pin for clock, and any pin for data.
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ In your keyboard config.h:
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
### Interrupt Version (ARM chibios) :id=interrupt-version-chibios
|
### Interrupt Version (ARM chibios) {#interrupt-version-chibios}
|
||||||
|
|
||||||
Pretty much any two pins can be used for the (software) interrupt variant on ARM cores. The example below uses A8 for clock, and A9 for data.
|
Pretty much any two pins can be used for the (software) interrupt variant on ARM cores. The example below uses A8 for clock, and A9 for data.
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ And in the chibios specifig halconf.h:
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### USART Version :id=usart-version
|
### USART Version {#usart-version}
|
||||||
|
|
||||||
To use USART on the ATMega32u4, you have to use PD5 for clock and PD2 for data. If one of those are unavailable, you need to use interrupt version.
|
To use USART on the ATMega32u4, you have to use PD5 for clock and PD2 for data. If one of those are unavailable, you need to use interrupt version.
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ In your keyboard config.h:
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
### RP2040 PIO Version :id=rp2040-pio-version
|
### RP2040 PIO Version {#rp2040-pio-version}
|
||||||
|
|
||||||
The `PIO` subsystem is a Raspberry Pi RP2040 specific implementation, using the integrated PIO peripheral and is therefore only available on this MCU.
|
The `PIO` subsystem is a Raspberry Pi RP2040 specific implementation, using the integrated PIO peripheral and is therefore only available on this MCU.
|
||||||
|
|
||||||
|
@ -178,9 +178,9 @@ Example info.json content:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Additional Settings :id=additional-settings
|
## Additional Settings {#additional-settings}
|
||||||
|
|
||||||
### PS/2 Mouse Features :id=ps2-mouse-features
|
### PS/2 Mouse Features {#ps2-mouse-features}
|
||||||
|
|
||||||
These enable settings supported by the PS/2 mouse protocol.
|
These enable settings supported by the PS/2 mouse protocol.
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution);
|
||||||
void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate);
|
void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Fine Control :id=fine-control
|
### Fine Control {#fine-control}
|
||||||
|
|
||||||
Use the following defines to change the sensitivity and speed of the mouse.
|
Use the following defines to change the sensitivity and speed of the mouse.
|
||||||
Note: you can also use `ps2_mouse_set_resolution` for the same effect (not supported on most touchpads).
|
Note: you can also use `ps2_mouse_set_resolution` for the same effect (not supported on most touchpads).
|
||||||
|
@ -232,7 +232,7 @@ Note: you can also use `ps2_mouse_set_resolution` for the same effect (not suppo
|
||||||
#define PS2_MOUSE_V_MULTIPLIER 1
|
#define PS2_MOUSE_V_MULTIPLIER 1
|
||||||
```
|
```
|
||||||
|
|
||||||
### Scroll Button :id=scroll-button
|
### Scroll Button {#scroll-button}
|
||||||
|
|
||||||
If you're using a trackpoint, you will likely want to be able to use it for scrolling.
|
If you're using a trackpoint, you will likely want to be able to use it for scrolling.
|
||||||
It's possible to enable a "scroll button/s" that when pressed will cause the mouse to scroll instead of moving.
|
It's possible to enable a "scroll button/s" that when pressed will cause the mouse to scroll instead of moving.
|
||||||
|
@ -279,7 +279,7 @@ Fine control over the scrolling is supported with the following defines:
|
||||||
#define PS2_MOUSE_SCROLL_DIVISOR_V 2
|
#define PS2_MOUSE_SCROLL_DIVISOR_V 2
|
||||||
```
|
```
|
||||||
|
|
||||||
### Invert Mouse buttons :id=invert-buttons
|
### Invert Mouse buttons {#invert-buttons}
|
||||||
|
|
||||||
To invert the left & right buttons you can put:
|
To invert the left & right buttons you can put:
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ To invert the left & right buttons you can put:
|
||||||
|
|
||||||
into config.h.
|
into config.h.
|
||||||
|
|
||||||
### Invert Mouse and Scroll Axes :id=invert-mouse-and-scroll-axes
|
### Invert Mouse and Scroll Axes {#invert-mouse-and-scroll-axes}
|
||||||
|
|
||||||
To invert the X and Y axes you can put:
|
To invert the X and Y axes you can put:
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ To reverse the scroll axes you can put:
|
||||||
|
|
||||||
into config.h.
|
into config.h.
|
||||||
|
|
||||||
### Rotate Mouse Axes :id=rotate-mouse-axes
|
### Rotate Mouse Axes {#rotate-mouse-axes}
|
||||||
|
|
||||||
Transform the output of the device with a clockwise rotation of 90, 180, or 270
|
Transform the output of the device with a clockwise rotation of 90, 180, or 270
|
||||||
degrees.
|
degrees.
|
||||||
|
@ -328,7 +328,7 @@ be North-facing, compensate as follows:
|
||||||
#define PS2_MOUSE_ROTATE 90 /* Compensate for West-facing device orientation. */
|
#define PS2_MOUSE_ROTATE 90 /* Compensate for West-facing device orientation. */
|
||||||
```
|
```
|
||||||
|
|
||||||
### Debug Settings :id=debug-settings
|
### Debug Settings {#debug-settings}
|
||||||
|
|
||||||
To debug the mouse, add `debug_mouse = true` or enable via bootmagic.
|
To debug the mouse, add `debug_mouse = true` or enable via bootmagic.
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ To debug the mouse, add `debug_mouse = true` or enable via bootmagic.
|
||||||
#define PS2_MOUSE_DEBUG_RAW
|
#define PS2_MOUSE_DEBUG_RAW
|
||||||
```
|
```
|
||||||
|
|
||||||
### Movement Hook :id=movement-hook
|
### Movement Hook {#movement-hook}
|
||||||
|
|
||||||
Process mouse movement in the keymap before it is sent to the host. Example
|
Process mouse movement in the keymap before it is sent to the host. Example
|
||||||
uses include filtering noise, adding acceleration, and automatically activating
|
uses include filtering noise, adding acceleration, and automatically activating
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Raw HID :id=raw-hid
|
# Raw HID {#raw-hid}
|
||||||
|
|
||||||
The Raw HID feature allows for bidirectional communication between QMK and the host computer over an HID interface. This has many potential use cases, such as switching keymaps on the fly or sending useful metrics like CPU/RAM usage.
|
The Raw HID feature allows for bidirectional communication between QMK and the host computer over an HID interface. This has many potential use cases, such as switching keymaps on the fly or sending useful metrics like CPU/RAM usage.
|
||||||
|
|
||||||
In order to communicate with the keyboard using this feature, you will need to write a program that runs on the host. As such, some basic programming skills are required - more if you intend to implement complex behaviour.
|
In order to communicate with the keyboard using this feature, you will need to write a program that runs on the host. As such, some basic programming skills are required - more if you intend to implement complex behaviour.
|
||||||
|
|
||||||
## Usage :id=usage
|
## Usage {#usage}
|
||||||
|
|
||||||
Add the following to your `rules.mk`:
|
Add the following to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ Add the following to your `rules.mk`:
|
||||||
RAW_ENABLE = yes
|
RAW_ENABLE = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
## Basic Configuration :id=basic-configuration
|
## Basic Configuration {#basic-configuration}
|
||||||
|
|
||||||
By default, the HID Usage Page and Usage ID for the Raw HID interface are `0xFF60` and `0x61`. However, they can be changed if necessary by adding the following to your `config.h`:
|
By default, the HID Usage Page and Usage ID for the Raw HID interface are `0xFF60` and `0x61`. However, they can be changed if necessary by adding the following to your `config.h`:
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ By default, the HID Usage Page and Usage ID for the Raw HID interface are `0xFF6
|
||||||
|`RAW_USAGE_PAGE`|`0xFF60`|The usage page of the Raw HID interface|
|
|`RAW_USAGE_PAGE`|`0xFF60`|The usage page of the Raw HID interface|
|
||||||
|`RAW_USAGE_ID` |`0x61` |The usage ID of the Raw HID interface |
|
|`RAW_USAGE_ID` |`0x61` |The usage ID of the Raw HID interface |
|
||||||
|
|
||||||
## Sending Data to the Keyboard :id=sending-data-to-the-keyboard
|
## Sending Data to the Keyboard {#sending-data-to-the-keyboard}
|
||||||
|
|
||||||
To send data to the keyboard, you must first find a library for communicating with HID devices in the programming language of your choice. Here are some examples:
|
To send data to the keyboard, you must first find a library for communicating with HID devices in the programming language of your choice. Here are some examples:
|
||||||
|
|
||||||
|
@ -46,15 +46,17 @@ void raw_hid_receive(uint8_t *data, uint8_t length) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Because the HID specification does not support variable length reports, all reports in both directions must be exactly `RAW_EPSIZE` (currently 32) bytes long, regardless of actual payload length. However, variable length payloads can potentially be implemented on top of this by creating your own data structure that may span multiple reports.
|
::: warning
|
||||||
|
Because the HID specification does not support variable length reports, all reports in both directions must be exactly `RAW_EPSIZE` (currently 32) bytes long, regardless of actual payload length. However, variable length payloads can potentially be implemented on top of this by creating your own data structure that may span multiple reports.
|
||||||
|
:::
|
||||||
|
|
||||||
## Receiving Data from the Keyboard :id=receiving-data-from-the-keyboard
|
## Receiving Data from the Keyboard {#receiving-data-from-the-keyboard}
|
||||||
|
|
||||||
If you need the keyboard to send data back to the host, simply call the `raw_hid_send()` function. It requires two arguments - a pointer to a 32-byte buffer containing the data you wish to send, and the length (which should always be `RAW_EPSIZE`).
|
If you need the keyboard to send data back to the host, simply call the `raw_hid_send()` function. It requires two arguments - a pointer to a 32-byte buffer containing the data you wish to send, and the length (which should always be `RAW_EPSIZE`).
|
||||||
|
|
||||||
The received report can then be handled in whichever way your HID library provides.
|
The received report can then be handled in whichever way your HID library provides.
|
||||||
|
|
||||||
## Simple Example :id=simple-example
|
## Simple Example {#simple-example}
|
||||||
|
|
||||||
The following example reads the first byte of the received report from the host, and if it is an ASCII "A", responds with "B". `memset()` is used to fill the response buffer (which could still contain the previous response) with null bytes.
|
The following example reads the first byte of the received report from the host, and if it is an ASCII "A", responds with "B". `memset()` is used to fill the response buffer (which could still contain the previous response) with null bytes.
|
||||||
|
|
||||||
|
@ -129,13 +131,13 @@ if __name__ == '__main__':
|
||||||
])
|
])
|
||||||
```
|
```
|
||||||
|
|
||||||
## API :id=api
|
## API {#api}
|
||||||
|
|
||||||
### `void raw_hid_receive(uint8_t *data, uint8_t length)` :id=api-raw-hid-receive
|
### `void raw_hid_receive(uint8_t *data, uint8_t length)` {#api-raw-hid-receive}
|
||||||
|
|
||||||
Callback, invoked when a raw HID report has been received from the host.
|
Callback, invoked when a raw HID report has been received from the host.
|
||||||
|
|
||||||
#### Arguments :id=api-raw-hid-receive-arguments
|
#### Arguments {#api-raw-hid-receive-arguments}
|
||||||
|
|
||||||
- `uint8_t *data`
|
- `uint8_t *data`
|
||||||
A pointer to the received data. Always 32 bytes in length.
|
A pointer to the received data. Always 32 bytes in length.
|
||||||
|
@ -144,11 +146,11 @@ Callback, invoked when a raw HID report has been received from the host.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `void raw_hid_send(uint8_t *data, uint8_t length)` :id=api-raw-hid-send
|
### `void raw_hid_send(uint8_t *data, uint8_t length)` {#api-raw-hid-send}
|
||||||
|
|
||||||
Send an HID report.
|
Send an HID report.
|
||||||
|
|
||||||
#### Arguments :id=api-raw-hid-send-arguments
|
#### Arguments {#api-raw-hid-send-arguments}
|
||||||
|
|
||||||
- `uint8_t *data`
|
- `uint8_t *data`
|
||||||
A pointer to the data to send. Must always be 32 bytes in length.
|
A pointer to the data to send. Must always be 32 bytes in length.
|
||||||
|
|
|
@ -172,7 +172,7 @@ uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) {
|
||||||
#### Typing shortcuts
|
#### Typing shortcuts
|
||||||
|
|
||||||
A useful possibility is having Alternate Repeat press [a
|
A useful possibility is having Alternate Repeat press [a
|
||||||
macro](feature_macros.md). This way macros can be used without having to
|
macro](feature_macros). This way macros can be used without having to
|
||||||
dedicate keys to them. The following defines a couple shortcuts.
|
dedicate keys to them. The following defines a couple shortcuts.
|
||||||
|
|
||||||
* Typing <kbd>K</kbd>, <kbd>Alt Repeat</kbd> produces "`keyboard`," with the
|
* Typing <kbd>K</kbd>, <kbd>Alt Repeat</kbd> produces "`keyboard`," with the
|
||||||
|
@ -280,8 +280,10 @@ bool remember_last_key_user(uint16_t keycode, keyrecord_t* record,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
?> See [Layer Functions](feature_layers.md#functions) and [Checking Modifier
|
::: tip
|
||||||
State](feature_advanced_keycodes.md#checking-modifier-state) for further
|
See [Layer Functions](feature_layers#functions) and [Checking Modifier
|
||||||
|
:::
|
||||||
|
State](feature_advanced_keycodes#checking-modifier-state) for further
|
||||||
details.
|
details.
|
||||||
|
|
||||||
|
|
||||||
|
@ -386,7 +388,7 @@ By leveraging `get_last_keycode()` in macros, it is possible to define
|
||||||
additional, distinct "Alternate Repeat"-like keys. The following defines two
|
additional, distinct "Alternate Repeat"-like keys. The following defines two
|
||||||
keys `ALTREP2` and `ALTREP3` and implements ten shortcuts with them for common
|
keys `ALTREP2` and `ALTREP3` and implements ten shortcuts with them for common
|
||||||
English 5-gram letter patterns, taking inspiration from
|
English 5-gram letter patterns, taking inspiration from
|
||||||
[Stenotype](feature_stenography.md):
|
[Stenotype](feature_stenography):
|
||||||
|
|
||||||
|
|
||||||
| Typing | Produces | Typing | Produces |
|
| Typing | Produces | Typing | Produces |
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# RGB Matrix Lighting :id=rgb-matrix-lighting
|
# RGB Matrix Lighting {#rgb-matrix-lighting}
|
||||||
|
|
||||||
This feature allows you to use RGB LED matrices driven by external drivers. It hooks into the RGBLIGHT system so you can use the same keycodes as RGBLIGHT to control it.
|
This feature allows you to use RGB LED matrices driven by external drivers. It hooks into the RGBLIGHT system so you can use the same keycodes as RGBLIGHT to control it.
|
||||||
|
|
||||||
If you want to use single color LED's you should use the [LED Matrix Subsystem](feature_led_matrix.md) instead.
|
If you want to use single color LED's you should use the [LED Matrix Subsystem](feature_led_matrix) instead.
|
||||||
|
|
||||||
## Driver configuration :id=driver-configuration
|
## Driver configuration {#driver-configuration}
|
||||||
---
|
---
|
||||||
### IS31FL3731 :id=is31fl3731
|
### IS31FL3731 {#is31fl3731}
|
||||||
|
|
||||||
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -48,7 +48,9 @@ Here is an example using 2 drivers.
|
||||||
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
::: warning
|
||||||
|
Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
||||||
|
:::
|
||||||
|
|
||||||
For split keyboards using `RGB_MATRIX_SPLIT` with an LED driver, you can either have the same driver address or different driver addresses. If using different addresses, use `IS31FL3731_I2C_ADDRESS_1` for one and `IS31FL3731_I2C_ADDRESS_2` for the other one. Then, in `g_is31fl3731_leds`, fill out the correct driver index (0 or 1). If using one address, use `IS31FL3731_I2C_ADDRESS_1` for both, and use index 0 for `g_is31fl3731_leds`.
|
For split keyboards using `RGB_MATRIX_SPLIT` with an LED driver, you can either have the same driver address or different driver addresses. If using different addresses, use `IS31FL3731_I2C_ADDRESS_1` for one and `IS31FL3731_I2C_ADDRESS_2` for the other one. Then, in `g_is31fl3731_leds`, fill out the correct driver index (0 or 1). If using one address, use `IS31FL3731_I2C_ADDRESS_1` for both, and use index 0 for `g_is31fl3731_leds`.
|
||||||
|
|
||||||
|
@ -70,7 +72,7 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
||||||
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/led/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3`).
|
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/led/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3`).
|
||||||
|
|
||||||
---
|
---
|
||||||
### IS31FL3733 :id=is31fl3733
|
### IS31FL3733 {#is31fl3733}
|
||||||
|
|
||||||
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -132,7 +134,9 @@ Here is an example using 2 drivers.
|
||||||
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
::: warning
|
||||||
|
Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
||||||
|
:::
|
||||||
|
|
||||||
Currently only 4 drivers are supported, but it would be trivial to support all 8 combinations.
|
Currently only 4 drivers are supported, but it would be trivial to support all 8 combinations.
|
||||||
|
|
||||||
|
@ -154,7 +158,7 @@ const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT] = {
|
||||||
Where `SWx_CSy` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3733.pdf) and the header file `drivers/led/issi/is31fl3733.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` for now).
|
Where `SWx_CSy` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3733.pdf) and the header file `drivers/led/issi/is31fl3733.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` for now).
|
||||||
|
|
||||||
---
|
---
|
||||||
### IS31FL3736 :id=is31fl3736
|
### IS31FL3736 {#is31fl3736}
|
||||||
|
|
||||||
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3736 RGB controller. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3736 RGB controller. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -213,7 +217,9 @@ Here is an example using 2 drivers.
|
||||||
#define DRIVER_2_LED_TOTAL 32
|
#define DRIVER_2_LED_TOTAL 32
|
||||||
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
||||||
```
|
```
|
||||||
!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
::: warning
|
||||||
|
Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
||||||
|
:::
|
||||||
|
|
||||||
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||||
|
|
||||||
|
@ -229,7 +235,7 @@ const is31fl3736_led_t PROGMEM g_is31fl3736_leds[IS31FL3736_LED_COUNT] = {
|
||||||
....
|
....
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
### IS31FL3737 :id=is31fl3737
|
### IS31FL3737 {#is31fl3737}
|
||||||
|
|
||||||
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3737 RGB controller. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3737 RGB controller. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -287,7 +293,9 @@ Here is an example using 2 drivers.
|
||||||
#define DRIVER_2_LED_TOTAL 36
|
#define DRIVER_2_LED_TOTAL 36
|
||||||
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
||||||
```
|
```
|
||||||
!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
::: warning
|
||||||
|
Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
||||||
|
:::
|
||||||
|
|
||||||
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||||
|
|
||||||
|
@ -307,7 +315,7 @@ const is31fl3737_led_t PROGMEM g_is31fl3737_leds[IS31FL3737_LED_COUNT] = {
|
||||||
Where `SWx_CSy` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3737.pdf) and the header file `drivers/led/issi/is31fl3737.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0`, `1`, `2`, or `3` for now).
|
Where `SWx_CSy` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3737.pdf) and the header file `drivers/led/issi/is31fl3737.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0`, `1`, `2`, or `3` for now).
|
||||||
|
|
||||||
---
|
---
|
||||||
### IS31FLCOMMON :id=is31flcommon
|
### IS31FLCOMMON {#is31flcommon}
|
||||||
|
|
||||||
There is basic support for addressable RGB matrix lighting with a selection of I2C ISSI Lumissil RGB controllers through a shared common driver. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable RGB matrix lighting with a selection of I2C ISSI Lumissil RGB controllers through a shared common driver. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -372,7 +380,9 @@ Here is an example using 2 drivers.
|
||||||
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
::: warning
|
||||||
|
Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
||||||
|
:::
|
||||||
|
|
||||||
Currently only 4 drivers are supported, but it would be trivial to support for more. Note that using a combination of different drivers is not supported. All drivers must be of the same model.
|
Currently only 4 drivers are supported, but it would be trivial to support for more. Note that using a combination of different drivers is not supported. All drivers must be of the same model.
|
||||||
|
|
||||||
|
@ -415,7 +425,7 @@ Where LED Index is the position of the LED in the `g_is31_leds` array. The `scal
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### WS2812 :id=ws2812
|
### WS2812 {#ws2812}
|
||||||
|
|
||||||
There is basic support for addressable RGB matrix lighting with a WS2811/WS2812{a,b,c} addressable LED strand. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable RGB matrix lighting with a WS2811/WS2812{a,b,c} addressable LED strand. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -433,11 +443,13 @@ Configure the hardware via your `config.h`:
|
||||||
#define RGB_MATRIX_LED_COUNT 70
|
#define RGB_MATRIX_LED_COUNT 70
|
||||||
```
|
```
|
||||||
|
|
||||||
?> There are additional configuration options for ARM controllers that offer increased performance over the default bitbang driver. Please see [WS2812 Driver](ws2812_driver.md) for more information.
|
::: tip
|
||||||
|
There are additional configuration options for ARM controllers that offer increased performance over the default bitbang driver. Please see [WS2812 Driver](ws2812_driver) for more information.
|
||||||
|
:::
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### APA102 :id=apa102
|
### APA102 {#apa102}
|
||||||
|
|
||||||
There is basic support for APA102 based addressable LED strands. To enable it, add this to your `rules.mk`:
|
There is basic support for APA102 based addressable LED strands. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
@ -458,7 +470,7 @@ Configure the hardware via your `config.h`:
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
### AW20216S :id=aw20216s
|
### AW20216S {#aw20216s}
|
||||||
There is basic support for addressable RGB matrix lighting with the SPI AW20216S RGB controller. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable RGB matrix lighting with the SPI AW20216S RGB controller. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
```make
|
```make
|
||||||
|
@ -496,7 +508,9 @@ Here is an example using 2 drivers.
|
||||||
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
::: warning
|
||||||
|
Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
||||||
|
:::
|
||||||
|
|
||||||
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||||
|
|
||||||
|
@ -527,7 +541,7 @@ const aw20216s_led_t PROGMEM g_aw20216s_leds[AW20216S_LED_COUNT] = {
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Common Configuration :id=common-configuration
|
## Common Configuration {#common-configuration}
|
||||||
|
|
||||||
From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example:
|
From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example:
|
||||||
|
|
||||||
|
@ -560,7 +574,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
||||||
|
|
||||||
`// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type.
|
`// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type.
|
||||||
|
|
||||||
## Flags :id=flags
|
## Flags {#flags}
|
||||||
|
|
||||||
|Define |Value |Description |
|
|Define |Value |Description |
|
||||||
|----------------------------|------|-------------------------------------------------|
|
|----------------------------|------|-------------------------------------------------|
|
||||||
|
@ -573,7 +587,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
||||||
|`LED_FLAG_KEYLIGHT` |`0x04`|If the LED is for key backlight |
|
|`LED_FLAG_KEYLIGHT` |`0x04`|If the LED is for key backlight |
|
||||||
|`LED_FLAG_INDICATOR` |`0x08`|If the LED is for keyboard state indication |
|
|`LED_FLAG_INDICATOR` |`0x08`|If the LED is for keyboard state indication |
|
||||||
|
|
||||||
## Keycodes :id=keycodes
|
## Keycodes {#keycodes}
|
||||||
|
|
||||||
All RGB keycodes are currently shared with the RGBLIGHT system:
|
All RGB keycodes are currently shared with the RGBLIGHT system:
|
||||||
|
|
||||||
|
@ -599,12 +613,16 @@ All RGB keycodes are currently shared with the RGBLIGHT system:
|
||||||
|
|
||||||
`RGB_MODE_PLAIN`, `RGB_MODE_BREATHE`, `RGB_MODE_RAINBOW`, and `RGB_MODE_SWIRL` are the only ones that are mapped properly. The rest don't have a direct equivalent, and are not mapped.
|
`RGB_MODE_PLAIN`, `RGB_MODE_BREATHE`, `RGB_MODE_RAINBOW`, and `RGB_MODE_SWIRL` are the only ones that are mapped properly. The rest don't have a direct equivalent, and are not mapped.
|
||||||
|
|
||||||
?> `RGB_*` keycodes cannot be used with functions like `tap_code16(RGB_HUD)` as they're not USB HID keycodes. If you wish to replicate similar behaviour in custom code within your firmware (e.g. inside `encoder_update_user()` or `process_record_user()`), the equivalent [RGB functions](#functions) should be used instead.
|
::: tip
|
||||||
|
`RGB_*` keycodes cannot be used with functions like `tap_code16(RGB_HUD)` as they're not USB HID keycodes. If you wish to replicate similar behaviour in custom code within your firmware (e.g. inside `encoder_update_user()` or `process_record_user()`), the equivalent [RGB functions](#functions) should be used instead.
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
!> By default, if you have both the [RGB Light](feature_rgblight.md) and the RGB Matrix feature enabled, these keycodes will work for both features, at the same time. You can disable the keycode functionality by defining the `*_DISABLE_KEYCODES` option for the specific feature.
|
::: warning
|
||||||
|
By default, if you have both the [RGB Light](feature_rgblight) and the RGB Matrix feature enabled, these keycodes will work for both features, at the same time. You can disable the keycode functionality by defining the `*_DISABLE_KEYCODES` option for the specific feature.
|
||||||
|
:::
|
||||||
|
|
||||||
## RGB Matrix Effects :id=rgb-matrix-effects
|
## RGB Matrix Effects {#rgb-matrix-effects}
|
||||||
|
|
||||||
All effects have been configured to support current configuration values (Hue, Saturation, Value, & Speed) unless otherwise noted below. These are the effects that are currently available:
|
All effects have been configured to support current configuration values (Hue, Saturation, Value, & Speed) unless otherwise noted below. These are the effects that are currently available:
|
||||||
|
|
||||||
|
@ -709,7 +727,9 @@ You can enable a single effect by defining `ENABLE_[EFFECT_NAME]` in your `confi
|
||||||
|`#define ENABLE_RGB_MATRIX_TYPING_HEATMAP` |Enables `RGB_MATRIX_TYPING_HEATMAP` |
|
|`#define ENABLE_RGB_MATRIX_TYPING_HEATMAP` |Enables `RGB_MATRIX_TYPING_HEATMAP` |
|
||||||
|`#define ENABLE_RGB_MATRIX_DIGITAL_RAIN` |Enables `RGB_MATRIX_DIGITAL_RAIN` |
|
|`#define ENABLE_RGB_MATRIX_DIGITAL_RAIN` |Enables `RGB_MATRIX_DIGITAL_RAIN` |
|
||||||
|
|
||||||
?> These modes introduce additional logic that can increase firmware size.
|
::: tip
|
||||||
|
These modes introduce additional logic that can increase firmware size.
|
||||||
|
:::
|
||||||
|
|
||||||
|Reactive Defines |Description |
|
|Reactive Defines |Description |
|
||||||
|------------------------------------------------------|----------------------------------------------|
|
|------------------------------------------------------|----------------------------------------------|
|
||||||
|
@ -726,10 +746,12 @@ You can enable a single effect by defining `ENABLE_[EFFECT_NAME]` in your `confi
|
||||||
|`#define ENABLE_RGB_MATRIX_SOLID_SPLASH` |Enables `RGB_MATRIX_SOLID_SPLASH` |
|
|`#define ENABLE_RGB_MATRIX_SOLID_SPLASH` |Enables `RGB_MATRIX_SOLID_SPLASH` |
|
||||||
|`#define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH` |Enables `RGB_MATRIX_SOLID_MULTISPLASH` |
|
|`#define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH` |Enables `RGB_MATRIX_SOLID_MULTISPLASH` |
|
||||||
|
|
||||||
?> These modes introduce additional logic that can increase firmware size.
|
::: tip
|
||||||
|
These modes introduce additional logic that can increase firmware size.
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
### RGB Matrix Effect Typing Heatmap :id=rgb-matrix-effect-typing-heatmap
|
### RGB Matrix Effect Typing Heatmap {#rgb-matrix-effect-typing-heatmap}
|
||||||
|
|
||||||
This effect will color the RGB matrix according to a heatmap of recently pressed keys. Whenever a key is pressed its "temperature" increases as well as that of its neighboring keys. The temperature of each key is then decreased automatically every 25 milliseconds by default.
|
This effect will color the RGB matrix according to a heatmap of recently pressed keys. Whenever a key is pressed its "temperature" increases as well as that of its neighboring keys. The temperature of each key is then decreased automatically every 25 milliseconds by default.
|
||||||
|
|
||||||
|
@ -767,7 +789,7 @@ the number of keystrokes needed to fully heat up the key.
|
||||||
#define RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP 32
|
#define RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP 32
|
||||||
```
|
```
|
||||||
|
|
||||||
### RGB Matrix Effect Solid Reactive :id=rgb-matrix-effect-solid-reactive
|
### RGB Matrix Effect Solid Reactive {#rgb-matrix-effect-solid-reactive}
|
||||||
|
|
||||||
Solid reactive effects will pulse RGB light on key presses with user configurable hues. To enable gradient mode that will automatically change reactive color, add the following define:
|
Solid reactive effects will pulse RGB light on key presses with user configurable hues. To enable gradient mode that will automatically change reactive color, add the following define:
|
||||||
|
|
||||||
|
@ -777,11 +799,13 @@ Solid reactive effects will pulse RGB light on key presses with user configurabl
|
||||||
|
|
||||||
Gradient mode will loop through the color wheel hues over time and its duration can be controlled with the effect speed keycodes (`RGB_SPI`/`RGB_SPD`).
|
Gradient mode will loop through the color wheel hues over time and its duration can be controlled with the effect speed keycodes (`RGB_SPI`/`RGB_SPD`).
|
||||||
|
|
||||||
## Custom RGB Matrix Effects :id=custom-rgb-matrix-effects
|
## Custom RGB Matrix Effects {#custom-rgb-matrix-effects}
|
||||||
|
|
||||||
By setting `RGB_MATRIX_CUSTOM_USER = yes` in `rules.mk`, new effects can be defined directly from your keymap or userspace, without having to edit any QMK core files. To declare new effects, create a `rgb_matrix_user.inc` file in the user keymap directory or userspace folder.
|
By setting `RGB_MATRIX_CUSTOM_USER = yes` in `rules.mk`, new effects can be defined directly from your keymap or userspace, without having to edit any QMK core files. To declare new effects, create a `rgb_matrix_user.inc` file in the user keymap directory or userspace folder.
|
||||||
|
|
||||||
?> Hardware maintainers who want to limit custom effects to a specific keyboard can create a `rgb_matrix_kb.inc` file in the root of the keyboard directory, and add `RGB_MATRIX_CUSTOM_KB = yes` to the keyboard level `rules.mk`.
|
::: tip
|
||||||
|
Hardware maintainers who want to limit custom effects to a specific keyboard can create a `rgb_matrix_kb.inc` file in the root of the keyboard directory, and add `RGB_MATRIX_CUSTOM_KB = yes` to the keyboard level `rules.mk`.
|
||||||
|
:::
|
||||||
|
|
||||||
To use custom effects in your code, simply prepend `RGB_MATRIX_CUSTOM_` to the effect name specified in `RGB_MATRIX_EFFECT()`. For example, an effect declared as `RGB_MATRIX_EFFECT(my_cool_effect)` would be referenced with:
|
To use custom effects in your code, simply prepend `RGB_MATRIX_CUSTOM_` to the effect name specified in `RGB_MATRIX_EFFECT()`. For example, an effect declared as `RGB_MATRIX_EFFECT(my_cool_effect)` would be referenced with:
|
||||||
|
|
||||||
|
@ -835,7 +859,7 @@ static bool my_cool_effect2(effect_params_t* params) {
|
||||||
For inspiration and examples, check out the built-in effects under `quantum/rgb_matrix/animations/`.
|
For inspiration and examples, check out the built-in effects under `quantum/rgb_matrix/animations/`.
|
||||||
|
|
||||||
|
|
||||||
## Colors :id=colors
|
## Colors {#colors}
|
||||||
|
|
||||||
These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions.
|
These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions.
|
||||||
|
|
||||||
|
@ -864,7 +888,7 @@ These are shorthands to popular colors. The `RGB` ones can be passed to the `set
|
||||||
These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/color.h). Feel free to add to this list!
|
These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/color.h). Feel free to add to this list!
|
||||||
|
|
||||||
|
|
||||||
## Additional `config.h` Options :id=additional-configh-options
|
## Additional `config.h` Options {#additional-configh-options}
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define RGB_MATRIX_KEYRELEASES // reactive effects respond to keyreleases (instead of keypresses)
|
#define RGB_MATRIX_KEYRELEASES // reactive effects respond to keyreleases (instead of keypresses)
|
||||||
|
@ -886,19 +910,19 @@ These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master
|
||||||
#define RGB_TRIGGER_ON_KEYDOWN // Triggers RGB keypress events on key down. This makes RGB control feel more responsive. This may cause RGB to not function properly on some boards
|
#define RGB_TRIGGER_ON_KEYDOWN // Triggers RGB keypress events on key down. This makes RGB control feel more responsive. This may cause RGB to not function properly on some boards
|
||||||
```
|
```
|
||||||
|
|
||||||
## EEPROM storage :id=eeprom-storage
|
## EEPROM storage {#eeprom-storage}
|
||||||
|
|
||||||
The EEPROM for it is currently shared with the LED Matrix system (it's generally assumed only one feature would be used at a time).
|
The EEPROM for it is currently shared with the LED Matrix system (it's generally assumed only one feature would be used at a time).
|
||||||
|
|
||||||
## Functions :id=functions
|
## Functions {#functions}
|
||||||
|
|
||||||
### Direct Operation :id=direct-operation
|
### Direct Operation {#direct-operation}
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|--------------------------------------------|-------------|
|
|--------------------------------------------|-------------|
|
||||||
|`rgb_matrix_set_color_all(r, g, b)` |Set all of the LEDs to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) |
|
|`rgb_matrix_set_color_all(r, g, b)` |Set all of the LEDs to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) |
|
||||||
|`rgb_matrix_set_color(index, r, g, b)` |Set a single LED to the given RGB value, where `r`/`g`/`b` are between 0 and 255, and `index` is between 0 and `RGB_MATRIX_LED_COUNT` (not written to EEPROM) |
|
|`rgb_matrix_set_color(index, r, g, b)` |Set a single LED to the given RGB value, where `r`/`g`/`b` are between 0 and 255, and `index` is between 0 and `RGB_MATRIX_LED_COUNT` (not written to EEPROM) |
|
||||||
|
|
||||||
### Disable/Enable Effects :id=disable-enable-effects
|
### Disable/Enable Effects {#disable-enable-effects}
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|--------------------------------------------|-------------|
|
|--------------------------------------------|-------------|
|
||||||
|`rgb_matrix_toggle()` |Toggle effect range LEDs between on and off |
|
|`rgb_matrix_toggle()` |Toggle effect range LEDs between on and off |
|
||||||
|
@ -908,7 +932,7 @@ The EEPROM for it is currently shared with the LED Matrix system (it's generally
|
||||||
|`rgb_matrix_disable()` |Turn effect range LEDs off, based on their previous state |
|
|`rgb_matrix_disable()` |Turn effect range LEDs off, based on their previous state |
|
||||||
|`rgb_matrix_disable_noeeprom()` |Turn effect range LEDs off, based on their previous state (not written to EEPROM) |
|
|`rgb_matrix_disable_noeeprom()` |Turn effect range LEDs off, based on their previous state (not written to EEPROM) |
|
||||||
|
|
||||||
### Change Effect Mode :id=change-effect-mode
|
### Change Effect Mode {#change-effect-mode}
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|--------------------------------------------|-------------|
|
|--------------------------------------------|-------------|
|
||||||
|`rgb_matrix_mode(mode)` |Set the mode, if RGB animations are enabled |
|
|`rgb_matrix_mode(mode)` |Set the mode, if RGB animations are enabled |
|
||||||
|
@ -925,7 +949,7 @@ The EEPROM for it is currently shared with the LED Matrix system (it's generally
|
||||||
|`rgb_matrix_set_speed_noeeprom(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 (not written to EEPROM) |
|
|`rgb_matrix_set_speed_noeeprom(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 (not written to EEPROM) |
|
||||||
|`rgb_matrix_reload_from_eeprom()` |Reload the effect configuration (enabled, mode and color) from EEPROM |
|
|`rgb_matrix_reload_from_eeprom()` |Reload the effect configuration (enabled, mode and color) from EEPROM |
|
||||||
|
|
||||||
### Change Color :id=change-color
|
### Change Color {#change-color}
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|--------------------------------------------|-------------|
|
|--------------------------------------------|-------------|
|
||||||
|`rgb_matrix_increase_hue()` |Increase the hue for effect range LEDs. This wraps around at maximum hue |
|
|`rgb_matrix_increase_hue()` |Increase the hue for effect range LEDs. This wraps around at maximum hue |
|
||||||
|
@ -943,7 +967,7 @@ The EEPROM for it is currently shared with the LED Matrix system (it's generally
|
||||||
|`rgb_matrix_sethsv(h, s, v)` |Set LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 |
|
|`rgb_matrix_sethsv(h, s, v)` |Set LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 |
|
||||||
|`rgb_matrix_sethsv_noeeprom(h, s, v)` |Set LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) |
|
|`rgb_matrix_sethsv_noeeprom(h, s, v)` |Set LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) |
|
||||||
|
|
||||||
### Query Current Status :id=query-current-status
|
### Query Current Status {#query-current-status}
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|---------------------------------|---------------------------|
|
|---------------------------------|---------------------------|
|
||||||
|`rgb_matrix_is_enabled()` |Gets current on/off status |
|
|`rgb_matrix_is_enabled()` |Gets current on/off status |
|
||||||
|
@ -955,9 +979,9 @@ The EEPROM for it is currently shared with the LED Matrix system (it's generally
|
||||||
|`rgb_matrix_get_speed()` |Gets current speed |
|
|`rgb_matrix_get_speed()` |Gets current speed |
|
||||||
|`rgb_matrix_get_suspend_state()` |Gets current suspend state |
|
|`rgb_matrix_get_suspend_state()` |Gets current suspend state |
|
||||||
|
|
||||||
## Callbacks :id=callbacks
|
## Callbacks {#callbacks}
|
||||||
|
|
||||||
### Indicators :id=indicators
|
### Indicators {#indicators}
|
||||||
|
|
||||||
If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, then you can use the `rgb_matrix_indicators_kb` function on the keyboard level source file, or `rgb_matrix_indicators_user` function in the user `keymap.c`.
|
If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, then you can use the `rgb_matrix_indicators_kb` function on the keyboard level source file, or `rgb_matrix_indicators_user` function in the user `keymap.c`.
|
||||||
```c
|
```c
|
||||||
|
@ -979,7 +1003,7 @@ bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Indicator Examples :id=indicator-examples
|
### Indicator Examples {#indicator-examples}
|
||||||
|
|
||||||
Caps Lock indicator on alphanumeric flagged keys:
|
Caps Lock indicator on alphanumeric flagged keys:
|
||||||
```c
|
```c
|
||||||
|
@ -1035,9 +1059,11 @@ bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
?> Split keyboards will require layer state data syncing with `#define SPLIT_LAYER_STATE_ENABLE`. See [Data Sync Options](feature_split_keyboard?id=data-sync-options) for more details.
|
::: tip
|
||||||
|
Split keyboards will require layer state data syncing with `#define SPLIT_LAYER_STATE_ENABLE`. See [Data Sync Options](feature_split_keyboard#data-sync-options) for more details.
|
||||||
|
:::
|
||||||
|
|
||||||
#### Examples :id=indicator-examples
|
#### Examples {#indicator-examples-2}
|
||||||
|
|
||||||
This example sets the modifiers to be a specific color based on the layer state. You can use a switch case here, instead, if you would like. This uses HSV and then converts to RGB, because this allows the brightness to be limited (important when using the WS2812 driver).
|
This example sets the modifiers to be a specific color based on the layer state. You can use a switch case here, instead, if you would like. This uses HSV and then converts to RGB, because this allows the brightness to be limited (important when using the WS2812 driver).
|
||||||
|
|
||||||
|
@ -1078,7 +1104,9 @@ bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
?> RGB indicators on split keyboards will require state information synced to the slave half (e.g. `#define SPLIT_LAYER_STATE_ENABLE`). See [data sync options](feature_split_keyboard.md#data-sync-options) for more details.
|
::: tip
|
||||||
|
RGB indicators on split keyboards will require state information synced to the slave half (e.g. `#define SPLIT_LAYER_STATE_ENABLE`). See [data sync options](feature_split_keyboard#data-sync-options) for more details.
|
||||||
|
:::
|
||||||
|
|
||||||
#### Indicators without RGB Matrix Effect
|
#### Indicators without RGB Matrix Effect
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue