7

Bug 1767142 - [wayland] Implement fractional-scale-v1 protocol support for fract...

 1 year ago
source link: https://phabricator.services.mozilla.com/D186199
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Bug 1767142 - [wayland] Implement fractional-scale-v1 protocol support for fractional scaling. r=stransky,rmader
ClosedPublic
Authored by emilio on Tue, Aug 15, 2:00 AM.
Referenced Files
Unknown Object (File)
Wed, Aug 16, 6:34 AM
Subscribers

Details
Summary

This is a manually-rebased version of D145169, but with the protocol
header regenerated, various fixes and tweaks.

In particular we only check the pref once when asking for the protocol
now, the rest falls through from current_fractional_scale being 0.0.

I gave it a shot on KWin and stuff seems to work properly, but let's
keep it disabled by default for now and maybe enable on a separate bug.

Depends on D186198

Diff Detail

Event Timeline

phab-bot published this revision for review.Tue, Aug 15, 2:00 AM
phab-bot changed the visibility from "Custom Policy" to "Public (No Login Required)".
phab-bot changed the edit policy from "Custom Policy" to "Restricted Project (Project)".
This revision is now accepted and ready to land.Tue, Aug 15, 7:35 AM
This revision is now accepted and ready to land.Tue, Aug 15, 9:04 AM

Diff 754693

modules/libpref/init/StaticPrefList.yaml

  • This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 LinesShow All 15,347 Lines▼ Show 20 Lines
# Whether to use gtk high contrast themes to disable content styling like on
# windows high contrast mode.
- name: widget.content.gtk-high-contrast.enabled
type: bool
value: true
mirror: always
#ifdef MOZ_WAYLAND
- # Force fractional scaling using wp_viewporter. Valid values: 0.5 - 8
- - name: widget.wayland.fractional_buffer_scale
- type: float
- value: 0.0f
+ - name: widget.wayland.fractional-scale.enabled
+ type: bool
+ value: false
mirror: once
# Use opaque region for MozContainer wl_surface
- name: widget.wayland.opaque-region.enabled
type: bool
value: true
mirror: once
▲ Show 20 LinesShow All 294 LinesShow Last 20 Lines

widget/gtk/MozContainerWayland.h

- /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* vim:expandtab:shiftwidth=4:tabstop=4:
+ /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+ /* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __MOZ_CONTAINER_WAYLAND_H__
#define __MOZ_CONTAINER_WAYLAND_H__
Show All 24 Lines
struct MozContainerWayland {
struct wl_surface* surface = nullptr;
struct wl_subsurface* subsurface = nullptr;
int subsurface_dx = 0;
int subsurface_dy = 0;
struct wl_egl_window* eglwindow = nullptr;
struct wl_callback* frame_callback_handler = nullptr;
struct wp_viewport* viewport = nullptr;
+ struct wp_fractional_scale_v1* fractional_scale = nullptr;
gboolean opaque_region_needs_updates = false;
int opaque_region_corner_radius = 0;
gboolean opaque_region_used = false;
gboolean ready_to_draw = false;
gboolean commit_to_parent = false;
gboolean before_first_size_alloc = false;
gboolean waiting_to_show = false;
+ // Zero means no fractional scale set.
+ double current_fractional_scale = 0.0;
int buffer_scale = 1;
std::vector<std::function<void(void)>> initial_draw_cbs;
// mozcontainer is used from Compositor and Rendering threads so we need to
// control access to mozcontainer where wayland internals are used directly.
mozilla::Mutex container_lock{"MozContainerWayland::container_lock"};
};
struct _MozContainer;
Show All 37 Lines
MozContainer* container, const std::function<void(void)>& initial_draw_cb);
void moz_container_wayland_clear_initial_draw_callback(MozContainer* container);
wl_surface* moz_gtk_widget_get_wl_surface(GtkWidget* aWidget);
void moz_container_wayland_update_opaque_region(MozContainer* container,
int corner_radius);
gboolean moz_container_wayland_can_draw(MozContainer* container);
double moz_container_wayland_get_scale(MozContainer* container);
+ double moz_container_wayland_get_fractional_scale(MozContainer* container);
void moz_container_wayland_set_commit_to_parent(MozContainer* container);
bool moz_container_wayland_is_commiting_to_parent(MozContainer* container);
bool moz_container_wayland_is_waiting_to_show(MozContainer* container);
void moz_container_wayland_clear_waiting_to_show_flag(MozContainer* container);
#endif /* __MOZ_CONTAINER_WAYLAND_H__ */

widget/gtk/MozContainerWayland.cpp

