mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:02:45 +00:00 
			
		
		
		
	Ladybird/Qt: Listen to DPI changes and update WebContentView accordingly
This commit is contained in:
		
							parent
							
								
									51ecfdf71f
								
							
						
					
					
						commit
						04b591b2e0
					
				
					 6 changed files with 81 additions and 15 deletions
				
			
		|  | @ -27,6 +27,7 @@ | ||||||
| #include <QPlainTextEdit> | #include <QPlainTextEdit> | ||||||
| #include <QShortcut> | #include <QShortcut> | ||||||
| #include <QTabBar> | #include <QTabBar> | ||||||
|  | #include <QWindow> | ||||||
| 
 | 
 | ||||||
| namespace Ladybird { | namespace Ladybird { | ||||||
| 
 | 
 | ||||||
|  | @ -55,6 +56,22 @@ BrowserWindow::BrowserWindow(Vector<URL> const& initial_urls, WebView::CookieJar | ||||||
|     m_tabs_container->setDocumentMode(true); |     m_tabs_container->setDocumentMode(true); | ||||||
|     m_tabs_container->setTabBarAutoHide(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* menu = menuBar()->addMenu("&File"); | ||||||
| 
 | 
 | ||||||
|     auto* new_tab_action = new QAction("New &Tab", this); |     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); |     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) | void BrowserWindow::tab_title_changed(int index, QString const& title) | ||||||
| { | { | ||||||
|     m_tabs_container->setTabText(index, title); |     m_tabs_container->setTabText(index, title); | ||||||
|  |  | ||||||
|  | @ -70,6 +70,7 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| public slots: | public slots: | ||||||
|  |     void device_pixel_ratio_changed(qreal dpi); | ||||||
|     void tab_title_changed(int index, QString const&); |     void tab_title_changed(int index, QString const&); | ||||||
|     void tab_favicon_changed(int index, QIcon const& icon); |     void tab_favicon_changed(int index, QIcon const& icon); | ||||||
|     Tab& new_tab(QString const&, Web::HTML::ActivateTab); |     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 }; |     QTabWidget* m_tabs_container { nullptr }; | ||||||
|     Tab* m_current_tab { nullptr }; |     Tab* m_current_tab { nullptr }; | ||||||
|     QMenu* m_zoom_menu { nullptr }; |     QMenu* m_zoom_menu { nullptr }; | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
| #include <QCloseEvent> | #include <QCloseEvent> | ||||||
| #include <QMenu> | #include <QMenu> | ||||||
| #include <QVBoxLayout> | #include <QVBoxLayout> | ||||||
|  | #include <QWindow> | ||||||
| 
 | 
 | ||||||
| namespace Ladybird { | namespace Ladybird { | ||||||
| 
 | 
 | ||||||
|  | @ -123,6 +124,22 @@ InspectorWidget::InspectorWidget(QWidget* tab, WebContentView& content_view) | ||||||
| 
 | 
 | ||||||
|     setWindowTitle("Inspector"); |     setWindowTitle("Inspector"); | ||||||
|     resize(875, 825); |     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; | InspectorWidget::~InspectorWidget() = default; | ||||||
|  | @ -147,6 +164,12 @@ void InspectorWidget::select_default_node() | ||||||
|     m_inspector_client->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) | void InspectorWidget::closeEvent(QCloseEvent* event) | ||||||
| { | { | ||||||
|     event->accept(); |     event->accept(); | ||||||
|  |  | ||||||
|  | @ -31,11 +31,17 @@ public: | ||||||
|     void select_hovered_node(); |     void select_hovered_node(); | ||||||
|     void select_default_node(); |     void select_default_node(); | ||||||
| 
 | 
 | ||||||
|  | public slots: | ||||||
|  |     void device_pixel_ratio_changed(qreal dpi); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     void closeEvent(QCloseEvent*) override; |     void closeEvent(QCloseEvent*) override; | ||||||
| 
 | 
 | ||||||
|     QPoint to_widget_position(Gfx::IntPoint) const; |     QPoint to_widget_position(Gfx::IntPoint) const; | ||||||
| 
 | 
 | ||||||
|  |     QScreen* m_current_screen; | ||||||
|  |     double m_device_pixel_ratio { 0 }; | ||||||
|  | 
 | ||||||
|     WebContentView* m_inspector_view; |     WebContentView* m_inspector_view; | ||||||
|     OwnPtr<WebView::InspectorClient> m_inspector_client; |     OwnPtr<WebView::InspectorClient> m_inspector_client; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -63,7 +63,6 @@ WebContentView::WebContentView(WebContentOptions const& web_content_options, Str | ||||||
|     setFocusPolicy(Qt::FocusPolicy::StrongFocus); |     setFocusPolicy(Qt::FocusPolicy::StrongFocus); | ||||||
| 
 | 
 | ||||||
|     m_device_pixel_ratio = devicePixelRatio(); |     m_device_pixel_ratio = devicePixelRatio(); | ||||||
|     m_inverse_pixel_scaling_ratio = 1.0 / m_device_pixel_ratio; |  | ||||||
| 
 | 
 | ||||||
|     verticalScrollBar()->setSingleStep(24); |     verticalScrollBar()->setSingleStep(24); | ||||||
|     horizontalScrollBar()->setSingleStep(24); |     horizontalScrollBar()->setSingleStep(24); | ||||||
|  | @ -325,8 +324,8 @@ KeyCode get_keycode_from_qt_keyboard_event(QKeyEvent const& event) | ||||||
| void WebContentView::wheelEvent(QWheelEvent* event) | void WebContentView::wheelEvent(QWheelEvent* event) | ||||||
| { | { | ||||||
|     if (!event->modifiers().testFlag(Qt::ControlModifier)) { |     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 position(event->position().x() * m_device_pixel_ratio, event->position().y() * m_device_pixel_ratio); | ||||||
|         Gfx::IntPoint screen_position(event->globalPosition().x() / m_inverse_pixel_scaling_ratio, event->globalPosition().y() / m_inverse_pixel_scaling_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 button = get_button_from_qt_event(*event); | ||||||
|         auto buttons = get_buttons_from_qt_event(*event); |         auto buttons = get_buttons_from_qt_event(*event); | ||||||
|         auto modifiers = get_modifiers_from_qt_mouse_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) | 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 position(event->position().x() * m_device_pixel_ratio, event->position().y() * m_device_pixel_ratio); | ||||||
|     Gfx::IntPoint screen_position(event->globalPosition().x() / m_inverse_pixel_scaling_ratio, event->globalPosition().y() / m_inverse_pixel_scaling_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 buttons = get_buttons_from_qt_event(*event); | ||||||
|     auto modifiers = get_modifiers_from_qt_mouse_event(*event); |     auto modifiers = get_modifiers_from_qt_mouse_event(*event); | ||||||
|     client().async_mouse_move(to_content_position(position), screen_position, 0, buttons, modifiers); |     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) | 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 position(event->position().x() * m_device_pixel_ratio, event->position().y() * m_device_pixel_ratio); | ||||||
|     Gfx::IntPoint screen_position(event->globalPosition().x() / m_inverse_pixel_scaling_ratio, event->globalPosition().y() / m_inverse_pixel_scaling_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 button = get_button_from_qt_event(*event); | ||||||
|     if (button == 0) { |     if (button == 0) { | ||||||
|         // We could not convert Qt buttons to something that Lagom can
 |         // 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) | 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 position(event->position().x() * m_device_pixel_ratio, event->position().y() * m_device_pixel_ratio); | ||||||
|     Gfx::IntPoint screen_position(event->globalPosition().x() / m_inverse_pixel_scaling_ratio, event->globalPosition().y() / m_inverse_pixel_scaling_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 button = get_button_from_qt_event(*event); | ||||||
| 
 | 
 | ||||||
|     if (event->button() & Qt::MouseButton::BackButton) { |     if (event->button() & Qt::MouseButton::BackButton) { | ||||||
|  | @ -401,8 +400,8 @@ void WebContentView::mouseReleaseEvent(QMouseEvent* event) | ||||||
| 
 | 
 | ||||||
| void WebContentView::mouseDoubleClickEvent(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 position(event->position().x() * m_device_pixel_ratio, event->position().y() * m_device_pixel_ratio); | ||||||
|     Gfx::IntPoint screen_position(event->globalPosition().x() / m_inverse_pixel_scaling_ratio, event->globalPosition().y() / m_inverse_pixel_scaling_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 button = get_button_from_qt_event(*event); | ||||||
|     if (button == 0) { |     if (button == 0) { | ||||||
|         // We could not convert Qt buttons to something that Lagom can
 |         // We could not convert Qt buttons to something that Lagom can
 | ||||||
|  | @ -478,7 +477,7 @@ void WebContentView::focusOutEvent(QFocusEvent*) | ||||||
| void WebContentView::paintEvent(QPaintEvent*) | void WebContentView::paintEvent(QPaintEvent*) | ||||||
| { | { | ||||||
|     QPainter painter(viewport()); |     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::Bitmap const* bitmap = nullptr; | ||||||
|     Gfx::IntSize bitmap_size; |     Gfx::IntSize bitmap_size; | ||||||
|  | @ -532,10 +531,19 @@ void WebContentView::set_window_position(Gfx::IntPoint position) | ||||||
|     client().async_set_window_position(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() | void WebContentView::update_viewport_rect() | ||||||
| { | { | ||||||
|     auto scaled_width = int(viewport()->width() / m_inverse_pixel_scaling_ratio); |     auto scaled_width = int(viewport()->width() * m_device_pixel_ratio); | ||||||
|     auto scaled_height = int(viewport()->height() / m_inverse_pixel_scaling_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); |     Gfx::IntRect rect(max(0, horizontalScrollBar()->value()), max(0, verticalScrollBar()->value()), scaled_width, scaled_height); | ||||||
| 
 | 
 | ||||||
|     set_viewport_rect(rect); |     set_viewport_rect(rect); | ||||||
|  |  | ||||||
|  | @ -69,6 +69,7 @@ public: | ||||||
|     void set_viewport_rect(Gfx::IntRect); |     void set_viewport_rect(Gfx::IntRect); | ||||||
|     void set_window_size(Gfx::IntSize); |     void set_window_size(Gfx::IntSize); | ||||||
|     void set_window_position(Gfx::IntPoint); |     void set_window_position(Gfx::IntPoint); | ||||||
|  |     void set_device_pixel_ratio(double); | ||||||
| 
 | 
 | ||||||
|     enum class PaletteMode { |     enum class PaletteMode { | ||||||
|         Default, |         Default, | ||||||
|  | @ -90,7 +91,6 @@ private: | ||||||
|     void update_viewport_rect(); |     void update_viewport_rect(); | ||||||
|     void update_cursor(Gfx::StandardCursor cursor); |     void update_cursor(Gfx::StandardCursor cursor); | ||||||
| 
 | 
 | ||||||
|     qreal m_inverse_pixel_scaling_ratio { 1.0 }; |  | ||||||
|     bool m_should_show_line_box_borders { false }; |     bool m_should_show_line_box_borders { false }; | ||||||
| 
 | 
 | ||||||
|     Gfx::IntRect m_viewport_rect; |     Gfx::IntRect m_viewport_rect; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Bastiaan van der Plaat
						Bastiaan van der Plaat