UI/Qt: Assign dropdown handler for select in WebContentView, not Tab

This makes `<select>` elements also work outside of Tab content, for
example in the Inspector.

Co-authored-by: Tim Flynn <trflynn89@serenityos.org>
This commit is contained in:
Sam Atkins 2024-08-21 11:10:41 +01:00 committed by Sam Atkins
parent ced7b6de5e
commit 421fb6309f
Notes: github-actions[bot] 2024-09-03 09:14:01 +00:00
4 changed files with 53 additions and 48 deletions

View file

@ -319,47 +319,6 @@ Tab::Tab(BrowserWindow* window, RefPtr<WebView::WebContentClient> parent_client,
m_find_in_page->update_result_label(current_match_index, total_match_count);
};
m_select_dropdown = new QMenu("Select Dropdown", this);
QObject::connect(m_select_dropdown, &QMenu::aboutToHide, this, [this]() {
if (!m_select_dropdown->activeAction())
view().select_dropdown_closed({});
});
view().on_request_select_dropdown = [this](Gfx::IntPoint content_position, i32 minimum_width, Vector<Web::HTML::SelectItem> items) {
m_select_dropdown->clear();
m_select_dropdown->setMinimumWidth(minimum_width / view().device_pixel_ratio());
auto add_menu_item = [this](Web::HTML::SelectItemOption const& item_option, bool in_option_group) {
QAction* action = new QAction(qstring_from_ak_string(in_option_group ? MUST(String::formatted(" {}", item_option.label)) : item_option.label), this);
action->setCheckable(true);
action->setChecked(item_option.selected);
action->setDisabled(item_option.disabled);
action->setData(QVariant(static_cast<uint>(item_option.id)));
QObject::connect(action, &QAction::triggered, this, &Tab::select_dropdown_action);
m_select_dropdown->addAction(action);
};
for (auto const& item : items) {
if (item.has<Web::HTML::SelectItemOptionGroup>()) {
auto const& item_option_group = item.get<Web::HTML::SelectItemOptionGroup>();
QAction* subtitle = new QAction(qstring_from_ak_string(item_option_group.label), this);
subtitle->setDisabled(true);
m_select_dropdown->addAction(subtitle);
for (auto const& item_option : item_option_group.items)
add_menu_item(item_option, true);
}
if (item.has<Web::HTML::SelectItemOption>())
add_menu_item(item.get<Web::HTML::SelectItemOption>(), false);
if (item.has<Web::HTML::SelectItemSeparator>())
m_select_dropdown->addSeparator();
}
m_select_dropdown->exec(view().map_point_to_global_position(content_position));
};
QObject::connect(focus_location_editor_action, &QAction::triggered, this, &Tab::focus_location_editor);
view().on_received_source = [this](auto const& url, auto const& source) {
@ -796,12 +755,6 @@ Tab::~Tab()
delete m_inspector_widget;
}
void Tab::select_dropdown_action()
{
QAction* action = qobject_cast<QAction*>(sender());
view().select_dropdown_closed(action->data().value<uint>());
}
void Tab::update_reset_zoom_button()
{
auto zoom_level = view().zoom_level();

View file

@ -84,7 +84,6 @@ public:
public slots:
void focus_location_editor();
void location_edit_return_pressed();
void select_dropdown_action();
signals:
void title_changed(int id, QString const&);

View file

@ -142,10 +142,57 @@ WebContentView::WebContentView(QWidget* window, RefPtr<WebView::WebContentClient
auto worker_client = MUST(launch_web_worker_process(MUST(get_paths_for_helper_process("WebWorker"sv)), request_server_client));
return worker_client->dup_socket();
};
m_select_dropdown = new QMenu("Select Dropdown", this);
QObject::connect(m_select_dropdown, &QMenu::aboutToHide, this, [this]() {
if (!m_select_dropdown->activeAction())
select_dropdown_closed({});
});
on_request_select_dropdown = [this](Gfx::IntPoint content_position, i32 minimum_width, Vector<Web::HTML::SelectItem> items) {
m_select_dropdown->clear();
m_select_dropdown->setMinimumWidth(minimum_width / device_pixel_ratio());
auto add_menu_item = [this](Web::HTML::SelectItemOption const& item_option, bool in_option_group) {
QAction* action = new QAction(qstring_from_ak_string(in_option_group ? MUST(String::formatted(" {}", item_option.label)) : item_option.label), this);
action->setCheckable(true);
action->setChecked(item_option.selected);
action->setDisabled(item_option.disabled);
action->setData(QVariant(static_cast<uint>(item_option.id)));
QObject::connect(action, &QAction::triggered, this, &WebContentView::select_dropdown_action);
m_select_dropdown->addAction(action);
};
for (auto const& item : items) {
if (item.has<Web::HTML::SelectItemOptionGroup>()) {
auto const& item_option_group = item.get<Web::HTML::SelectItemOptionGroup>();
QAction* subtitle = new QAction(qstring_from_ak_string(item_option_group.label), this);
subtitle->setDisabled(true);
m_select_dropdown->addAction(subtitle);
for (auto const& item_option : item_option_group.items)
add_menu_item(item_option, true);
}
if (item.has<Web::HTML::SelectItemOption>())
add_menu_item(item.get<Web::HTML::SelectItemOption>(), false);
if (item.has<Web::HTML::SelectItemSeparator>())
m_select_dropdown->addSeparator();
}
m_select_dropdown->exec(map_point_to_global_position(content_position));
};
}
WebContentView::~WebContentView() = default;
void WebContentView::select_dropdown_action()
{
QAction* action = qobject_cast<QAction*>(sender());
select_dropdown_closed(action->data().value<uint>());
}
static Web::UIEvents::MouseButton get_button_from_qt_mouse_button(Qt::MouseButton button)
{
if (button == Qt::MouseButton::LeftButton)

View file

@ -22,6 +22,7 @@
#include <LibWeb/HTML/ActivateTab.h>
#include <LibWebView/ViewImplementation.h>
#include <QAbstractScrollArea>
#include <QMenu>
#include <QTimer>
#include <QUrl>
@ -88,6 +89,9 @@ public:
QPoint map_point_to_global_position(Gfx::IntPoint) const;
public slots:
void select_dropdown_action();
signals:
void urls_dropped(QList<QUrl> const&);
@ -119,6 +123,8 @@ private:
bool m_should_show_line_box_borders { false };
Gfx::IntSize m_viewport_size;
QMenu* m_select_dropdown { nullptr };
};
}