Show First 20 LinesShow All 350 Lines▼ Show 20 Lines
if (wl_container->commit_to_parent) {
wl_container->surface = nullptr;
}
MozClearPointer(wl_container->eglwindow, wl_egl_window_destroy);
MozClearPointer(wl_container->subsurface, wl_subsurface_destroy);
MozClearPointer(wl_container->surface, wl_surface_destroy);
MozClearPointer(wl_container->viewport, wp_viewport_destroy);
+ MozClearPointer(wl_container->fractional_scale,
+ wp_fractional_scale_v1_destroy);
wl_container->ready_to_draw = false;
wl_container->buffer_scale = 1;
+ wl_container->current_fractional_scale = 0.0;
}
static gboolean moz_container_wayland_map_event(GtkWidget* widget,
GdkEventAny* event) {
MozContainerWayland* wl_container = &MOZ_CONTAINER(widget)->data.wl_container;
LOGCONTAINER("%s [%p]\n", __FUNCTION__,
(void*)moz_container_get_nsWindow(MOZ_CONTAINER(widget)));
▲ Show 20 LinesShow All 161 Lines▼ Show 20 Lines
// crash with the following message:
// Buffer size (AxB) must be an integer multiple of the buffer_scale (2)
// Removing the possibly wrong wl_buffer to prevent that crash:
wl_surface_attach(wl_container->surface, nullptr, 0, 0);
wl_surface_set_buffer_scale(wl_container->surface, scale);
wl_container->buffer_scale = scale;
}
+ static void fractional_scale_handle_preferred_scale(
+ void* data, struct wp_fractional_scale_v1* info, uint32_t wire_scale) {
+ MozContainer* container = MOZ_CONTAINER(data);
+ MozContainerWayland* wl_container = &container->data.wl_container;
+ wl_container->current_fractional_scale = wire_scale / 120.0;
+
+ RefPtr<nsWindow> window = moz_container_get_nsWindow(container);
+ LOGWAYLAND("%s [%p] scale: %f\n", __func__, window.get(),
+ wl_container->current_fractional_scale);
+ MOZ_DIAGNOSTIC_ASSERT(window);
+ window->OnScaleChanged(/* aForce = */ true);
+ }
+
+ static const struct wp_fractional_scale_v1_listener fractional_scale_listener =
+ {
+ .preferred_scale = fractional_scale_handle_preferred_scale,
+ };
+
void moz_container_wayland_set_scale_factor_locked(
const MutexAutoLock& aProofOfLock, MozContainer* container) {
if (gfx::gfxVars::UseWebRenderCompositor()) {
// the compositor backend handles scaling itself
return;
}
MozContainerWayland* wl_container = &container->data.wl_container;
wl_container->container_lock.AssertCurrentThreadOwns();
- nsWindow* window = moz_container_get_nsWindow(container);
- MOZ_DIAGNOSTIC_ASSERT(window);
- if (window->UseFractionalScale()) {
- if (!wl_container->viewport) {
- wl_container->viewport = wp_viewporter_get_viewport(
- WaylandDisplayGet()->GetViewporter(), wl_container->surface);
- }
+ if (StaticPrefs::widget_wayland_fractional_scale_enabled_AtStartup()) {
+ if (!wl_container->fractional_scale) {
+ if (auto* manager = WaylandDisplayGet()->GetFractionalScaleManager()) {
+ wl_container->fractional_scale =
+ wp_fractional_scale_manager_v1_get_fractional_scale(
+ manager, wl_container->surface);
+ wp_fractional_scale_v1_add_listener(wl_container->fractional_scale,
+ &fractional_scale_listener,
+ container);
+ }
+ }
- GdkWindow* gdkWindow = gtk_widget_get_window(GTK_WIDGET(container));
- wp_viewport_set_destination(wl_container->viewport,
- gdk_window_get_width(gdkWindow),
- gdk_window_get_height(gdkWindow));
- } else {
- moz_container_wayland_surface_set_scale_locked(
- aProofOfLock, wl_container, window->GdkCeiledScaleFactor());
- }
- }
+ if (wl_container->fractional_scale) {
+ if (!wl_container->viewport) {
+ if (auto* viewporter = WaylandDisplayGet()->GetViewporter()) {
+ wl_container->viewport =
+ wp_viewporter_get_viewport(viewporter, wl_container->surface);
+ }
+ }
+ if (wl_container->viewport) {
+ GdkWindow* gdkWindow = gtk_widget_get_window(GTK_WIDGET(container));
+ wp_viewport_set_destination(wl_container->viewport,
+ gdk_window_get_width(gdkWindow),
+ gdk_window_get_height(gdkWindow));
+ return;
+ }
+ }
+ }
+
+ nsWindow* window = moz_container_get_nsWindow(container);
+ MOZ_DIAGNOSTIC_ASSERT(window);
+ moz_container_wayland_surface_set_scale_locked(
+ aProofOfLock, wl_container, window->GdkCeiledScaleFactor());
+ }
void moz_container_wayland_set_scale_factor(MozContainer* container) {
MutexAutoLock lock(container->data.wl_container.container_lock);
if (container->data.wl_container.surface) {
moz_container_wayland_set_scale_factor_locked(lock, container);
}
}
▲ Show 20 LinesShow All 187 Lines▼ Show 20 Lines
}
gboolean moz_container_wayland_can_draw(MozContainer* container) {
MozContainerWayland* wl_container = &container->data.wl_container;
MutexAutoLock lock(wl_container->container_lock);
return wl_container->ready_to_draw;
}
+ double moz_container_wayland_get_fractional_scale(MozContainer* container) {
+ return container->data.wl_container.current_fractional_scale;
+ }
+
double moz_container_wayland_get_scale(MozContainer* container) {
+ double scale = moz_container_wayland_get_fractional_scale(container);
+ if (scale != 0.0) {
+ return scale;
+ }
nsWindow* window = moz_container_get_nsWindow(container);
return window ? window->FractionalScaleFactor() : 1;
}
void moz_container_wayland_set_commit_to_parent(MozContainer* container) {
MozContainerWayland* wl_container = &container->data.wl_container;
MOZ_DIAGNOSTIC_ASSERT(!wl_container->surface);
wl_container->commit_to_parent = true;
Show All 15 Lines

widget/gtk/mozwayland/mozwayland.c

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdlib.h>
#include "mozilla/Types.h"
#include <gtk/gtk.h>
#include <gtk/gtkx.h>
#include <gdk/gdkwayland.h>
union wl_argument;
- /* Those strucures are just placeholders and will be replaced by
+ /* Those structures are just placeholders and will be replaced by
* real symbols from libwayland during run-time linking. We need to make
* them explicitly visible.
*/
#pragma GCC visibility push(default)
const struct wl_interface wl_buffer_interface;
const struct wl_interface wl_callback_interface;
const struct wl_interface wl_data_device_interface;
const struct wl_interface wl_data_device_manager_interface;
▲ Show 20 LinesShow All 188 LinesShow Last 20 Lines

widget/gtk/nsWaylandDisplay.h

/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __MOZ_WAYLAND_DISPLAY_H__
#define __MOZ_WAYLAND_DISPLAY_H__
#include "DMABufLibWrapper.h"
#include "mozilla/widget/mozwayland.h"
#include "mozilla/widget/gbm.h"
+ #include "mozilla/widget/fractional-scale-v1-client-protocol.h"
#include "mozilla/widget/idle-inhibit-unstable-v1-client-protocol.h"
#include "mozilla/widget/relative-pointer-unstable-v1-client-protocol.h"
#include "mozilla/widget/pointer-constraints-unstable-v1-client-protocol.h"
#include "mozilla/widget/linux-dmabuf-unstable-v1-client-protocol.h"
#include "mozilla/widget/viewporter-client-protocol.h"
#include "mozilla/widget/xdg-activation-v1-client-protocol.h"
#include "mozilla/widget/xdg-output-unstable-v1-client-protocol.h"
- namespace mozilla {
- namespace widget {
+ namespace mozilla::widget {
// Our general connection to Wayland display server,
// holds our display connection and runs event loop.
// We have a global nsWaylandDisplay object for each thread.
class nsWaylandDisplay {
public:
// Create nsWaylandDisplay object on top of native Wayland wl_display
// connection.
Show All 10 Lines
zwp_relative_pointer_manager_v1* GetRelativePointerManager() {
return mRelativePointerManager;
}
zwp_pointer_constraints_v1* GetPointerConstraints() {
return mPointerConstraints;
}
zwp_linux_dmabuf_v1* GetDmabuf() { return mDmabuf; };
xdg_activation_v1* GetXdgActivation() { return mXdgActivation; };
-
+ wp_fractional_scale_manager_v1* GetFractionalScaleManager() {
+ return mFractionalScaleManager;
+ }
void SetShm(wl_shm* aShm);
void SetCompositor(wl_compositor* aCompositor);
void SetSubcompositor(wl_subcompositor* aSubcompositor);
void SetDataDeviceManager(wl_data_device_manager* aDataDeviceManager);
void SetIdleInhibitManager(zwp_idle_inhibit_manager_v1* aIdleInhibitManager);
void SetViewporter(wp_viewporter* aViewporter);
void SetRelativePointerManager(
zwp_relative_pointer_manager_v1* aRelativePointerManager);
void SetPointerConstraints(zwp_pointer_constraints_v1* aPointerConstraints);
void SetDmabuf(zwp_linux_dmabuf_v1* aDmabuf);
void SetXdgActivation(xdg_activation_v1* aXdgActivation);
+ void SetFractionalScaleManager(wp_fractional_scale_manager_v1* aManager) {
+ mFractionalScaleManager = aManager;
+ }
~nsWaylandDisplay();
private:
PRThread* mThreadId = nullptr;
wl_registry* mRegistry = nullptr;
wl_display* mDisplay = nullptr;
wl_compositor* mCompositor = nullptr;
wl_subcompositor* mSubcompositor = nullptr;
wl_shm* mShm = nullptr;
zwp_idle_inhibit_manager_v1* mIdleInhibitManager = nullptr;
zwp_relative_pointer_manager_v1* mRelativePointerManager = nullptr;
zwp_pointer_constraints_v1* mPointerConstraints = nullptr;
wp_viewporter* mViewporter = nullptr;
zwp_linux_dmabuf_v1* mDmabuf = nullptr;
xdg_activation_v1* mXdgActivation = nullptr;
+ wp_fractional_scale_manager_v1* mFractionalScaleManager = nullptr;
bool mExplicitSync = false;
};
wl_display* WaylandDisplayGetWLDisplay();
nsWaylandDisplay* WaylandDisplayGet();
void WaylandDisplayRelease();
- } // namespace widget
- } // namespace mozilla
+ } // namespace mozilla::widget
template <class T>
static inline T* WaylandRegistryBind(struct wl_registry* wl_registry,
uint32_t name,
const struct wl_interface* interface,
uint32_t version) {
struct wl_proxy* id;
Show All 16 Lines

widget/gtk/nsWaylandDisplay.cpp

Show First 20 LinesShow All 95 Lines▼ Show 20 Lines
static void global_registry_handler(void* data, wl_registry* registry,
uint32_t id, const char* interface,
uint32_t version) {
auto* display = static_cast<nsWaylandDisplay*>(data);
if (!display) {
return;
}
- if (strcmp(interface, "wl_shm") == 0) {
+ nsDependentCString iface(interface);
+ if (iface.EqualsLiteral("wl_shm")) {
auto* shm = WaylandRegistryBind<wl_shm>(registry, id, &wl_shm_interface, 1);
display->SetShm(shm);
- } else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) {
+ } else if (iface.EqualsLiteral("zwp_idle_inhibit_manager_v1")) {
auto* idle_inhibit_manager =
WaylandRegistryBind<zwp_idle_inhibit_manager_v1>(
registry, id, &zwp_idle_inhibit_manager_v1_interface, 1);
display->SetIdleInhibitManager(idle_inhibit_manager);
- } else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
+ } else if (iface.EqualsLiteral("zwp_relative_pointer_manager_v1")) {
auto* relative_pointer_manager =
WaylandRegistryBind<zwp_relative_pointer_manager_v1>(
registry, id, &zwp_relative_pointer_manager_v1_interface, 1);
display->SetRelativePointerManager(relative_pointer_manager);
- } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
+ } else if (iface.EqualsLiteral("zwp_pointer_constraints_v1")) {
auto* pointer_constraints = WaylandRegistryBind<zwp_pointer_constraints_v1>(
registry, id, &zwp_pointer_constraints_v1_interface, 1);
display->SetPointerConstraints(pointer_constraints);
- } else if (strcmp(interface, "wl_compositor") == 0) {
+ } else if (iface.EqualsLiteral("wl_compositor")) {
// Requested wl_compositor version 4 as we need wl_surface_damage_buffer().
auto* compositor = WaylandRegistryBind<wl_compositor>(
registry, id, &wl_compositor_interface, 4);
display->SetCompositor(compositor);
- } else if (strcmp(interface, "wl_subcompositor") == 0) {
+ } else if (iface.EqualsLiteral("wl_subcompositor")) {
auto* subcompositor = WaylandRegistryBind<wl_subcompositor>(
registry, id, &wl_subcompositor_interface, 1);
display->SetSubcompositor(subcompositor);
- } else if (strcmp(interface, "wp_viewporter") == 0) {
+ } else if (iface.EqualsLiteral("wp_viewporter")) {
auto* viewporter = WaylandRegistryBind<wp_viewporter>(
registry, id, &wp_viewporter_interface, 1);
display->SetViewporter(viewporter);
- } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0 && version > 2) {
+ } else if (iface.EqualsLiteral("zwp_linux_dmabuf_v1") && version > 2) {
auto* dmabuf = WaylandRegistryBind<zwp_linux_dmabuf_v1>(
registry, id, &zwp_linux_dmabuf_v1_interface, 3);
display->SetDmabuf(dmabuf);
- } else if (strcmp(interface, "xdg_activation_v1") == 0) {
+ } else if (iface.EqualsLiteral("xdg_activation_v1")) {
auto* activation = WaylandRegistryBind<xdg_activation_v1>(
registry, id, &xdg_activation_v1_interface, 1);
display->SetXdgActivation(activation);
+ } else if (iface.EqualsLiteral("wl_seat")) {
// Install keyboard handlers for main thread only
- } else if (strcmp(interface, "wl_seat") == 0) {
auto* seat =
WaylandRegistryBind<wl_seat>(registry, id, &wl_seat_interface, 1);
KeymapWrapper::SetSeat(seat, id);
+ } else if (iface.EqualsLiteral("wp_fractional_scale_manager_v1")) {
+ auto* manager = WaylandRegistryBind<wp_fractional_scale_manager_v1>(
+ registry, id, &wp_fractional_scale_manager_v1_interface, 1);
+ display->SetFractionalScaleManager(manager);
}
}
static void global_registry_remover(void* data, wl_registry* registry,
uint32_t id) {
KeymapWrapper::ClearSeat(id);
}
▲ Show 20 LinesShow All 42 LinesShow Last 20 Lines

