Skip to content

Commit

Permalink
close #239 (enable keyboard handling in command handlers on linux)
Browse files Browse the repository at this point in the history
  • Loading branch information
daniele77 committed Apr 26, 2024
1 parent af87753 commit 17dafd8
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Parent menus does not chain (issue [#234](https://github.com/daniele77/cli/issues/234))
- Parent menu shortcut (issue [#233](https://github.com/daniele77/cli/issues/233))
- Integer overflow warning detected by clang++ (issue [#236](https://github.com/daniele77/cli/issues/236))
- Enable Keyboard Handling in Command Handlers on Linux Platform (issue [#239](https://github.com/daniele77/cli/issues/239))

## [2.1.0] - 2023-06-29

Expand Down
2 changes: 2 additions & 0 deletions include/cli/detail/inputdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class InputDevice

explicit InputDevice(Scheduler& _scheduler) : scheduler(_scheduler) {}
virtual ~InputDevice() = default;
virtual void ActivateInput() {}
virtual void DeactivateInput() {}

template <typename H>
void Register(H&& h) { handler = std::forward<H>(h); }
Expand Down
8 changes: 6 additions & 2 deletions include/cli/detail/inputhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ namespace detail
class InputHandler
{
public:
InputHandler(CliSession& _session, InputDevice& kb) :
InputHandler(CliSession& _session, InputDevice& _kb) :
session(_session),
terminal(session.OutStream())
terminal(session.OutStream()),
kb(_kb)
{
kb.Register( [this](auto key){ this->Keypressed(key); } );
}
Expand Down Expand Up @@ -75,8 +76,10 @@ class InputHandler
}
case Symbol::command:
{
kb.DeactivateInput();
session.Feed(s.second);
session.Prompt();
kb.ActivateInput();
break;
}
case Symbol::down:
Expand Down Expand Up @@ -124,6 +127,7 @@ class InputHandler

CliSession& session;
Terminal terminal;
InputDevice& kb;
};

} // namespace detail
Expand Down
26 changes: 24 additions & 2 deletions include/cli/detail/linuxkeyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@

#include <thread>
#include <memory>
#include <stdexcept>

#include <cstdio>
#include <termios.h>
#include <unistd.h>
#include <sys/select.h>
#include <cassert>

#include <condition_variable>
#include "inputdevice.h"


Expand Down Expand Up @@ -106,16 +107,30 @@ class LinuxKeyboard : public InputDevice
public:
explicit LinuxKeyboard(Scheduler& _scheduler) :
InputDevice(_scheduler),
enabled(false),
servant( [this]() noexcept { Read(); } )
{
ToManualMode();
ActivateInput();
}
~LinuxKeyboard() override
{
ToStandardMode();
is.Stop();
servant.join();
}
void ActivateInput() override
{
ToManualMode();
std::lock_guard<std::mutex> lock(mtx);
enabled = true;
cv.notify_one();
}
void DeactivateInput() override
{
ToStandardMode();
std::lock_guard<std::mutex> lock(mtx);
enabled = false;
}

private:

Expand All @@ -125,6 +140,10 @@ class LinuxKeyboard : public InputDevice
{
while (true)
{
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this]{ return enabled; }); // release mtx, suspend thread execution until enabled becomes true
}
auto k = Get();
Notify(k);
}
Expand Down Expand Up @@ -205,10 +224,13 @@ class LinuxKeyboard : public InputDevice
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
}

bool enabled;
termios oldt;
termios newt;
InputSource is;
std::thread servant;
std::mutex mtx;
std::condition_variable cv;
};

} // namespace detail
Expand Down

0 comments on commit 17dafd8

Please sign in to comment.