diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index 20c1eb9655..68359615d9 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -210,6 +210,11 @@ int main(int argc, char** argv) })); menubar->add_menu(move(app_menu)); + auto edit_menu = make("Edit"); + edit_menu->add_action(terminal->copy_action()); + edit_menu->add_action(terminal->paste_action()); + menubar->add_menu(move(edit_menu)); + auto font_menu = make("Font"); GFontDatabase::the().for_each_fixed_width_font([&](const StringView& font_name) { font_menu->add_action(GAction::create(font_name, [&](const GAction& action) { diff --git a/Libraries/LibVT/TerminalWidget.cpp b/Libraries/LibVT/TerminalWidget.cpp index 6296e1d738..e00142faff 100644 --- a/Libraries/LibVT/TerminalWidget.cpp +++ b/Libraries/LibVT/TerminalWidget.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +91,14 @@ TerminalWidget::TerminalWidget(int ptm_fd, bool automatic_size_policy, RefPtrread_num_entry("Window", "Width", 80), m_config->read_num_entry("Window", "Height", 25)); + + m_copy_action = GAction::create("Copy", { Mod_Ctrl | Mod_Shift, Key_C }, GraphicsBitmap::load_from_file("/res/icons/16x16/edit-copy.png"), [this](auto&) { + copy(); + }); + + m_paste_action = GAction::create("Paste", { Mod_Ctrl | Mod_Shift, Key_V }, GraphicsBitmap::load_from_file("/res/icons/paste16.png"), [this](auto&) { + paste(); + }); } TerminalWidget::~TerminalWidget() @@ -495,6 +504,26 @@ void TerminalWidget::doubleclick_event(GMouseEvent& event) GFrame::doubleclick_event(event); } +void TerminalWidget::paste() +{ + if (m_ptm_fd == -1) + return; + auto text = GClipboard::the().data(); + if (text.is_empty()) + return; + int nwritten = write(m_ptm_fd, text.characters(), text.length()); + if (nwritten < 0) { + perror("write"); + ASSERT_NOT_REACHED(); + } +} + +void TerminalWidget::copy() +{ + if (has_selection()) + GClipboard::the().set_data(selected_text()); +} + void TerminalWidget::mousedown_event(GMouseEvent& event) { if (event.button() == GMouseButton::Left) { @@ -505,25 +534,11 @@ void TerminalWidget::mousedown_event(GMouseEvent& event) auto position = buffer_position_at(event.position()); m_selection_start = { position.row(), start_column }; m_selection_end = { position.row(), end_column }; - - if (has_selection()) - GClipboard::the().set_data(selected_text()); } else { m_selection_start = buffer_position_at(event.position()); m_selection_end = {}; } update(); - } else if (event.button() == GMouseButton::Middle) { - if (m_ptm_fd == -1) - return; - auto text = GClipboard::the().data(); - if (text.is_empty()) - return; - int nwritten = write(m_ptm_fd, text.characters(), text.length()); - if (nwritten < 0) { - perror("write"); - ASSERT_NOT_REACHED(); - } } } diff --git a/Libraries/LibVT/TerminalWidget.h b/Libraries/LibVT/TerminalWidget.h index 8c06844840..3c56ac1e1b 100644 --- a/Libraries/LibVT/TerminalWidget.h +++ b/Libraries/LibVT/TerminalWidget.h @@ -48,6 +48,12 @@ public: bool is_scrollable() const; + GAction& copy_action() { return *m_copy_action; } + GAction& paste_action() { return *m_paste_action; } + + void copy(); + void paste(); + virtual bool accepts_focus() const override { return true; } Function on_title_change; @@ -119,5 +125,8 @@ private: RefPtr m_scrollbar; + RefPtr m_copy_action; + RefPtr m_paste_action; + CElapsedTimer m_triple_click_timer; };