widget/gtk/nsWindow.h

Show First 20 LinesShow All 262 Lines▼ Show 20 Lines
mozilla::gfx::DrawTarget* aDrawTarget,
const LayoutDeviceIntRegion& aInvalidRegion) override;
void SetProgress(unsigned long progressPercent);
RefPtr<mozilla::VsyncDispatcher> GetVsyncDispatcher() override;
bool SynchronouslyRepaintOnResize() override;
- void OnDPIChanged(void);
- void OnCheckResize(void);
- void OnCompositedChanged(void);
- void OnScaleChanged();
+ void OnDPIChanged();
+ void OnCheckResize();
+ void OnCompositedChanged();
+ void OnScaleChanged(bool aForce);
void DispatchResized();
static guint32 sLastButtonPressTime;
MozContainer* GetMozContainer() { return mContainer; }
GdkWindow* GetGdkWindow() const { return mGdkWindow; };
GdkWindow* GetToplevelGdkWindow() const;
GtkWidget* GetGtkWidget() const { return mShell; }
▲ Show 20 LinesShow All 86 Lines▼ Show 20 Lines
void SetDrawsInTitlebar(bool aState) override;
mozilla::LayoutDeviceIntCoord GetTitlebarRadius();
LayoutDeviceIntRect GetTitlebarRect();
void UpdateWindowDraggingRegion(
const LayoutDeviceIntRegion& aRegion) override;
// HiDPI scale conversion
gint GdkCeiledScaleFactor();
- bool UseFractionalScale() const;
double FractionalScaleFactor();
// To GDK
gint DevicePixelsToGdkCoordRoundUp(int);
gint DevicePixelsToGdkCoordRoundDown(int);
GdkPoint DevicePixelsToGdkPointRoundDown(const LayoutDeviceIntPoint&);
GdkRectangle DevicePixelsToGdkSizeRoundUp(const LayoutDeviceIntSize&);
GdkRectangle DevicePixelsToGdkRectRoundOut(const LayoutDeviceIntRect&);
▲ Show 20 LinesShow All 618 LinesShow Last 20 Lines

