diff --git a/doc/apps.md b/doc/apps.md
index 744d845e20..0f853da096 100644
--- a/doc/apps.md
+++ b/doc/apps.md
@@ -330,24 +330,27 @@ Hotkey | Description
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/settings.md b/doc/settings.md
index c9adc6fe4f..363b7d7529 100644
--- a/doc/settings.md
+++ b/doc/settings.md
@@ -887,27 +887,27 @@ Notes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/netxs/apps.hpp b/src/netxs/apps.hpp
index 66c841c962..530e0c8855 100644
--- a/src/netxs/apps.hpp
+++ b/src/netxs/apps.hpp
@@ -530,10 +530,10 @@ namespace netxs::app::shared
auto [menu_block, cover, menu_data] = menu::mini(faux, faux, 1,
menu::list
{
- { menu::item{ menu::item::type::Splitter, faux, 0, std::vector{{ .label = ver }}},
+ { menu::item{ menu::type::Splitter, faux, 0, std::vector{{ .label = ver }}},
[](auto& /*boss*/, auto& /*item*/)
{ }},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "×", .tooltip = " Close ", .hover = c1 }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "×", .tooltip = " Close ", .hover = c1 }}},
[window, c1](auto& boss, auto& /*item*/)
{
boss.template shader(cell::shaders::color(c1), e2::form::state::keybd::command::close, boss.This());
diff --git a/src/netxs/apps/term.hpp b/src/netxs/apps/term.hpp
index 0b5ae615e7..42ee26cd30 100644
--- a/src/netxs/apps/term.hpp
+++ b/src/netxs/apps/term.hpp
@@ -125,7 +125,7 @@ namespace netxs::app::terminal
template
auto _submit(ui::item& boss, menu::item& item, P proc)
{
- if (item.brand == menu::item::Repeat)
+ if (item.type == menu::type::Repeat)
{
auto& tick = boss.plugins();
boss.LISTEN(tier::release, hids::events::mouse::button::down::left, gear, -, (proc))
@@ -185,7 +185,7 @@ namespace netxs::app::terminal
proc(boss, item, gear);
if constexpr (AutoUpdate)
{
- if (item.brand == menu::item::Option) _update_gear(boss, item, gear);
+ if (item.type == menu::type::Option) _update_gear(boss, item, gear);
}
gear.nodbl = true;
};
@@ -198,81 +198,20 @@ namespace netxs::app::terminal
auto menudata = config.list(attr::menuitems);
- static auto brand_options = std::unordered_map
- {{ menu::type::Splitter, menu::item::Splitter },
- { menu::type::Command, menu::item::Command },
- { menu::type::Option, menu::item::Option },
- { menu::type::Repeat, menu::item::Repeat }};
+ static auto type_options = std::unordered_map
+ {{ "Splitter", menu::type::Splitter },
+ { "Command", menu::type::Command },
+ { "Option", menu::type::Option },
+ { "Repeat", menu::type::Repeat }};
- #define proc_list \
- X(Noop ) /* */ \
- X(ExclusiveKeyboardMode ) /* */ \
- X(TerminalQuit ) /* */ \
- X(TerminalCwdSync ) /* */ \
- X(TerminalFullscreen ) /* */ \
- X(TerminalMaximize ) /* */ \
- X(TerminalMinimize ) /* */ \
- X(TerminalRestart ) /* */ \
- X(TerminalSendKey ) /* */ \
- X(TerminalWrapMode ) /* */ \
- X(TerminalAlignMode ) /* */ \
- X(TerminalOutput ) /* */ \
- X(TerminalFindNext ) /* */ \
- X(TerminalFindPrev ) /* */ \
- X(TerminalUndo ) /* Undo/Redo for cooked read on win32 */ \
- X(TerminalRedo ) /* */ \
- X(TerminalClipboardCopy ) /* */ \
- X(TerminalClipboardPaste ) /* */ \
- X(TerminalClipboardWipe ) /* */ \
- X(TerminalClipboardFormat ) /* */ \
- X(TerminalSelectionRect ) /* Linear/Rectangular */ \
- X(TerminalSelectionCancel ) /* */ \
- X(TerminalSelectionOneShot ) /* One-shot toggle to copy text while mouse tracking is active */ \
- X(TerminalScrollViewportByPage) /* */ \
- X(TerminalScrollViewportByCell) /* */ \
- X(TerminalScrollViewportToTop ) /* */ \
- X(TerminalScrollViewportToEnd ) /* */ \
- X(TerminalViewportCopy ) /* */ \
- X(TerminalStdioLog ) /* */ \
- X(TerminalLogStart ) /* */ \
- X(TerminalLogPause ) /* */ \
- X(TerminalLogStop ) /* */ \
- X(TerminalLogAbort ) /* */ \
- X(TerminalLogRestart ) /* */ \
- X(TerminalVideoRecStart ) /* */ \
- X(TerminalVideoRecStop ) /* */ \
- X(TerminalVideoRecPause ) /* */ \
- X(TerminalVideoRecAbort ) /* */ \
- X(TerminalVideoRecRestart ) /* */ \
- X(TerminalVideoPlay ) /* */ \
- X(TerminalVideoPause ) /* */ \
- X(TerminalVideoStop ) /* */ \
- X(TerminalVideoForward ) /* */ \
- X(TerminalVideoBackward ) /* */ \
- X(TerminalVideoHome ) /* */ \
- X(TerminalVideoEnd ) /* */
+ using term = ui::term;
+ using preview = terminal::events::preview;
+ using release = terminal::events::release;
- enum func
+ static const auto proc_map = std::unordered_map, qiew::hash, qiew::equal>
{
- #define X(_proc) _proc,
- proc_list
- #undef X
- };
-
- static const auto route_options = std::unordered_map
- {
- #define X(_proc) { #_proc, func::_proc },
- proc_list
- #undef X
- };
-
- struct disp
- {
- using preview = terminal::events::preview;
- using release = terminal::events::release;
-
- static void Noop(ui::item& /*boss*/, menu::item& /*item*/) { }
- static void ExclusiveKeyboardMode(ui::item& boss, menu::item& item)
+ { term::action::Noop, [](ui::item& /*boss*/, menu::item& /*item*/){ } },
+ { term::action::ExclusiveKeyboardMode, [](ui::item& boss, menu::item& item)
{
item.reindex([](auto& utf8){ return xml::take_or(utf8, faux); });
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
@@ -283,8 +222,8 @@ namespace netxs::app::terminal
{
_update_to(boss, item, state);
};
- }
- static void TerminalWrapMode(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalWrapMode, [](ui::item& boss, menu::item& item)
{
item.reindex([](auto& utf8){ return xml::take(utf8).value() ? wrap::on : wrap::off; });
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
@@ -295,8 +234,8 @@ namespace netxs::app::terminal
{
_update_to(boss, item, wrapln);
};
- }
- static void TerminalAlignMode(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalAlignMode, [](ui::item& boss, menu::item& item)
{
item.reindex([](auto& utf8){ return netxs::get_or(xml::options::align, utf8, bias::left); });
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
@@ -307,8 +246,8 @@ namespace netxs::app::terminal
{
_update_to(boss, item, align);
};
- }
- static void TerminalFindPrev(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalFindPrev, [](ui::item& boss, menu::item& item)
{
item.reindex([](auto& utf8){ return xml::take(utf8).value(); });
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& gear)
@@ -319,8 +258,8 @@ namespace netxs::app::terminal
{
_update_to(boss, item, (status & 2) ? 1 : 0);
};
- }
- static void TerminalFindNext(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalFindNext, [](ui::item& boss, menu::item& item)
{
item.reindex([](auto& utf8){ return xml::take(utf8).value(); });
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& gear)
@@ -331,92 +270,92 @@ namespace netxs::app::terminal
{
_update_to(boss, item, (status & 1) ? 1 : 0);
};
- }
- static void TerminalOutput(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalOutput, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
{
boss.bell::signal(tier::anycast, terminal::events::data::in, view{ item.views[item.taken].data });
});
- }
- static void TerminalSendKey(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalSendKey, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
{
boss.bell::signal(tier::anycast, terminal::events::data::out, view{ item.views[item.taken].data });
});
- }
- static void TerminalQuit(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalQuit, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& /*gear*/)
{
boss.bell::signal(tier::anycast, terminal::events::cmd, ui::term::commands::ui::commands::sighup);
});
- }
- static void TerminalFullscreen(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalFullscreen, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& gear)
{
boss.base::riseup(tier::preview, e2::form::size::enlarge::fullscreen, gear);
});
- }
- static void TerminalMaximize(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalMaximize, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& gear)
{
boss.base::riseup(tier::preview, e2::form::size::enlarge::maximize, gear);
});
- }
- static void TerminalMinimize(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalMinimize, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& gear)
{
boss.base::riseup(tier::release, e2::form::size::minimize, gear);
});
- }
- static void TerminalRestart(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalRestart, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& /*gear*/)
{
boss.bell::signal(tier::anycast, terminal::events::cmd, ui::term::commands::ui::commands::restart);
});
- }
- static void TerminalUndo(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalUndo, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& /*gear*/)
{
boss.bell::signal(tier::anycast, terminal::events::cmd, ui::term::commands::ui::commands::undo);
});
- }
- static void TerminalRedo(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalRedo, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& /*gear*/)
{
boss.bell::signal(tier::anycast, terminal::events::cmd, ui::term::commands::ui::commands::redo);
});
- }
- static void TerminalClipboardPaste(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalClipboardPaste, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& gear)
{
boss.bell::signal(tier::anycast, terminal::events::data::paste, gear);
});
- }
- static void TerminalClipboardWipe(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalClipboardWipe, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& /*boss*/, auto& /*item*/, auto& gear)
{
gear.clear_clipboard();
});
- }
- static void TerminalClipboardCopy(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalClipboardCopy, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& gear)
{
boss.bell::signal(tier::anycast, terminal::events::data::copy, gear);
});
- }
- static void TerminalClipboardFormat(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalClipboardFormat, [](ui::item& boss, menu::item& item)
{
item.reindex([](auto& utf8){ return netxs::get_or(xml::options::format, utf8, mime::disabled); });
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
@@ -427,8 +366,8 @@ namespace netxs::app::terminal
{
_update_to(boss, item, mode);
};
- }
- static void TerminalSelectionOneShot(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalSelectionOneShot, [](ui::item& boss, menu::item& item)
{
item.reindex([](auto& utf8){ return netxs::get_or(xml::options::format, utf8, mime::disabled); });
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
@@ -439,8 +378,8 @@ namespace netxs::app::terminal
{
_update_to(boss, item, mode);
};
- }
- static void TerminalSelectionRect(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalSelectionRect, [](ui::item& boss, menu::item& item)
{
item.reindex([](auto& utf8){ return xml::take(utf8).value(); });
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
@@ -451,52 +390,52 @@ namespace netxs::app::terminal
{
_update_to(boss, item, selbox);
};
- }
- static void TerminalSelectionCancel(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalSelectionCancel, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& /*gear*/)
{
boss.bell::signal(tier::anycast, terminal::events::cmd, ui::term::commands::ui::commands::deselect);
});
- }
- static void TerminalViewportCopy(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalViewportCopy, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& gear)
{
boss.bell::signal(tier::anycast, terminal::events::data::prnscrn, gear);
});
- }
- static void TerminalScrollViewportByPage(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalScrollViewportByPage, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
{
auto delta = xml::take_or(item.views[item.taken].data, dot_00);
boss.bell::signal(tier::anycast, e2::form::upon::scroll::bypage::v, { .vector = delta });
});
- }
- static void TerminalScrollViewportByCell(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalScrollViewportByCell, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
{
auto delta = xml::take_or(item.views[item.taken].data, dot_00);
boss.bell::signal(tier::anycast, e2::form::upon::scroll::bystep::v, { .vector = delta });
});
- }
- static void TerminalScrollViewportToTop(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalScrollViewportToTop, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& /*gear*/)
{
boss.bell::signal(tier::anycast, e2::form::upon::scroll::to_top::y);
});
- }
- static void TerminalScrollViewportToEnd(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalScrollViewportToEnd, [](ui::item& boss, menu::item& item)
{
_submit(boss, item, [](auto& boss, auto& /*item*/, auto& /*gear*/)
{
boss.bell::signal(tier::anycast, e2::form::upon::scroll::to_end::y);
});
- }
- static void TerminalStdioLog(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalStdioLog, [](ui::item& boss, menu::item& item)
{
item.reindex([](auto& utf8){ return xml::take(utf8).value(); });
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
@@ -507,8 +446,8 @@ namespace netxs::app::terminal
{
_update_to(boss, item, state);
};
- }
- static void TerminalCwdSync(ui::item& boss, menu::item& item)
+ }},
+ { term::action::TerminalCwdSync, [](ui::item& boss, menu::item& item)
{
item.reindex([](auto& utf8){ return xml::take(utf8).value(); });
_submit(boss, item, [](auto& boss, auto& item, auto& /*gear*/)
@@ -519,84 +458,76 @@ namespace netxs::app::terminal
{
_update_to(boss, item, state);
};
- }
- static void TerminalLogStart(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalLogStart, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalLogPause(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalLogPause, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalLogStop(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalLogStop, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalLogAbort(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalLogAbort, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalLogRestart(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalLogRestart, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoRecStart(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoRecStart, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoRecStop(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoRecStop, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoRecPause(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoRecPause, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoRecAbort(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoRecAbort, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoRecRestart(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoRecRestart, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoPlay(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoPlay, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoPause(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoPause, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoStop(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoStop, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoForward(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoForward, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoBackward(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoBackward, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoHome(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoHome, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
- static void TerminalVideoEnd(ui::item& /*boss*/, menu::item& /*item*/)
+ }},
+ { term::action::TerminalVideoEnd, [](ui::item& /*boss*/, menu::item& /*item*/)
{
- }
+ }},
};
- using submit_proc = std::function;
- static const auto proc_map = std::unordered_map
- {
- #define X(_proc) { func::_proc, &disp::_proc },
- proc_list
- #undef X
- };
- #undef proc_list
auto list = menu::list{};
auto defs = menu::item::look{};
@@ -604,11 +535,11 @@ namespace netxs::app::terminal
{
auto item = menu::item{};
auto& data = *data_ptr;
- auto route = data.take(menu::attr::route, func::Noop, route_options);
- item.brand = data.take(menu::attr::brand, menu::item::Command, brand_options);
+ auto action = data.take(menu::attr::action, ""s);
+ item.type = data.take(menu::attr::type, menu::type::Command, type_options);
defs.tooltip = data.take(menu::attr::tooltip, ""s);
defs.data = data.take(menu::attr::data, ""s);
- item.alive = route != func::Noop && item.brand != menu::item::Splitter;
+ item.alive = !action.empty() && item.type != menu::type::Splitter;
for (auto label : data.list(menu::attr::label))
{
item.views.push_back(
@@ -619,17 +550,21 @@ namespace netxs::app::terminal
});
}
if (item.views.empty()) continue; // Menu item without label.
- auto setup = [route](ui::item& boss, menu::item& item)
+ auto setup = [action](ui::item& boss, menu::item& item)
{
- if (item.brand == menu::item::Option)
+ if (item.type == menu::type::Option)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
{
item.taken = (item.taken + 1) % item.views.size();
};
}
- auto& initproc = proc_map.find(route)->second;
- initproc(boss, item);
+ auto iter = proc_map.find(action);
+ if (iter != proc_map.end())
+ {
+ auto& initproc = iter->second;
+ initproc(boss, item);
+ }
};
list.push_back({ item, setup });
}
diff --git a/src/netxs/apps/tile.hpp b/src/netxs/apps/tile.hpp
index 30cf3b44db..b299197701 100644
--- a/src/netxs/apps/tile.hpp
+++ b/src/netxs/apps/tile.hpp
@@ -382,7 +382,7 @@ namespace netxs::app::tile
auto [menu_block, cover, menu_data] = menu::mini(true, faux, 1,
menu::list
{
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "+", .tooltip = " Launch application instance. \n"
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "+", .tooltip = " Launch application instance. \n"
" The app to run can be set by RightClick on the taskbar. " }}},
[](auto& boss, auto& /*item*/)
{
@@ -392,7 +392,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "│", .tooltip = " Split horizontally " }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "│", .tooltip = " Split horizontally " }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -401,7 +401,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "──", .tooltip = " Split vertically " }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "──", .tooltip = " Split vertically " }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -410,7 +410,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "×", .tooltip = " Delete pane ", .hover = c1 }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "×", .tooltip = " Delete pane ", .hover = c1 }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -836,12 +836,8 @@ namespace netxs::app::tile
auto [menu_block, cover, menu_data] = menu::create(config,
menu::list
{
- // Green ?Even Red
- // ┌────┐ ┌────┐ ┌─┬──┐ ┌────┐ ┌─┬──┐ ┌─┬──┐ ┌────┐ // ┌─┐ ┌─┬─┐ ┌─┬─┐ ┌─┬─┐
- // │Exec│ ├─┐ │ │ H │ ├ V ─┤ │Swap│ │Fair│ │Shut│ // ├─┤ └─┴─┘ └<┴>┘ └>┴<┘
- // └────┘ └─┴──┘ └─┴──┘ └────┘ └─┴──┘ └─┴──┘ └────┘ // └─┘
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = " + ", .tooltip = " Launch application instances in active empty slots. \n"
- " The app to run can be set by RightClick on the taskbar. " }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = " + ", .tooltip = " Launch application instances in active empty slots. \n"
+ " The app to run can be set by RightClick on the taskbar. " }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -850,7 +846,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = ":::", .tooltip = " Select all panes " }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = ":::", .tooltip = " Select all panes " }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -859,7 +855,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = " │ ", .tooltip = " Split active panes horizontally " }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = " │ ", .tooltip = " Split active panes horizontally " }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -868,7 +864,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "──", .tooltip = " Split active panes vertically " }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "──", .tooltip = " Split active panes vertically " }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -877,7 +873,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "┌┘", .tooltip = " Change split orientation " }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "┌┘", .tooltip = " Change split orientation " }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -886,7 +882,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "<->", .tooltip = " Swap two or more panes " }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "<->", .tooltip = " Swap two or more panes " }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -895,7 +891,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = ">|<", .tooltip = " Equalize split ratio " }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = ">|<", .tooltip = " Equalize split ratio " }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -904,7 +900,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "\"…\"", .tooltip = " Set tiling manager window title using clipboard data " }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "\"…\"", .tooltip = " Set tiling manager window title using clipboard data " }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -913,7 +909,7 @@ namespace netxs::app::tile
gear.nodbl = true;
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "×", .tooltip = " Close active app ", .hover = c1 }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "×", .tooltip = " Close active app ", .hover = c1 }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
diff --git a/src/netxs/desktopio/application.hpp b/src/netxs/desktopio/application.hpp
index 927251a5fe..c67eba26a2 100644
--- a/src/netxs/desktopio/application.hpp
+++ b/src/netxs/desktopio/application.hpp
@@ -24,7 +24,7 @@ namespace netxs::app
namespace netxs::app::shared
{
- static const auto version = "v0.9.99.54";
+ static const auto version = "v0.9.99.55";
static const auto repository = "https://github.com/directvt/vtm";
static const auto usr_config = "~/.config/vtm/settings.xml"s;
static const auto sys_config = "/etc/vtm/settings.xml"s;
@@ -144,9 +144,8 @@ namespace netxs::app::shared
keybd.proc("ScrollCharRight" , [&](hids& gear, txts&){ gear.set_handled(); scroll_inst.base::riseup(tier::preview, e2::form::upon::scroll::bystep::x, { .vector = {-3, 0 }}); });
keybd.proc("ScrollTop" , [&](hids& gear, txts&){ gear.set_handled(); scroll_inst.base::riseup(tier::preview, e2::form::upon::scroll::to_top::y); });
keybd.proc("ScrollEnd" , [&](hids& gear, txts&){ gear.set_handled(); scroll_inst.base::riseup(tier::preview, e2::form::upon::scroll::to_end::y); });
- //todo use sptr for gear when enqueueing (dangling reference)
- keybd.proc("ToggleMaximize" , [&](hids& gear, txts&){ gear.set_handled(); scroll_inst.bell::enqueue(boss.This(), [&](auto& /*boss*/){ scroll_inst.base::riseup(tier::preview, e2::form::size::enlarge::maximize, gear); }); }); // Refocus-related operations require execution outside of keyboard eves.
- keybd.proc("ToggleFullscreen", [&](hids& gear, txts&){ gear.set_handled(); scroll_inst.bell::enqueue(boss.This(), [&](auto& /*boss*/){ scroll_inst.base::riseup(tier::preview, e2::form::size::enlarge::fullscreen, gear); }); });
+ keybd.proc("ToggleMaximize" , [&](hids& gear, txts&){ gear.set_handled(); scroll_inst.bell::enqueue(boss.This(), [&, gear_id = gear.id](auto& /*boss*/){ if (auto gear_ptr = boss.bell::getref(gear_id)) scroll_inst.base::riseup(tier::preview, e2::form::size::enlarge::maximize, *gear_ptr); }); }); // Refocus-related operations require execution outside of keyboard eves.
+ keybd.proc("ToggleFullscreen", [&](hids& gear, txts&){ gear.set_handled(); scroll_inst.bell::enqueue(boss.This(), [&, gear_id = gear.id](auto& /*boss*/){ if (auto gear_ptr = boss.bell::getref(gear_id)) scroll_inst.base::riseup(tier::preview, e2::form::size::enlarge::fullscreen, *gear_ptr); }); });
keybd.bind( "Esc", "DropAutoRepeat" , true);
keybd.bind( "Esc", "WindowClosePreview", true);
@@ -194,30 +193,23 @@ namespace netxs::app::shared
{
namespace attr
{
- static constexpr auto brand = "type";
- static constexpr auto label = "label";
+ static constexpr auto type = "type";
+ static constexpr auto label = "label";
static constexpr auto tooltip = "tooltip";
- static constexpr auto route = "action";
- static constexpr auto data = "data";
+ static constexpr auto action = "action";
+ static constexpr auto data = "data";
}
namespace type
{
- static const auto Command = "Command"s;
- static const auto Splitter = "Splitter"s;
- static const auto Option = "Option"s;
- static const auto Repeat = "Repeat"s;
+ static constexpr auto _counter = __COUNTER__ + 1;
+ static constexpr auto Splitter = __COUNTER__ - _counter;
+ static constexpr auto Command = __COUNTER__ - _counter;
+ static constexpr auto Option = __COUNTER__ - _counter;
+ static constexpr auto Repeat = __COUNTER__ - _counter;
}
struct item
{
- enum type
- {
- Splitter,
- Command,
- Option,
- Repeat,
- };
-
struct look
{
text label{};
@@ -231,7 +223,7 @@ namespace netxs::app::shared
using umap = std::unordered_map;
using list = std::vector;
- type brand{};
+ si32 type{};
bool alive{};
si32 taken{}; // Active label index.
list views{};
@@ -333,7 +325,7 @@ namespace netxs::app::shared
{
auto control = std::vector
{
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "—", .tooltip = " Minimize " }}},//, .hover = c2 }}}, //toto too funky
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "—", .tooltip = " Minimize " }}},//, .hover = c2 }}}, //toto too funky
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -342,7 +334,7 @@ namespace netxs::app::shared
gear.dismiss();
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "□", .tooltip = " Maximize " }}},//, .hover = c6 }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "□", .tooltip = " Maximize " }}},//, .hover = c6 }}},
[](auto& boss, auto& /*item*/)
{
boss.LISTEN(tier::release, hids::events::mouse::button::click::left, gear)
@@ -351,7 +343,7 @@ namespace netxs::app::shared
gear.dismiss();
};
}},
- { menu::item{ menu::item::type::Command, true, 0, std::vector{{ .label = "×", .tooltip = " Close ", .hover = c1 }}},
+ { menu::item{ menu::type::Command, true, 0, std::vector{{ .label = "×", .tooltip = " Close ", .hover = c1 }}},
[c1](auto& boss, auto& /*item*/)
{
boss.template shader(cell::shaders::color(c1), e2::form::state::keybd::command::close);
@@ -460,11 +452,11 @@ namespace netxs::app::shared
//auto c3 = highlight_color;
auto items = list
{
- { item{ item::type::Command, true, 0, std::vector{{ .label = ansi::und(true).add("F").nil().add("ile"), .tooltip = " File menu item " }}}, [&](auto& /*boss*/, auto& /*item*/){ }},
- { item{ item::type::Command, true, 0, std::vector{{ .label = ansi::und(true).add("E").nil().add("dit"), .tooltip = " Edit menu item " }}}, [&](auto& /*boss*/, auto& /*item*/){ }},
- { item{ item::type::Command, true, 0, std::vector{{ .label = ansi::und(true).add("V").nil().add("iew"), .tooltip = " View menu item " }}}, [&](auto& /*boss*/, auto& /*item*/){ }},
- { item{ item::type::Command, true, 0, std::vector{{ .label = ansi::und(true).add("D").nil().add("ata"), .tooltip = " Data menu item " }}}, [&](auto& /*boss*/, auto& /*item*/){ }},
- { item{ item::type::Command, true, 0, std::vector{{ .label = ansi::und(true).add("H").nil().add("elp"), .tooltip = " Help menu item " }}}, [&](auto& /*boss*/, auto& /*item*/){ }},
+ { item{ type::Command, true, 0, std::vector{{ .label = ansi::und(true).add("F").nil().add("ile"), .tooltip = " File menu item " }}}, [&](auto& /*boss*/, auto& /*item*/){ }},
+ { item{ type::Command, true, 0, std::vector{{ .label = ansi::und(true).add("E").nil().add("dit"), .tooltip = " Edit menu item " }}}, [&](auto& /*boss*/, auto& /*item*/){ }},
+ { item{ type::Command, true, 0, std::vector{{ .label = ansi::und(true).add("V").nil().add("iew"), .tooltip = " View menu item " }}}, [&](auto& /*boss*/, auto& /*item*/){ }},
+ { item{ type::Command, true, 0, std::vector{{ .label = ansi::und(true).add("D").nil().add("ata"), .tooltip = " Data menu item " }}}, [&](auto& /*boss*/, auto& /*item*/){ }},
+ { item{ type::Command, true, 0, std::vector{{ .label = ansi::und(true).add("H").nil().add("elp"), .tooltip = " Help menu item " }}}, [&](auto& /*boss*/, auto& /*item*/){ }},
};
auto [menu, cover, menu_data] = create(config, items);
return menu;
diff --git a/src/netxs/desktopio/terminal.hpp b/src/netxs/desktopio/terminal.hpp
index a01d31eb38..539b596786 100644
--- a/src/netxs/desktopio/terminal.hpp
+++ b/src/netxs/desktopio/terminal.hpp
@@ -53,6 +53,63 @@ namespace netxs::ui
{
using events = netxs::events::userland::uiterm;
+ #define proc_list \
+ X(Noop ) /* */ \
+ X(ExclusiveKeyboardMode ) /* */ \
+ X(TerminalQuit ) /* */ \
+ X(TerminalCwdSync ) /* */ \
+ X(TerminalFullscreen ) /* */ \
+ X(TerminalMaximize ) /* */ \
+ X(TerminalMinimize ) /* */ \
+ X(TerminalRestart ) /* */ \
+ X(TerminalSendKey ) /* */ \
+ X(TerminalWrapMode ) /* */ \
+ X(TerminalAlignMode ) /* */ \
+ X(TerminalOutput ) /* */ \
+ X(TerminalFindNext ) /* */ \
+ X(TerminalFindPrev ) /* */ \
+ X(TerminalUndo ) /* Undo/Redo for cooked read on win32 */ \
+ X(TerminalRedo ) /* */ \
+ X(TerminalClipboardCopy ) /* */ \
+ X(TerminalClipboardPaste ) /* */ \
+ X(TerminalClipboardWipe ) /* */ \
+ X(TerminalClipboardFormat ) /* */ \
+ X(TerminalSelectionRect ) /* Linear/Rectangular */ \
+ X(TerminalSelectionCancel ) /* */ \
+ X(TerminalSelectionOneShot ) /* One-shot toggle to copy text while mouse tracking is active */ \
+ X(TerminalScrollViewportByPage) /* */ \
+ X(TerminalScrollViewportByCell) /* */ \
+ X(TerminalScrollViewportToTop ) /* */ \
+ X(TerminalScrollViewportToEnd ) /* */ \
+ X(TerminalViewportCopy ) /* */ \
+ X(TerminalStdioLog ) /* */ \
+ X(TerminalLogStart ) /* */ \
+ X(TerminalLogPause ) /* */ \
+ X(TerminalLogStop ) /* */ \
+ X(TerminalLogAbort ) /* */ \
+ X(TerminalLogRestart ) /* */ \
+ X(TerminalVideoRecStart ) /* */ \
+ X(TerminalVideoRecStop ) /* */ \
+ X(TerminalVideoRecPause ) /* */ \
+ X(TerminalVideoRecAbort ) /* */ \
+ X(TerminalVideoRecRestart ) /* */ \
+ X(TerminalVideoPlay ) /* */ \
+ X(TerminalVideoPause ) /* */ \
+ X(TerminalVideoStop ) /* */ \
+ X(TerminalVideoForward ) /* */ \
+ X(TerminalVideoBackward ) /* */ \
+ X(TerminalVideoHome ) /* */ \
+ X(TerminalVideoEnd ) /* */
+
+ struct action
+ {
+ #define X(_proc) static constexpr auto _proc = #_proc;
+ proc_list
+ #undef X
+ };
+
+ #undef proc_list
+
struct commands
{
struct erase
@@ -7744,35 +7801,34 @@ namespace netxs::ui
publish_property(ui::term::events::search::status, [&](auto& v){ v = target->selection_button(); });
selection_selmod(config.def_selmod);
- chords.proc("TerminalScrollViewportByPage", [&](hids& gear, txts& args){ if (target != &normal) return; gear.set_handled(); base::riseup(tier::preview, e2::form::upon::scroll::bypage::v, { .vector = args.size() ? xml::take_or(args.front(), dot_00) : dot_00 }); });
- chords.proc("TerminalScrollViewportByCell", [&](hids& gear, txts& args){ if (target != &normal) return; gear.set_handled(); base::riseup(tier::preview, e2::form::upon::scroll::bystep::v, { .vector = args.size() ? xml::take_or(args.front(), dot_00) : dot_00 }); });
- chords.proc("TerminalScrollViewportToTop", [&](hids& gear, txts&){ if (target != &normal) return; gear.set_handled(); base::riseup(tier::preview, e2::form::upon::scroll::to_top::y); });
- chords.proc("TerminalScrollViewportToEnd", [&](hids& gear, txts&){ if (target != &normal) return; gear.set_handled(); base::riseup(tier::preview, e2::form::upon::scroll::to_end::y); });
- chords.proc("TerminalFindPrev", [&](hids& gear, txts&){ gear.set_handled(); selection_search(gear, feed::rev); });
- chords.proc("TerminalFindNext", [&](hids& gear, txts&){ gear.set_handled(); selection_search(gear, feed::fwd); });
- chords.proc("TerminalCwdSync", [&](hids& gear, txts&){ gear.set_handled(); base::riseup(tier::preview, ui::term::events::toggle::cwdsync, true); });
- chords.proc("TerminalQuit", [&](hids& gear, txts&){ gear.set_handled(); exec_cmd(commands::ui::sighup); });
- chords.proc("TerminalRestart", [&](hids& gear, txts&){ gear.set_handled(); exec_cmd(commands::ui::restart); });
- //todo use wptr for gear when enqueueing
- chords.proc("TerminalFullscreen", [&](hids& gear, txts&){ gear.set_handled(); bell::enqueue(This(), [&](auto& /*boss*/){ base::riseup(tier::preview, e2::form::size::enlarge::fullscreen, gear); }); }); // Refocus-related operations require execution outside of keyboard events.
- chords.proc("TerminalMaximize", [&](hids& gear, txts&){ gear.set_handled(); bell::enqueue(This(), [&](auto& /*boss*/){ base::riseup(tier::preview, e2::form::size::enlarge::maximize, gear); }); });
- chords.proc("TerminalMinimize", [&](hids& gear, txts&){ gear.set_handled(); bell::enqueue(This(), [&](auto& /*boss*/){ base::riseup(tier::release, e2::form::size::minimize, gear); }); });
- chords.proc("TerminalUndo", [&](hids& gear, txts&){ gear.set_handled(); exec_cmd(commands::ui::undo); });
- chords.proc("TerminalRedo", [&](hids& gear, txts&){ gear.set_handled(); exec_cmd(commands::ui::redo); });
- chords.proc("TerminalClipboardCopy", [&](hids& gear, txts&){ gear.set_handled(); copy(gear); });
- chords.proc("TerminalClipboardPaste", [&](hids& gear, txts&){ gear.set_handled(); paste(gear); });
- chords.proc("TerminalClipboardWipe", [&](hids& gear, txts&){ gear.set_handled(); gear.clear_clipboard(); });
- chords.proc("TerminalClipboardFormat", [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) exec_cmd(commands::ui::togglesel); else set_selmod((si32)netxs::get_or(xml::options::format, args.front(), mime::textonly)); });
- chords.proc("TerminalViewportCopy", [&](hids& gear, txts&){ gear.set_handled(); prnscrn(gear); });
- chords.proc("TerminalSelectionCancel", [&](hids& gear, txts&){ if (!selection_active()) return; gear.set_handled(); exec_cmd(commands::ui::deselect); });
- chords.proc("TerminalSelectionRect", [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) exec_cmd(commands::ui::toggleselalt); else set_selalt(xml::take_or(args.front(), faux)); });
- chords.proc("TerminalSelectionOneShot", [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) set_oneshot(mime::textonly); else set_oneshot(netxs::get_or(xml::options::format, args.front(), mime::textonly)); });
- chords.proc("TerminalStdioLog", [&](hids& gear, txts& args){ gear.set_handled(); set_log(args.size() ? xml::take_or(args.front(), !io_log) : !io_log); ondata(); });
- chords.proc("TerminalSendKey", [&](hids& gear, txts& args){ gear.set_handled(); if (args.size()) data_out(args.front()); });
- chords.proc("TerminalOutput", [&](hids& gear, txts& args){ gear.set_handled(); if (args.size()) data_in(args.front()); });
- chords.proc("TerminalAlignMode", [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) exec_cmd(commands::ui::togglejet); else set_align((si32)netxs::get_or(xml::options::align, args.front(), bias::none)); });
- chords.proc("TerminalWrapMode", [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) exec_cmd(commands::ui::togglewrp); else set_wrapln(1 + (si32)!xml::take_or(args.front(), true)); });
- chords.proc("ExclusiveKeyboardMode", [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) exec_cmd(commands::ui::toggleraw); else set_rawkbd(1 + (si32)!xml::take_or(args.front(), true)); });
+ chords.proc(action::TerminalScrollViewportByPage, [&](hids& gear, txts& args){ if (target != &normal) return; gear.set_handled(); base::riseup(tier::preview, e2::form::upon::scroll::bypage::v, { .vector = args.size() ? xml::take_or(args.front(), dot_00) : dot_00 }); });
+ chords.proc(action::TerminalScrollViewportByCell, [&](hids& gear, txts& args){ if (target != &normal) return; gear.set_handled(); base::riseup(tier::preview, e2::form::upon::scroll::bystep::v, { .vector = args.size() ? xml::take_or(args.front(), dot_00) : dot_00 }); });
+ chords.proc(action::TerminalScrollViewportToTop, [&](hids& gear, txts&){ if (target != &normal) return; gear.set_handled(); base::riseup(tier::preview, e2::form::upon::scroll::to_top::y); });
+ chords.proc(action::TerminalScrollViewportToEnd, [&](hids& gear, txts&){ if (target != &normal) return; gear.set_handled(); base::riseup(tier::preview, e2::form::upon::scroll::to_end::y); });
+ chords.proc(action::TerminalFindPrev, [&](hids& gear, txts&){ gear.set_handled(); selection_search(gear, feed::rev); });
+ chords.proc(action::TerminalFindNext, [&](hids& gear, txts&){ gear.set_handled(); selection_search(gear, feed::fwd); });
+ chords.proc(action::TerminalCwdSync, [&](hids& gear, txts&){ gear.set_handled(); base::riseup(tier::preview, ui::term::events::toggle::cwdsync, true); });
+ chords.proc(action::TerminalQuit, [&](hids& gear, txts&){ gear.set_handled(); exec_cmd(commands::ui::sighup); });
+ chords.proc(action::TerminalRestart, [&](hids& gear, txts&){ gear.set_handled(); exec_cmd(commands::ui::restart); });
+ chords.proc(action::TerminalFullscreen, [&](hids& gear, txts&){ gear.set_handled(); bell::enqueue(This(), [&, gear_id = gear.id](auto& /*boss*/){ if (auto gear_ptr = bell::getref(gear_id)) base::riseup(tier::preview, e2::form::size::enlarge::fullscreen, *gear_ptr); }); }); // Refocus-related operations require execution outside of keyboard events.
+ chords.proc(action::TerminalMaximize, [&](hids& gear, txts&){ gear.set_handled(); bell::enqueue(This(), [&, gear_id = gear.id](auto& /*boss*/){ if (auto gear_ptr = bell::getref(gear_id)) base::riseup(tier::preview, e2::form::size::enlarge::maximize, *gear_ptr); }); });
+ chords.proc(action::TerminalMinimize, [&](hids& gear, txts&){ gear.set_handled(); bell::enqueue(This(), [&, gear_id = gear.id](auto& /*boss*/){ if (auto gear_ptr = bell::getref(gear_id)) base::riseup(tier::release, e2::form::size::minimize, *gear_ptr); }); });
+ chords.proc(action::TerminalUndo, [&](hids& gear, txts&){ gear.set_handled(); exec_cmd(commands::ui::undo); });
+ chords.proc(action::TerminalRedo, [&](hids& gear, txts&){ gear.set_handled(); exec_cmd(commands::ui::redo); });
+ chords.proc(action::TerminalClipboardCopy, [&](hids& gear, txts&){ gear.set_handled(); copy(gear); });
+ chords.proc(action::TerminalClipboardPaste, [&](hids& gear, txts&){ gear.set_handled(); paste(gear); });
+ chords.proc(action::TerminalClipboardWipe, [&](hids& gear, txts&){ gear.set_handled(); gear.clear_clipboard(); });
+ chords.proc(action::TerminalClipboardFormat, [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) exec_cmd(commands::ui::togglesel); else set_selmod((si32)netxs::get_or(xml::options::format, args.front(), mime::textonly)); });
+ chords.proc(action::TerminalViewportCopy, [&](hids& gear, txts&){ gear.set_handled(); prnscrn(gear); });
+ chords.proc(action::TerminalSelectionCancel, [&](hids& gear, txts&){ if (!selection_active()) return; gear.set_handled(); exec_cmd(commands::ui::deselect); });
+ chords.proc(action::TerminalSelectionRect, [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) exec_cmd(commands::ui::toggleselalt); else set_selalt(xml::take_or(args.front(), faux)); });
+ chords.proc(action::TerminalSelectionOneShot, [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) set_oneshot(mime::textonly); else set_oneshot(netxs::get_or(xml::options::format, args.front(), mime::textonly)); });
+ chords.proc(action::TerminalStdioLog, [&](hids& gear, txts& args){ gear.set_handled(); set_log(args.size() ? xml::take_or(args.front(), !io_log) : !io_log); ondata(); });
+ chords.proc(action::TerminalSendKey, [&](hids& gear, txts& args){ gear.set_handled(); if (args.size()) data_out(args.front()); });
+ chords.proc(action::TerminalOutput, [&](hids& gear, txts& args){ gear.set_handled(); if (args.size()) data_in(args.front()); });
+ chords.proc(action::TerminalAlignMode, [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) exec_cmd(commands::ui::togglejet); else set_align((si32)netxs::get_or(xml::options::align, args.front(), bias::none)); });
+ chords.proc(action::TerminalWrapMode, [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) exec_cmd(commands::ui::togglewrp); else set_wrapln(1 + (si32)!xml::take_or(args.front(), true)); });
+ chords.proc(action::ExclusiveKeyboardMode, [&](hids& gear, txts& args){ gear.set_handled(); if (args.empty()) exec_cmd(commands::ui::toggleraw); else set_rawkbd(1 + (si32)!xml::take_or(args.front(), true)); });
auto bindings = chords.load(xml_config, "terminal");
chords.bind(bindings);
diff --git a/src/vtm.xml b/src/vtm.xml
index 6ee4b5d17f..1ccb289de2 100644
--- a/src/vtm.xml
+++ b/src/vtm.xml
@@ -448,27 +448,27 @@ R"==(
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
)=="
\ No newline at end of file