mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 14:12:44 +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 <QShortcut> | ||||
| #include <QTabBar> | ||||
| #include <QWindow> | ||||
| 
 | ||||
| namespace Ladybird { | ||||
| 
 | ||||
|  | @ -55,6 +56,22 @@ BrowserWindow::BrowserWindow(Vector<URL> 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); | ||||
|  |  | |||
|  | @ -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 }; | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ | |||
| #include <QCloseEvent> | ||||
| #include <QMenu> | ||||
| #include <QVBoxLayout> | ||||
| #include <QWindow> | ||||
| 
 | ||||
| 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(); | ||||
|  |  | |||
|  | @ -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<WebView::InspectorClient> m_inspector_client; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Bastiaan van der Plaat
						Bastiaan van der Plaat