Repository navigation
Shortcuts
src/hotkeys.cpp, src/hotkeys.h
These can be reassigned under Settings → Keys:
| Key | Action |
|---|---|
| Enter | Fullscreen |
| Ctrl+Enter | Borderless |
| F1 | Statistics |
| F2 | Settings |
| F3 | Toolbar |
| F5 | Restart capture |
| Shift+F5 | Reinitialise card |
| F6 | Measure colour range again |
| F7 | Detect video standard |
| F8 | Detect border |
| F9 | Start / stop recording |
| F10 | Screenshot |
| Ctrl+F10 | Screenshot to the clipboard |
| F11 | Freeze |
| F12 | Compare filters |
| Shift+F12 | All filters off |
| M | Mute |
+ / -
|
Volume |
These cannot:
| Key | Action |
|---|---|
| Esc | Leave fullscreen, close the settings |
| Ctrl+1 … Ctrl+9 | Switch profile |
| Ctrl+F | Search, while the settings are open |
| Double click on the picture | Fullscreen |
| Mouse wheel | Volume |
| Right click | Menu |
| Shift while resizing | Keep the picture's shape |
| Dragging the picture | Move the window, when borderless |
F11, F12 and Shift+F12 are described on Freeze and compare, Ctrl+F on The settings window, the last two on The main window.
// Escape always leaves fullscreen and closes the dialog, and Ctrl+1..9 always
// picks a profile: both are conventions people expect to hold, and a binding
// editor that lets you break your way out of fullscreen is a trap rather than
// a feature.That is the whole reasoning. A UI that lets you rebind Escape produces a program you can get stuck inside.
enum class HotkeyAction {
Fullscreen, Settings, Stats, RestartCapture, ReinitCard, Record,
Screenshot, ScreenshotClipboard, Freeze, Compare, BypassFilters,
DetectCrop, DetectStandard, RemeasureRange, Mute, VolumeUp, VolumeDown, Count
};
struct HotkeyBinding {
Key key = Key::None; // None = unbound
bool ctrl, shift, alt;
};Seventeen actions, each with one binding, held in a Hotkeys struct indexed by
the enum. HotkeyAction::Count doubles as "no action bound to this
combination", which is what Hotkeys::Find() returns on a miss.
Key is qBlank's own list of keys (src/keys.h), not a Windows virtual-key
code; src/keys_win32.cpp translates between the two. Up to 4.4 the binding
held the virtual-key number itself.
Four of them earn their place by being needed exactly when a dialog is the last thing you want to open. Shift+F5 rebuilds the card's device list from scratch, for when a card was plugged in or re-enumerated after qBlank started. F8 measures the black border around the picture and crops to it — useful whenever a source changes size, because a crop is a count of source pixels and is dropped when that count stops meaning anything (see Cropping and geometry).
F7 runs the video standard search again from the start, both stages, even when the current standard holds and shows plenty of colour — the one case the automatic search cannot see, because colour that is wrong is still colour (see Automatic video standard).
F6 throws away the full-or-limited verdict and measures it again, for the case no automatic can see: an option in the card's own driver moves every black level in the picture and leaves the media type alone, so the frozen verdict goes on describing rules that stopped applying (see Colour range and matrix).
The three sit next to each other because they are the same kind of command: a measurement on the picture in front of you, triggered because you can see something the automation does not measure. F7 and F8 both need a real picture and neither decides anything on black. F6 is the exception, and for a reason worth knowing: the black end is precisely what it measures, so a black picture is not a poor one to measure on — it is the clearest there is.
A search started this way also says what it found — the standard and the reason, over the picture for five seconds, whichever of its exits it took. The automatic search reports with a toast and only when something changed; a key that was pressed on purpose gets an answer either way.
On a source that is already locked it takes under two seconds end to end, measured on a GameCube through a PEXHDCAP60L, and the standards visibly step past one another while it runs. It cost 6.0 s until 31.08., of which 2.7 s were spent before the first switch even happened — see Automatic video standard for what each half of that was and what replaced it.
Modifiers must match exactly — HotkeyBinding::Matches() compares all three,
so F9 and Shift+F9 are different bindings rather than one swallowing the other.
Each action has three strings, and they are deliberately separate:
HotkeyActionName() |
the label in the settings and the context menu, in the current language |
HotkeyActionKey() |
what is written to qBlank.json — language-independent and stable |
HotkeyText() |
"Strg+Umschalt+F9", or empty when unbound |
The middle one matters: a config file written in German and read in English has to name the same action. The first and third are display only.
The key itself is stored the same way, by name ("key": "F12"), since 5.0.
Next to it the file still carries the old number ("vk"), for a qBlank older
than 5.0 reading the same file after a downgrade. A file that has only the
number, from before 5.0, is read as before, so an update keeps every binding.
The combination text comes from the keyboard layout through
GetKeyNameTextW (KeyLabel() in src/keys_win32.cpp), so a French keyboard
reads its own labels rather than a translation of the American ones. Keys the
layout names badly or not at all — Enter, Space, the arrows, + and - — are
named by SpecialKeyName() instead.
IsReservedKey() returns true for keys that must not be swallowed as a shortcut:
- Escape — fixed, for the reason above
- The modifiers themselves — Ctrl, Shift, Alt and both Windows keys, left and right variants included. A modifier alone is not a shortcut
- F4 — it would collide with Alt+F4
The binding editor refuses these rather than accepting them and behaving oddly later.
The context menu (right click) shows the same actions with their current combinations, so a rebound key is discoverable without opening the settings.
Compare filters is a submenu there, with the two directions inside. Its key stands on the submenu rather than on either direction, because F12 switches compare on in whichever direction was chosen last.
A double click on the picture toggles fullscreen, as in any video player.
Both clicks have to land on the bare picture (App::DoubleClickFullscreen()):
a first click that closed a menu or grabbed the compare divider would otherwise
turn the second into a switch nobody asked for. A third click counts as a new
first one. While the crop picker is open, clicks belong to it.
The button strip along the top is on by default, and everything it offers is also
on a key — but a key you have to know about first. showToolbar in
AppSettings turns it off for anyone who does.
The picture is fitted below the toolbar rather than drawn underneath it
(VideoRenderer::SetTopInset()), so the bar never covers what you are playing.
F1 cycles StatsDetail, which has three levels:
StatsDetail |
Shows |
|---|---|
Compact |
Frame rates and pipeline delay |
Normal |
Those, plus capture format, colour handling and audio buffer |
Full |
Everything, including device names and dropped frame counts |
Normal is where a wrong colour range verdict becomes visible. The virtual
camera reports itself elsewhere: Settings > Recording lists every program
reading it, with the format each one negotiated.