widget/gtk/nsWindow.cpp

  • This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 LinesShow All 5,290 Lines▼ Show 20 Lines
void nsWindow::OnCompositedChanged() {
// Update CSD after the change in alpha visibility. This only affects
// system metrics, not other theme shenanigans.
NotifyThemeChanged(ThemeChangeKind::MediaQueriesOnly);
mCompositedScreen = gdk_screen_is_composited(gdk_screen_get_default());
}
- void nsWindow::OnScaleChanged() {
+ void nsWindow::OnScaleChanged(bool aForce) {
// Force scale factor recalculation
if (!mGdkWindow) {
mWindowScaleFactorChanged = true;
return;
}
- LOG("OnScaleChanged -> %d\n", gdk_window_get_scale_factor(mGdkWindow));
+ LOG("OnScaleChanged -> %d, frac=%f\n",
+ gdk_window_get_scale_factor(mGdkWindow), FractionalScaleFactor());
// Gtk supply us sometimes with doubled events so stay calm in such case.
- if (gdk_window_get_scale_factor(mGdkWindow) == mWindowScaleFactor) {
+ if (!aForce &&
+ gdk_window_get_scale_factor(mGdkWindow) == mWindowScaleFactor) {
return;
}
// We pause compositor to avoid rendering of obsoleted remote content which
// produces flickering.
// Re-enable compositor again when remote content is updated or
// timeout happens.
PauseCompositorFlickering();
▲ Show 20 LinesShow All 3,020 Lines▼ Show 20 Lines
static void scale_changed_cb(GtkWidget* widget, GParamSpec* aPSpec,
gpointer aPointer) {
RefPtr<nsWindow> window = get_window_for_gtk_widget(widget);
if (!window) {
return;
}
- window->OnScaleChanged();
+ window->OnScaleChanged(/* aForce = */ false);
}
static gboolean touch_event_cb(GtkWidget* aWidget, GdkEventTouch* aEvent) {
UpdateLastInputEventTime(aEvent);
RefPtr<nsWindow> window = GetFirstNSWindowForGDKWindow(aEvent->window);
if (!window) {
return FALSE;
▲ Show 20 LinesShow All 575 Lines▼ Show 20 Lines
mWindowScaleFactor = gdk_window_get_scale_factor(scaledGdkWindow);
mWindowScaleFactorChanged = false;
} else {
mWindowScaleFactor = ScreenHelperGTK::GetGTKMonitorScaleFactor();
}
return mWindowScaleFactor;
}
- bool nsWindow::UseFractionalScale() const {
- #ifdef MOZ_WAYLAND
- return GdkIsWaylandDisplay() &&
- StaticPrefs::widget_wayland_fractional_buffer_scale_AtStartup() > 0 &&
- WaylandDisplayGet()->GetViewporter();
- #else
- return false;
- #endif
- }
-
double nsWindow::FractionalScaleFactor() {
#ifdef MOZ_WAYLAND
- if (UseFractionalScale()) {
- double scale =
- StaticPrefs::widget_wayland_fractional_buffer_scale_AtStartup();
- scale = std::max(scale, 0.5);
- scale = std::min(scale, 8.0);
- return scale;
+ if (mContainer) {
+ double fractional_scale =
+ moz_container_wayland_get_fractional_scale(mContainer);
+ if (fractional_scale != 0.0) {
+ return fractional_scale;
+ }
}
#endif
return GdkCeiledScaleFactor();
}
gint nsWindow::DevicePixelsToGdkCoordRoundUp(int aPixels) {
double scale = FractionalScaleFactor();
return ceil(aPixels / scale);
▲ Show 20 LinesShow All 853 LinesShow Last 20 Lines

widget/gtk/wayland/fractional-scale-v1-client-protocol.h

  • This file was added.
+ /* Generated by wayland-scanner 1.19.0 */
+
+ #ifndef FRACTIONAL_SCALE_V1_CLIENT_PROTOCOL_H
+ #define FRACTIONAL_SCALE_V1_CLIENT_PROTOCOL_H
+
+ #include <stdint.h>
+ #include <stddef.h>
+ #include "wayland-client.h"
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ /**
+ * @page page_fractional_scale_v1 The fractional_scale_v1 protocol
+ * Protocol for requesting fractional surface scales
+ *
+ * @section page_desc_fractional_scale_v1 Description
+ *
+ * This protocol allows a compositor to suggest for surfaces to render at
+ * fractional scales.
+ *
+ * A client can submit scaled content by utilizing wp_viewport. This is done by
+ * creating a wp_viewport object for the surface and setting the destination
+ * rectangle to the surface size before the scale factor is applied.
+ *
+ * The buffer size is calculated by multiplying the surface size by the
+ * intended scale.
+ *
+ * The wl_surface buffer scale should remain set to 1.
+ *
+ * If a surface has a surface-local size of 100 px by 50 px and wishes to
+ * submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should
+ * be used and the wp_viewport destination rectangle should be 100 px by 50 px.
+ *
+ * For toplevel surfaces, the size is rounded halfway away from zero. The
+ * rounding algorithm for subsurface position and size is not defined.
+ *
+ * @section page_ifaces_fractional_scale_v1 Interfaces
+ * - @subpage page_iface_wp_fractional_scale_manager_v1 - fractional surface scale information
+ * - @subpage page_iface_wp_fractional_scale_v1 - fractional scale interface to a wl_surface
+ * @section page_copyright_fractional_scale_v1 Copyright
+ * <pre>
+ *
+ * Copyright © 2022 Kenny Levinsen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * </pre>
+ */
+ struct wl_surface;
+ struct wp_fractional_scale_manager_v1;
+ struct wp_fractional_scale_v1;
+
+ #ifndef WP_FRACTIONAL_SCALE_MANAGER_V1_INTERFACE
+ #define WP_FRACTIONAL_SCALE_MANAGER_V1_INTERFACE
+ /**
+ * @page page_iface_wp_fractional_scale_manager_v1 wp_fractional_scale_manager_v1
+ * @section page_iface_wp_fractional_scale_manager_v1_desc Description
+ *
+ * A global interface for requesting surfaces to use fractional scales.
+ * @section page_iface_wp_fractional_scale_manager_v1_api API
+ * See @ref iface_wp_fractional_scale_manager_v1.
+ */
+ /**
+ * @defgroup iface_wp_fractional_scale_manager_v1 The wp_fractional_scale_manager_v1 interface
+ *
+ * A global interface for requesting surfaces to use fractional scales.
+ */
+ extern const struct wl_interface wp_fractional_scale_manager_v1_interface;
+ #endif
+ #ifndef WP_FRACTIONAL_SCALE_V1_INTERFACE
+ #define WP_FRACTIONAL_SCALE_V1_INTERFACE
+ /**
+ * @page page_iface_wp_fractional_scale_v1 wp_fractional_scale_v1
+ * @section page_iface_wp_fractional_scale_v1_desc Description
+ *
+ * An additional interface to a wl_surface object which allows the compositor
+ * to inform the client of the preferred scale.
+ * @section page_iface_wp_fractional_scale_v1_api API
+ * See @ref iface_wp_fractional_scale_v1.
+ */
+ /**
+ * @defgroup iface_wp_fractional_scale_v1 The wp_fractional_scale_v1 interface
+ *
+ * An additional interface to a wl_surface object which allows the compositor
+ * to inform the client of the preferred scale.
+ */
+ extern const struct wl_interface wp_fractional_scale_v1_interface;
+ #endif
+
+ #ifndef WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM
+ #define WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM
+ enum wp_fractional_scale_manager_v1_error {
+ /**
+ * the surface already has a fractional_scale object associated
+ */
+ WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_FRACTIONAL_SCALE_EXISTS = 0,
+ };
+ #endif /* WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM */
+
+ #define WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY 0
+ #define WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE 1
+
+
+ /**
+ * @ingroup iface_wp_fractional_scale_manager_v1
+ */
+ #define WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY_SINCE_VERSION 1
+ /**
+ * @ingroup iface_wp_fractional_scale_manager_v1
+ */
+ #define WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE_SINCE_VERSION 1
+
+ /** @ingroup iface_wp_fractional_scale_manager_v1 */
+ static inline void
+ wp_fractional_scale_manager_v1_set_user_data(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1, void *user_data)
+ {
+ wl_proxy_set_user_data((struct wl_proxy *) wp_fractional_scale_manager_v1, user_data);
+ }
+
+ /** @ingroup iface_wp_fractional_scale_manager_v1 */
+ static inline void *
+ wp_fractional_scale_manager_v1_get_user_data(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1)
+ {
+ return wl_proxy_get_user_data((struct wl_proxy *) wp_fractional_scale_manager_v1);
+ }
+
+ static inline uint32_t
+ wp_fractional_scale_manager_v1_get_version(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1)
+ {
+ return wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_manager_v1);
+ }
+
+ /**
+ * @ingroup iface_wp_fractional_scale_manager_v1
+ *
+ * Informs the server that the client will not be using this protocol
+ * object anymore. This does not affect any other objects,
+ * wp_fractional_scale_v1 objects included.
+ */
+ static inline void
+ wp_fractional_scale_manager_v1_destroy(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1)
+ {
+ wl_proxy_marshal((struct wl_proxy *) wp_fractional_scale_manager_v1,
+ WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY);
+
+ wl_proxy_destroy((struct wl_proxy *) wp_fractional_scale_manager_v1);
+ }
+
+ /**
+ * @ingroup iface_wp_fractional_scale_manager_v1
+ *
+ * Create an add-on object for the the wl_surface to let the compositor
+ * request fractional scales. If the given wl_surface already has a
+ * wp_fractional_scale_v1 object associated, the fractional_scale_exists
+ * protocol error is raised.
+ */
+ static inline struct wp_fractional_scale_v1 *
+ wp_fractional_scale_manager_v1_get_fractional_scale(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1, struct wl_surface *surface)
+ {
+ struct wl_proxy *id;
+
+ id = wl_proxy_marshal_constructor((struct wl_proxy *) wp_fractional_scale_manager_v1,
+ WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE, &wp_fractional_scale_v1_interface, NULL, surface);
+
+ return (struct wp_fractional_scale_v1 *) id;
+ }
+
+ /**
+ * @ingroup iface_wp_fractional_scale_v1
+ * @struct wp_fractional_scale_v1_listener
+ */
+ struct wp_fractional_scale_v1_listener {
+ /**
+ * notify of new preferred scale
+ *
+ * Notification of a new preferred scale for this surface that
+ * the compositor suggests that the client should use.
+ *
+ * The sent scale is the numerator of a fraction with a denominator
+ * of 120.
+ * @param scale the new preferred scale
+ */
+ void (*preferred_scale)(void *data,
+ struct wp_fractional_scale_v1 *wp_fractional_scale_v1,
+ uint32_t scale);
+ };
+
+ /**
+ * @ingroup iface_wp_fractional_scale_v1
+ */
+ static inline int
+ wp_fractional_scale_v1_add_listener(struct wp_fractional_scale_v1 *wp_fractional_scale_v1,
+ const struct wp_fractional_scale_v1_listener *listener, void *data)
+ {
+ return wl_proxy_add_listener((struct wl_proxy *) wp_fractional_scale_v1,
+ (void (**)(void)) listener, data);
+ }
+
+ #define WP_FRACTIONAL_SCALE_V1_DESTROY 0
+
+ /**
+ * @ingroup iface_wp_fractional_scale_v1
+ */
+ #define WP_FRACTIONAL_SCALE_V1_PREFERRED_SCALE_SINCE_VERSION 1
+
+ /**
+ * @ingroup iface_wp_fractional_scale_v1
+ */
+ #define WP_FRACTIONAL_SCALE_V1_DESTROY_SINCE_VERSION 1
+
+ /** @ingroup iface_wp_fractional_scale_v1 */
+ static inline void
+ wp_fractional_scale_v1_set_user_data(struct wp_fractional_scale_v1 *wp_fractional_scale_v1, void *user_data)
+ {
+ wl_proxy_set_user_data((struct wl_proxy *) wp_fractional_scale_v1, user_data);
+ }
+
+ /** @ingroup iface_wp_fractional_scale_v1 */
+ static inline void *
+ wp_fractional_scale_v1_get_user_data(struct wp_fractional_scale_v1 *wp_fractional_scale_v1)
+ {
+ return wl_proxy_get_user_data((struct wl_proxy *) wp_fractional_scale_v1);
+ }
+
+ static inline uint32_t
+ wp_fractional_scale_v1_get_version(struct wp_fractional_scale_v1 *wp_fractional_scale_v1)
+ {
+ return wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_v1);
+ }
+
+ /**
+ * @ingroup iface_wp_fractional_scale_v1
+ *
+ * Destroy the fractional scale object. When this object is destroyed,
+ * preferred_scale events will no longer be sent.
+ */
+ static inline void
+ wp_fractional_scale_v1_destroy(struct wp_fractional_scale_v1 *wp_fractional_scale_v1)
+ {
+ wl_proxy_marshal((struct wl_proxy *) wp_fractional_scale_v1,
+ WP_FRACTIONAL_SCALE_V1_DESTROY);
+
+ wl_proxy_destroy((struct wl_proxy *) wp_fractional_scale_v1);
+ }
+
+ #ifdef __cplusplus
+ }
+ #endif
+
+ #endif

widget/gtk/wayland/fractional-scale-v1-protocol.c

  • This file was added.
+ /* Generated by wayland-scanner 1.19.0 */
+
+ /*
+ * Copyright © 2022 Kenny Levinsen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+ #include <stdlib.h>
+ #include <stdint.h>
+ #include "wayland-util.h"
+
+ #ifndef __has_attribute
+ # define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
+ #endif
+
+ #if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
+ #define WL_PRIVATE __attribute__ ((visibility("hidden")))
+ #else
+ #define WL_PRIVATE
+ #endif
+
+ #pragma GCC visibility push(default)
+ extern const struct wl_interface wl_surface_interface;
+ #pragma GCC visibility pop
+ extern const struct wl_interface wp_fractional_scale_v1_interface;
+
+ static const struct wl_interface *fractional_scale_v1_types[] = {
+ NULL,
+ &wp_fractional_scale_v1_interface,
+ &wl_surface_interface,
+ };
+
+ static const struct wl_message wp_fractional_scale_manager_v1_requests[] = {
+ { "destroy", "", fractional_scale_v1_types + 0 },
+ { "get_fractional_scale", "no", fractional_scale_v1_types + 1 },
+ };
+
+ WL_PRIVATE const struct wl_interface wp_fractional_scale_manager_v1_interface = {
+ "wp_fractional_scale_manager_v1", 1,
+ 2, wp_fractional_scale_manager_v1_requests,
+ 0, NULL,
+ };
+
+ static const struct wl_message wp_fractional_scale_v1_requests[] = {
+ { "destroy", "", fractional_scale_v1_types + 0 },
+ };
+
+ static const struct wl_message wp_fractional_scale_v1_events[] = {
+ { "preferred_scale", "u", fractional_scale_v1_types + 0 },
+ };
+
+ WL_PRIVATE const struct wl_interface wp_fractional_scale_v1_interface = {
+ "wp_fractional_scale_v1", 1,
+ 1, wp_fractional_scale_v1_requests,
+ 1, wp_fractional_scale_v1_events,
+ };
+

widget/gtk/wayland/moz.build

# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Core", "Widget: Gtk")
SOURCES += [
+ "fractional-scale-v1-protocol.c",
"idle-inhibit-unstable-v1-protocol.c",
"linux-dmabuf-unstable-v1-protocol.c",
"pointer-constraints-unstable-v1-protocol.c",
"relative-pointer-unstable-v1-protocol.c",
"viewporter-protocol.c",
"xdg-activation-v1-protocol.c",
"xdg-output-unstable-v1-protocol.c",
]
EXPORTS.mozilla.widget += [
+ "fractional-scale-v1-client-protocol.h",
"idle-inhibit-unstable-v1-client-protocol.h",
"linux-dmabuf-unstable-v1-client-protocol.h",
"pointer-constraints-unstable-v1-client-protocol.h",
"relative-pointer-unstable-v1-client-protocol.h",
"viewporter-client-protocol.h",
"xdg-activation-v1-client-protocol.h",
"xdg-output-unstable-v1-client-protocol.h",
]
include("/ipc/chromium/chromium-config.mozbuild")
FINAL_LIBRARY = "xul"
CFLAGS += CONFIG["MOZ_GTK3_CFLAGS"]
CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"]

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK