From bee96376c97299daeaa48cf07eebf061a7a23d27 Mon Sep 17 00:00:00 2001 From: Timothy Werquin Date: Mon, 25 Jan 2021 20:03:07 +0100 Subject: [PATCH] Yaft: change keyboard hold behaviour --- apps/yaft/ctrlseq/csi.h | 4 ++++ apps/yaft/keyboard.cpp | 48 ++++++++++++++++++++++++++--------------- apps/yaft/keyboard.h | 7 ++++-- apps/yaft/yaft.h | 15 ++++++++----- 4 files changed, 50 insertions(+), 24 deletions(-) diff --git a/apps/yaft/ctrlseq/csi.h b/apps/yaft/ctrlseq/csi.h index 2d4add8..b303be6 100755 --- a/apps/yaft/ctrlseq/csi.h +++ b/apps/yaft/ctrlseq/csi.h @@ -431,6 +431,8 @@ set_mode(struct terminal_t* term, struct parm_t* parm) { term->mode |= MODE_VWBS; } else if (mode == 1000) { term->mode |= MODE_MOUSE; + } else if (mode == 1002) { + term->mode |= MODE_MOUSE_MOVE; } else { printf("UNKNOWN MODE: %d\n", mode); } @@ -461,6 +463,8 @@ reset_mode(struct terminal_t* term, struct parm_t* parm) { term->mode &= ~MODE_VWBS; } else if (mode == 1000) { term->mode &= ~MODE_MOUSE; + } else if (mode == 1002) { + term->mode &= ~MODE_MOUSE_MOVE; } } } diff --git a/apps/yaft/keyboard.cpp b/apps/yaft/keyboard.cpp index 3f42180..d9bd3ff 100755 --- a/apps/yaft/keyboard.cpp +++ b/apps/yaft/keyboard.cpp @@ -263,7 +263,7 @@ Keyboard::init(rmlib::fb::FrameBuffer& fb, terminal_t& term) { int y = startHeight; int rowNum = 0; for (const auto& row : layout) { - int x = 0; + int x = (fb.canvas.width - row_size * baseKeyWidth) / 2; for (const auto& key : row) { const auto keyWidth = baseKeyWidth * key.width; @@ -337,10 +337,13 @@ Keyboard::drawKey(const Key& key) const { if (key.isDown()) { auto a = key.keyRect.topLeft + Point{ 2, 2 }; auto b = key.keyRect.bottomRight - Point{ 1, 1 }; - fb->canvas.drawLine(a, { b.x, a.y }, 0x0); fb->canvas.drawLine(a, { a.x, b.y }, 0x0); fb->canvas.drawLine(b, { b.x, a.y }, 0x0); - fb->canvas.drawLine(b, { a.x, b.y }, 0x0); + + if (key.held) { + fb->canvas.drawLine(a, { b.x, a.y }, 0x0); + fb->canvas.drawLine(b, { a.x, b.y }, 0x0); + } } } @@ -419,15 +422,18 @@ struct event_traits { template void handleScreenEvent(Keyboard& kb, const Event& ev) { - if ((kb.term->mode & MODE_MOUSE) == 0) { + if ((kb.term->mode & ALL_MOUSE_MODES) == 0) { return; } const auto slot = event_traits::getSlot(ev); - const auto loc = ev.location - kb.screenRect.topLeft; - char cx = 33 + (loc.x / CELL_WIDTH); - char cy = 33 + (loc.y / CELL_HEIGHT); + auto loc = ev.location - kb.screenRect.topLeft; + loc.x /= CELL_WIDTH; + loc.y /= CELL_HEIGHT; + + char cx = 33 + loc.x; + char cy = 33 + loc.y; char buf[] = { esc_char, '[', 'M', 32, cx, cy }; if (ev.type == event_traits::down_type) { @@ -451,8 +457,13 @@ handleScreenEvent(Keyboard& kb, const Event& ev) { // Send mouse up code buf[3] += 3; // mouse release write(kb.term->fd, buf, 6); + } else if (kb.mouseSlot != -1 && kb.lastMousePos != loc && + (kb.term->mode & MODE_MOUSE_MOVE) != 0) { + buf[3] += 32; // mouse move + write(kb.term->fd, buf, 6); } -} + kb.lastMousePos = loc; +} // namespace template void @@ -469,18 +480,14 @@ handleKeyEvent(Keyboard& kb, const Event& ev) { key->slot = event_traits::getSlot(ev); key->nextRepeat = time_source::now() + repeat_delay; - kb.drawKey(*key); - kb.fb->doUpdate( - key->keyRect, rmlib::fb::Waveform::DU, rmlib::fb::UpdateFlags::None); - kb.sendKeyDown(*key); // Clear sticky keys. if (!isModifier(key->info.code)) { for (auto* key : { kb.shiftKey, kb.altKey, kb.ctrlKey }) { + key->nextRepeat = time_source::now() + repeat_delay; if (key->stuck) { key->stuck = false; - key->nextRepeat = time_source::now() + repeat_delay; kb.drawKey(*key); kb.fb->doUpdate(key->keyRect, rmlib::fb::Waveform::DU, @@ -488,13 +495,16 @@ handleKeyEvent(Keyboard& kb, const Event& ev) { } } } else { - if constexpr (std::is_same_v) { + if (!key->held) { key->stuck = !key->stuck; - } else { - key->stuck = false; } + key->held = false; } + kb.drawKey(*key); + kb.fb->doUpdate( + key->keyRect, rmlib::fb::Waveform::DU, rmlib::fb::UpdateFlags::None); + } else if (ev.type == event_traits::up_type) { const auto slot = event_traits::getSlot(ev); auto keyIt = @@ -543,7 +553,11 @@ Keyboard::updateRepeat() { if (time > key.nextRepeat) { // If a modifier is long pressed, stick it. if (isModifier(key.info.code)) { - key.stuck = true; + key.held = true; + + drawKey(key); + fb->doUpdate( + key.keyRect, rmlib::fb::Waveform::DU, rmlib::fb::UpdateFlags::None); } sendKeyDown(key); diff --git a/apps/yaft/keyboard.h b/apps/yaft/keyboard.h index 3e7272e..e0ce5ad 100755 --- a/apps/yaft/keyboard.h +++ b/apps/yaft/keyboard.h @@ -37,9 +37,11 @@ struct Keyboard { rmlib::Rect keyRect; int slot = -1; - bool stuck = false; - bool isDown() const { return slot != -1 || stuck; } + bool stuck = false; // Used for mod keys, get stuck after tap. + bool held = false; // Used for mod keys, held down after long press. + + bool isDown() const { return slot != -1 || stuck || held; } time_source::time_point nextRepeat; }; @@ -67,6 +69,7 @@ struct Keyboard { terminal_t* term; int mouseSlot = -1; + rmlib::Point lastMousePos; // Pointers for tracking modifier state. Key* shiftKey = nullptr; diff --git a/apps/yaft/yaft.h b/apps/yaft/yaft.h index 9b8e0b9..262e20b 100755 --- a/apps/yaft/yaft.h +++ b/apps/yaft/yaft.h @@ -126,37 +126,42 @@ enum term_mode { MODE_VWBS = 0x08, /* variable-width backspace */ MODE_APP_CURSOR = 0x10, /* app cursor mode */ MODE_MOUSE = 0x20, /* enable xterm mouse */ + MODE_MOUSE_MOVE = 0x40, /* enable xterm mouse */ }; #ifdef __cplusplus -inline term_mode& +constexpr term_mode& operator|=(term_mode& m, term_mode o) { m = (term_mode)(m | o); return m; } -inline term_mode +constexpr term_mode operator|(term_mode m, term_mode o) { return (term_mode)((int)m | (int)o); } -inline term_mode& +constexpr term_mode& operator&=(term_mode& m, term_mode o) { m = (term_mode)(m & o); return m; } -inline term_mode +constexpr term_mode operator&(term_mode m, term_mode o) { return (term_mode)((int)m & (int)o); } -inline term_mode +constexpr term_mode operator~(term_mode m) { return (term_mode)(~(int)m); } #endif +enum { + ALL_MOUSE_MODES = MODE_MOUSE_MOVE | MODE_MOUSE, +}; + enum esc_state { STATE_RESET = 0x00, STATE_ESC = 0x01, /* 0x1B, \033, ESC */