Experimental support for mouse
This commit is contained in:
parent
def33de9bc
commit
5eaf472fc0
|
@ -49,6 +49,45 @@ namespace InputModes
|
|||
static constexpr std::chrono::milliseconds idle_timeout{50};
|
||||
static constexpr std::chrono::milliseconds fs_check_timeout{500};
|
||||
|
||||
struct MouseHandler
|
||||
{
|
||||
bool handle_key(Key key, Context& context)
|
||||
{
|
||||
if (not context.has_window())
|
||||
return false;
|
||||
|
||||
if (key.modifiers == Key::Modifiers::MousePress)
|
||||
{
|
||||
m_dragging = true;
|
||||
m_anchor = context.window().buffer_coord(key.mouse_coord());
|
||||
context.selections() = SelectionList{ context.buffer(), m_anchor };
|
||||
return true;
|
||||
}
|
||||
if (key.modifiers == Key::Modifiers::MouseRelease)
|
||||
{
|
||||
if (not m_dragging)
|
||||
return true;
|
||||
m_dragging = false;
|
||||
auto cursor = context.window().buffer_coord(key.mouse_coord());
|
||||
context.selections() = SelectionList{ context.buffer(), Selection{m_anchor, cursor} };
|
||||
return true;
|
||||
}
|
||||
if (key.modifiers == Key::Modifiers::MousePos)
|
||||
{
|
||||
if (not m_dragging)
|
||||
return true;
|
||||
auto cursor = context.window().buffer_coord(key.mouse_coord());
|
||||
context.selections() = SelectionList{ context.buffer(), Selection{m_anchor, cursor} };
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_dragging = false;
|
||||
ByteCoord m_anchor;
|
||||
};
|
||||
|
||||
class Normal : public InputMode
|
||||
{
|
||||
public:
|
||||
|
@ -87,6 +126,9 @@ public:
|
|||
|
||||
void on_key(Key key) override
|
||||
{
|
||||
if (m_mouse_handler.handle_key(key, context()))
|
||||
return;
|
||||
|
||||
if (m_waiting_for_reg)
|
||||
{
|
||||
if (key.modifiers == Key::Modifiers::None)
|
||||
|
@ -139,6 +181,7 @@ public:
|
|||
}
|
||||
m_params = { 0, '"' };
|
||||
}
|
||||
|
||||
context().hooks().run_hook("NormalKey", key_to_str(key), context());
|
||||
m_idle_timer.set_next_date(Clock::now() + idle_timeout);
|
||||
}
|
||||
|
@ -167,6 +210,7 @@ private:
|
|||
bool m_waiting_for_reg = false;
|
||||
Timer m_idle_timer;
|
||||
Timer m_fs_check_timer;
|
||||
MouseHandler m_mouse_handler;
|
||||
};
|
||||
|
||||
template<WordType word_type>
|
||||
|
@ -1109,7 +1153,8 @@ void InputHandler::on_next_key(KeymapMode keymap_mode, KeyCallback callback)
|
|||
|
||||
static bool is_valid(Key key)
|
||||
{
|
||||
return key != Key::Invalid and key.key <= 0x10FFFF;
|
||||
return key != Key::Invalid and
|
||||
((key.modifiers & ~Key::Modifiers::ControlAlt) or key.key <= 0x10FFFF);
|
||||
}
|
||||
|
||||
void InputHandler::handle_key(Key key)
|
||||
|
|
15
src/keys.hh
15
src/keys.hh
|
@ -5,6 +5,7 @@
|
|||
#include "flags.hh"
|
||||
#include "hash.hh"
|
||||
#include "vector.hh"
|
||||
#include "coord.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -16,7 +17,11 @@ struct Key
|
|||
None = 0,
|
||||
Control = 1 << 0,
|
||||
Alt = 1 << 1,
|
||||
ControlAlt = Control | Alt
|
||||
ControlAlt = Control | Alt,
|
||||
|
||||
MousePress = 1 << 2,
|
||||
MouseRelease = 1 << 3,
|
||||
MousePos = 1 << 4,
|
||||
};
|
||||
enum NamedKey : Codepoint
|
||||
{
|
||||
|
@ -62,6 +67,8 @@ struct Key
|
|||
constexpr bool operator==(Key other) const { return val() == other.val(); }
|
||||
constexpr bool operator!=(Key other) const { return val() != other.val(); }
|
||||
constexpr bool operator<(Key other) const { return val() < other.val(); }
|
||||
|
||||
constexpr CharCoord mouse_coord() const { return {(int)((key & 0xFFFF0000) >> 16), (int)(key & 0x0000FFFF)}; }
|
||||
};
|
||||
|
||||
template<> struct WithBitOps<Key::Modifiers> : std::true_type {};
|
||||
|
@ -78,6 +85,12 @@ constexpr Key alt(Codepoint key) { return { Key::Modifiers::Alt, key }; }
|
|||
constexpr Key ctrl(Codepoint key) { return { Key::Modifiers::Control, key }; }
|
||||
constexpr Key ctrlalt(Codepoint key) { return { Key::Modifiers::ControlAlt, key }; }
|
||||
|
||||
constexpr Codepoint encode_mouse_coord(CharCoord coord) { return (Codepoint)(((int)coord.line << 16) | ((int)coord.column & 0x0000FFFF)); }
|
||||
|
||||
constexpr Key mouse_press(CharCoord pos) { return { Key::Modifiers::MousePress, encode_mouse_coord(pos) }; }
|
||||
constexpr Key mouse_release(CharCoord pos) { return { Key::Modifiers::MouseRelease, encode_mouse_coord(pos) }; }
|
||||
constexpr Key mouse_pos(CharCoord pos) { return { Key::Modifiers::MousePos, encode_mouse_coord(pos) }; }
|
||||
|
||||
inline size_t hash_value(const Key& key) { return hash_values(key.modifiers, key.key); }
|
||||
|
||||
}
|
||||
|
|
|
@ -260,6 +260,10 @@ NCursesUI::NCursesUI()
|
|||
signal(SIGWINCH, on_term_resize);
|
||||
signal(SIGINT, on_sigint);
|
||||
|
||||
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, nullptr);
|
||||
mouseinterval(0);
|
||||
// force enable report mouse position
|
||||
printf("\033[?1002h");
|
||||
update_dimensions();
|
||||
|
||||
wrefresh(stdscr);
|
||||
|
@ -267,6 +271,7 @@ NCursesUI::NCursesUI()
|
|||
|
||||
NCursesUI::~NCursesUI()
|
||||
{
|
||||
printf("\033[?1002l");
|
||||
endwin();
|
||||
signal(SIGWINCH, SIG_DFL);
|
||||
signal(SIGINT, SIG_DFL);
|
||||
|
@ -442,6 +447,19 @@ Key NCursesUI::get_key()
|
|||
check_resize();
|
||||
|
||||
const int c = getch();
|
||||
|
||||
if (c == KEY_MOUSE)
|
||||
{
|
||||
MEVENT ev;
|
||||
if (getmouse(&ev) == OK)
|
||||
{
|
||||
CharCoord pos{ ev.y, ev.x };
|
||||
if ((ev.bstate & BUTTON1_PRESSED) == BUTTON1_PRESSED) return mouse_press(pos);
|
||||
if ((ev.bstate & BUTTON1_RELEASED) == BUTTON1_RELEASED) return mouse_release(pos);
|
||||
else return mouse_pos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (c > 0 and c < 27)
|
||||
{
|
||||
if (c == CTRL('l'))
|
||||
|
|
Loading…
Reference in New Issue
Block a user