Project

General

Profile

Bug #14758 » main.cpp

Michael Seibt, 08/18/2026 04:47 PM

 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <Wt/WAbstractTableModel.h>
#pragma GCC diagnostic pop
#include <Wt/WApplication.h>
#include <Wt/WBootstrap5Theme.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WGridLayout.h>
#include <Wt/WHBoxLayout.h>
#include <Wt/WLineEdit.h>
#include <Wt/WMenuItem.h>
#include <Wt/WPanel.h>
#include <Wt/WPopupMenu.h>
#include <Wt/WPushButton.h>
#include <Wt/WServer.h>
#include <Wt/WTableView.h>
#include <Wt/WTabWidget.h>
#include <Wt/WText.h>
#include <Wt/WVBoxLayout.h>

using namespace std;
using namespace Wt;

#define SET_BS5THEME 1

// Always apply theme before creating widgets!
class CThemedApplication : public WApplication
{
public:
CThemedApplication(const WEnvironment& rcEnv)
: WApplication{rcEnv}
{
#if SET_BS5THEME
setTheme(make_shared<WBootstrap5Theme>());
#endif
}
};

#include <boost/core/typeinfo.hpp>
template <typename T> inline string demangled_type_name(T& rT) { return boost::core::demangled_name(typeid(rT)); }

template <>
class std::formatter<WFlags<KeyboardModifier>> : public formatter<string>
{
public: auto format(const WFlags<KeyboardModifier>& rcModifiers, format_context& rCtx) const
{
return formatter<string>::format(std::format("0x{:02x}", rcModifiers.value()), rCtx);
}
};

template <>
class std::formatter<WKeyEvent> : public formatter<string>
{
public: auto format(const WKeyEvent& rcKeyEvent, format_context& rCtx) const
{
const WWidget* pcwFocused{WApplication::instance()->focusedWidget()};
const string csFocused{pcwFocused == nullptr ? "none" : std::format("{} {} {}", demangled_type_name(*pcwFocused), pcwFocused->id(), static_cast<const void*>(pcwFocused))};
return formatter<string>::format(std::format("{{ key: '{}' '{}' {} 0x{:02x}, modifiers: {}, charCode: '{}' {} 0x{:02x}, focused: {} }}"
, rcKeyEvent.keyValue() , static_cast<char>(rcKeyEvent.key()), static_cast<int>(rcKeyEvent.key()), static_cast<int>(rcKeyEvent.key())
, rcKeyEvent.modifiers()
, static_cast<char>(rcKeyEvent.charCode()), rcKeyEvent.charCode(), rcKeyEvent.charCode()
, csFocused
)
, rCtx
);
}
};

class CApplication final : public CThemedApplication
{
public:
CApplication(const WEnvironment& rcEnv);

private:
WServer& _Server; //!< The associated WServer instance, needed for async operations.

WContainerWidget& _cntRoot{*root()};
WBoxLayout& _lytRoot{*_cntRoot.setLayout(make_unique<WVBoxLayout>())};
};

CApplication::CApplication(const WEnvironment& rcEnv)
: CThemedApplication{rcEnv}
, _Server{*environment().server()}
{
setTitle("bug repro " WT_VERSION_STR);

unique_ptr<WPopupMenu> submenu{make_unique<WPopupMenu>()};
submenu->addItem("subitem with longer label 1111111111111111111 1111111111111111111 1111111111111111111111111 1111111111111111111111")
->keyWentDown().connect([this](const WKeyEvent& e)
{
log("trace") << format("subitem keyWentDown({})", e);
});
unique_ptr<WPopupMenu> dropdown{make_unique<WPopupMenu>()};
WMenuItem& submenuitem{*dropdown->addItem("submenu")};
submenuitem.setMenu(move(submenu));
submenuitem.keyWentDown().connect([this](const WKeyEvent& e)
{
log("trace") << format("submenu keyWentDown({})", e);
});
dropdown->addItem("item");
unique_ptr<WMenu> mainmenu{make_unique<WMenu>()};
mainmenu->addMenu("item", move(dropdown))
->keyWentDown().connect([this](const WKeyEvent& e)
{
log("trace") << format("main item keyWentDown({})", e);
});
_lytRoot.addWidget(move(mainmenu));
_lytRoot.addWidget(make_unique<WLineEdit>());

_cntRoot.keyWentDown().connect([this](const WKeyEvent& e)
{
log("trace") << format("root keyWentDown({})", e);
});

globalKeyWentDown().connect([this](const WKeyEvent& e)
{
log("trace") << format("globalKeyWentDown({})", e);
});

// final action after creating the UI
enableUpdates();
}

int main(int argc, char* argv[])
{
return WRun(argc, argv, [](const WEnvironment& rcEnv)
{
try
{
return make_unique<CApplication>(rcEnv);
}
catch (const std::exception& rcException)
{
cerr << "exception " << typeid(remove_cvref<decltype(rcException)>::type).name() << ": " << rcException.what() << endl;

#if DEBUG
exit(-1);
#endif
throw;
}
});
}
(1-1/2)