diff --git a/Ladybird/Qt/BrowserWindow.cpp b/Ladybird/Qt/BrowserWindow.cpp index 049f166ab48..a5cfa6bbbb2 100644 --- a/Ladybird/Qt/BrowserWindow.cpp +++ b/Ladybird/Qt/BrowserWindow.cpp @@ -27,6 +27,7 @@ #include #include #include +#include namespace Ladybird { @@ -55,6 +56,22 @@ BrowserWindow::BrowserWindow(Vector const& initial_urls, WebView::CookieJar m_tabs_container->setDocumentMode(true); m_tabs_container->setTabBarAutoHide(true); + // Listen for DPI changes + setAttribute(Qt::WA_NativeWindow); + setAttribute(Qt::WA_DontCreateNativeAncestors); + m_device_pixel_ratio = devicePixelRatio(); + m_current_screen = screen(); + QObject::connect(m_current_screen, &QScreen::logicalDotsPerInchChanged, this, &BrowserWindow::device_pixel_ratio_changed); + QObject::connect(windowHandle(), &QWindow::screenChanged, this, [this](QScreen* screen) { + if (m_device_pixel_ratio != screen->devicePixelRatio()) + device_pixel_ratio_changed(screen->devicePixelRatio()); + + // Listen for logicalDotsPerInchChanged signals on new screen + QObject::disconnect(m_current_screen, &QScreen::logicalDotsPerInchChanged, nullptr, nullptr); + m_current_screen = screen; + QObject::connect(m_current_screen, &QScreen::logicalDotsPerInchChanged, this, &BrowserWindow::device_pixel_ratio_changed); + }); + auto* menu = menuBar()->addMenu("&File"); auto* new_tab_action = new QAction("New &Tab", this); @@ -562,6 +579,14 @@ int BrowserWindow::tab_index(Tab* tab) return m_tabs_container->indexOf(tab); } +void BrowserWindow::device_pixel_ratio_changed(qreal dpi) +{ + m_device_pixel_ratio = dpi; + for_each_tab([this](auto& tab) { + tab.view().set_device_pixel_ratio(m_device_pixel_ratio); + }); +} + void BrowserWindow::tab_title_changed(int index, QString const& title) { m_tabs_container->setTabText(index, title); diff --git a/Ladybird/Qt/BrowserWindow.h b/Ladybird/Qt/BrowserWindow.h index d16fcebb15f..3cf612a7279 100644 --- a/Ladybird/Qt/BrowserWindow.h +++ b/Ladybird/Qt/BrowserWindow.h @@ -70,6 +70,7 @@ public: } public slots: + void device_pixel_ratio_changed(qreal dpi); void tab_title_changed(int index, QString const&); void tab_favicon_changed(int index, QIcon const& icon); Tab& new_tab(QString const&, Web::HTML::ActivateTab); @@ -115,6 +116,9 @@ private: } } + QScreen* m_current_screen; + double m_device_pixel_ratio { 0 }; + QTabWidget* m_tabs_container { nullptr }; Tab* m_current_tab { nullptr }; QMenu* m_zoom_menu { nullptr }; diff --git a/Ladybird/Qt/InspectorWidget.cpp b/Ladybird/Qt/InspectorWidget.cpp index 76a699f0ced..ce8d9df996d 100644 --- a/Ladybird/Qt/InspectorWidget.cpp +++ b/Ladybird/Qt/InspectorWidget.cpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace Ladybird { @@ -123,6 +124,22 @@ InspectorWidget::InspectorWidget(QWidget* tab, WebContentView& content_view) setWindowTitle("Inspector"); resize(875, 825); + + // Listen for DPI changes + setAttribute(Qt::WA_NativeWindow); + setAttribute(Qt::WA_DontCreateNativeAncestors); + m_device_pixel_ratio = devicePixelRatio(); + m_current_screen = screen(); + QObject::connect(m_current_screen, &QScreen::logicalDotsPerInchChanged, this, &InspectorWidget::device_pixel_ratio_changed); + QObject::connect(windowHandle(), &QWindow::screenChanged, this, [this](QScreen* screen) { + if (m_device_pixel_ratio != screen->devicePixelRatio()) + device_pixel_ratio_changed(screen->devicePixelRatio()); + + // Listen for logicalDotsPerInchChanged signals on new screen + QObject::disconnect(m_current_screen, &QScreen::logicalDotsPerInchChanged, nullptr, nullptr); + m_current_screen = screen; + QObject::connect(m_current_screen, &QScreen::logicalDotsPerInchChanged, this, &InspectorWidget::device_pixel_ratio_changed); + }); } InspectorWidget::~InspectorWidget() = default; @@ -147,6 +164,12 @@ void InspectorWidget::select_default_node() m_inspector_client->select_default_node(); } +void InspectorWidget::device_pixel_ratio_changed(qreal dpi) +{ + m_device_pixel_ratio = dpi; + m_inspector_view->set_device_pixel_ratio(m_device_pixel_ratio); +} + void InspectorWidget::closeEvent(QCloseEvent* event) { event->accept(); diff --git a/Ladybird/Qt/InspectorWidget.h b/Ladybird/Qt/InspectorWidget.h index 1e38e361230..b1400d2ea3d 100644 --- a/Ladybird/Qt/InspectorWidget.h +++ b/Ladybird/Qt/InspectorWidget.h @@ -31,11 +31,17 @@ public: void select_hovered_node(); void select_default_node(); +public slots: + void device_pixel_ratio_changed(qreal dpi); + private: void closeEvent(QCloseEvent*) override; QPoint to_widget_position(Gfx::IntPoint) const; + QScreen* m_current_screen; + double m_device_pixel_ratio { 0 }; + WebContentView* m_inspector_view; OwnPtr m_inspector_client; diff --git a/Ladybird/Qt/WebContentView.cpp b/Ladybird/Qt/WebContentView.cpp index a2b35a14434..a1993f6ce2c 100644 --- a/Ladybird/Qt/WebContentView.cpp +++ b/Ladybird/Qt/WebContentView.cpp @@ -63,7 +63,6 @@ WebContentView::WebContentView(WebContentOptions const& web_content_options, Str setFocusPolicy(Qt::FocusPolicy::StrongFocus); m_device_pixel_ratio = devicePixelRatio(); - m_inverse_pixel_scaling_ratio = 1.0 / m_device_pixel_ratio; verticalScrollBar()->setSingleStep(24); horizontalScrollBar()->setSingleStep(24); @@ -325,8 +324,8 @@ KeyCode get_keycode_from_qt_keyboard_event(QKeyEvent const& event) void WebContentView::wheelEvent(QWheelEvent* event) { if (!event->modifiers().testFlag(Qt::ControlModifier)) { - Gfx::IntPoint position(event->position().x() / m_inverse_pixel_scaling_ratio, event->position().y() / m_inverse_pixel_scaling_ratio); - Gfx::IntPoint screen_position(event->globalPosition().x() / m_inverse_pixel_scaling_ratio, event->globalPosition().y() / m_inverse_pixel_scaling_ratio); + Gfx::IntPoint position(event->position().x() * m_device_pixel_ratio, event->position().y() * m_device_pixel_ratio); + Gfx::IntPoint screen_position(event->globalPosition().x() * m_device_pixel_ratio, event->globalPosition().y() * m_device_pixel_ratio); auto button = get_button_from_qt_event(*event); auto buttons = get_buttons_from_qt_event(*event); auto modifiers = get_modifiers_from_qt_mouse_event(*event); @@ -351,8 +350,8 @@ void WebContentView::wheelEvent(QWheelEvent* event) void WebContentView::mouseMoveEvent(QMouseEvent* event) { - Gfx::IntPoint position(event->position().x() / m_inverse_pixel_scaling_ratio, event->position().y() / m_inverse_pixel_scaling_ratio); - Gfx::IntPoint screen_position(event->globalPosition().x() / m_inverse_pixel_scaling_ratio, event->globalPosition().y() / m_inverse_pixel_scaling_ratio); + Gfx::IntPoint position(event->position().x() * m_device_pixel_ratio, event->position().y() * m_device_pixel_ratio); + Gfx::IntPoint screen_position(event->globalPosition().x() * m_device_pixel_ratio, event->globalPosition().y() * m_device_pixel_ratio); auto buttons = get_buttons_from_qt_event(*event); auto modifiers = get_modifiers_from_qt_mouse_event(*event); client().async_mouse_move(to_content_position(position), screen_position, 0, buttons, modifiers); @@ -360,8 +359,8 @@ void WebContentView::mouseMoveEvent(QMouseEvent* event) void WebContentView::mousePressEvent(QMouseEvent* event) { - Gfx::IntPoint position(event->position().x() / m_inverse_pixel_scaling_ratio, event->position().y() / m_inverse_pixel_scaling_ratio); - Gfx::IntPoint screen_position(event->globalPosition().x() / m_inverse_pixel_scaling_ratio, event->globalPosition().y() / m_inverse_pixel_scaling_ratio); + Gfx::IntPoint position(event->position().x() * m_device_pixel_ratio, event->position().y() * m_device_pixel_ratio); + Gfx::IntPoint screen_position(event->globalPosition().x() * m_device_pixel_ratio, event->globalPosition().y() * m_device_pixel_ratio); auto button = get_button_from_qt_event(*event); if (button == 0) { // We could not convert Qt buttons to something that Lagom can @@ -376,8 +375,8 @@ void WebContentView::mousePressEvent(QMouseEvent* event) void WebContentView::mouseReleaseEvent(QMouseEvent* event) { - Gfx::IntPoint position(event->position().x() / m_inverse_pixel_scaling_ratio, event->position().y() / m_inverse_pixel_scaling_ratio); - Gfx::IntPoint screen_position(event->globalPosition().x() / m_inverse_pixel_scaling_ratio, event->globalPosition().y() / m_inverse_pixel_scaling_ratio); + Gfx::IntPoint position(event->position().x() * m_device_pixel_ratio, event->position().y() * m_device_pixel_ratio); + Gfx::IntPoint screen_position(event->globalPosition().x() * m_device_pixel_ratio, event->globalPosition().y() * m_device_pixel_ratio); auto button = get_button_from_qt_event(*event); if (event->button() & Qt::MouseButton::BackButton) { @@ -401,8 +400,8 @@ void WebContentView::mouseReleaseEvent(QMouseEvent* event) void WebContentView::mouseDoubleClickEvent(QMouseEvent* event) { - Gfx::IntPoint position(event->position().x() / m_inverse_pixel_scaling_ratio, event->position().y() / m_inverse_pixel_scaling_ratio); - Gfx::IntPoint screen_position(event->globalPosition().x() / m_inverse_pixel_scaling_ratio, event->globalPosition().y() / m_inverse_pixel_scaling_ratio); + Gfx::IntPoint position(event->position().x() * m_device_pixel_ratio, event->position().y() * m_device_pixel_ratio); + Gfx::IntPoint screen_position(event->globalPosition().x() * m_device_pixel_ratio, event->globalPosition().y() * m_device_pixel_ratio); auto button = get_button_from_qt_event(*event); if (button == 0) { // We could not convert Qt buttons to something that Lagom can @@ -478,7 +477,7 @@ void WebContentView::focusOutEvent(QFocusEvent*) void WebContentView::paintEvent(QPaintEvent*) { QPainter painter(viewport()); - painter.scale(m_inverse_pixel_scaling_ratio, m_inverse_pixel_scaling_ratio); + painter.scale(1 / m_device_pixel_ratio, 1 / m_device_pixel_ratio); Gfx::Bitmap const* bitmap = nullptr; Gfx::IntSize bitmap_size; @@ -532,10 +531,19 @@ void WebContentView::set_window_position(Gfx::IntPoint position) client().async_set_window_position(position); } +void WebContentView::set_device_pixel_ratio(double device_pixel_ratio) +{ + m_device_pixel_ratio = device_pixel_ratio; + client().async_set_device_pixels_per_css_pixel(m_device_pixel_ratio * m_zoom_level); + update_viewport_rect(); + handle_resize(); + request_repaint(); +} + void WebContentView::update_viewport_rect() { - auto scaled_width = int(viewport()->width() / m_inverse_pixel_scaling_ratio); - auto scaled_height = int(viewport()->height() / m_inverse_pixel_scaling_ratio); + auto scaled_width = int(viewport()->width() * m_device_pixel_ratio); + auto scaled_height = int(viewport()->height() * m_device_pixel_ratio); Gfx::IntRect rect(max(0, horizontalScrollBar()->value()), max(0, verticalScrollBar()->value()), scaled_width, scaled_height); set_viewport_rect(rect); diff --git a/Ladybird/Qt/WebContentView.h b/Ladybird/Qt/WebContentView.h index 7d124d03313..5f088dab230 100644 --- a/Ladybird/Qt/WebContentView.h +++ b/Ladybird/Qt/WebContentView.h @@ -69,6 +69,7 @@ public: void set_viewport_rect(Gfx::IntRect); void set_window_size(Gfx::IntSize); void set_window_position(Gfx::IntPoint); + void set_device_pixel_ratio(double); enum class PaletteMode { Default, @@ -90,7 +91,6 @@ private: void update_viewport_rect(); void update_cursor(Gfx::StandardCursor cursor); - qreal m_inverse_pixel_scaling_ratio { 1.0 }; bool m_should_show_line_box_borders { false }; Gfx::IntRect m_viewport_rect;