Skip to content

Commit c16373a

Browse files
committed
Display (Linux): support primary display detection for GNOME
1 parent 73875de commit c16373a

File tree

6 files changed

+553
-15
lines changed

6 files changed

+553
-15
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ if(LINUX)
434434
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
435435
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
436436
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
437+
src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c
437438
src/detection/displayserver/linux/wmde.c
438439
src/detection/displayserver/linux/xcb.c
439440
src/detection/displayserver/linux/xlib.c
@@ -570,6 +571,7 @@ elseif(BSD)
570571
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
571572
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
572573
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
574+
src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c
573575
src/detection/displayserver/linux/wmde.c
574576
src/detection/displayserver/linux/xcb.c
575577
src/detection/displayserver/linux/xlib.c
@@ -774,6 +776,7 @@ elseif(SunOS)
774776
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
775777
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
776778
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
779+
src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c
777780
src/detection/displayserver/linux/wmde.c
778781
src/detection/displayserver/linux/xcb.c
779782
src/detection/displayserver/linux/xlib.c

src/detection/displayserver/linux/wayland/global-output.c

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "wayland.h"
44
#include "util/stringUtils.h"
5+
#include "xdg-output-unstable-v1-client-protocol.h"
56

67
static void waylandOutputModeListener(void* data, FF_MAYBE_UNUSED struct wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refreshRate)
78
{
@@ -35,6 +36,39 @@ static void waylandOutputGeometryListener(void *data,
3536
display->transform = (enum wl_output_transform) transform;
3637
}
3738

39+
static void handleXdgLogicalSize(void *data, FF_MAYBE_UNUSED struct zxdg_output_v1 *_, int32_t width, FF_MAYBE_UNUSED int32_t height)
40+
{
41+
WaylandDisplay* display = data;
42+
// Seems the values are only useful when ractional scale is enabled
43+
if (width < display->width)
44+
{
45+
display->scale = (double) display->width / width;
46+
}
47+
}
48+
49+
// Dirty hack for #477
50+
// The order of these callbacks MUST follow `struct wl_output_listener`
51+
static void* outputListener[] = {
52+
waylandOutputGeometryListener, // geometry
53+
waylandOutputModeListener, // mode
54+
stubListener, // done
55+
waylandOutputScaleListener, // scale
56+
ffWaylandOutputNameListener, // name
57+
ffWaylandOutputDescriptionListener, // description
58+
};
59+
static_assert(
60+
sizeof(outputListener) >= sizeof(struct wl_output_listener),
61+
"sizeof(outputListener) is too small. Please report it to fastfetch github issue"
62+
);
63+
64+
static struct zxdg_output_v1_listener zxdgOutputListener = {
65+
.logical_position = (void*) stubListener,
66+
.logical_size = handleXdgLogicalSize,
67+
.done = (void*) stubListener,
68+
.name = (void*) stubListener,
69+
.description = (void*) stubListener,
70+
};
71+
3872
void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
3973
{
4074
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, wldata->ffwl_output_interface, version, name, wldata->ffwl_output_interface->name, version, NULL);
@@ -54,23 +88,21 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
5488
.edidName = ffStrbufCreate(),
5589
};
5690

57-
// Dirty hack for #477
58-
// The order of these callbacks MUST follow `struct wl_output_listener`
59-
void* outputListener[] = {
60-
waylandOutputGeometryListener, // geometry
61-
waylandOutputModeListener, // mode
62-
stubListener, // done
63-
waylandOutputScaleListener, // scale
64-
ffWaylandOutputNameListener, // name
65-
ffWaylandOutputDescriptionListener, // description
66-
};
67-
static_assert(
68-
sizeof(outputListener) >= sizeof(struct wl_output_listener),
69-
"sizeof(outputListener) is too small. Please report it to fastfetch github issue"
70-
);
71-
7291
wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display);
7392
wldata->ffwl_display_roundtrip(wldata->display);
93+
94+
if (wldata->zxdgOutputManager)
95+
{
96+
struct wl_proxy* zxdgOutput = wldata->ffwl_proxy_marshal_constructor_versioned(wldata->zxdgOutputManager, ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, version, NULL, output);
97+
98+
if (zxdgOutput)
99+
{
100+
wldata->ffwl_proxy_add_listener(zxdgOutput, (void(**)(void)) &zxdgOutputListener, &display);
101+
wldata->ffwl_display_roundtrip(wldata->display);
102+
wldata->ffwl_proxy_destroy(zxdgOutput);
103+
}
104+
}
105+
74106
wldata->ffwl_proxy_destroy(output);
75107

76108
if(display.width <= 0 || display.height <= 0)
@@ -132,4 +164,13 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
132164
ffStrbufDestroy(&display.edidName);
133165
}
134166

167+
void ffWaylandHandleXdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
168+
{
169+
struct wl_proxy* manager = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &zxdg_output_manager_v1_interface, version, name, zxdg_output_manager_v1_interface.name, version, NULL);
170+
if(manager == NULL)
171+
return;
172+
173+
wldata->zxdgOutputManager = manager;
174+
}
175+
135176
#endif

src/detection/displayserver/linux/wayland/wayland.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "wlr-output-management-unstable-v1-client-protocol.h"
1414
#include "kde-output-device-v2-client-protocol.h"
1515
#include "kde-output-order-v1-client-protocol.h"
16+
#include "xdg-output-unstable-v1-client-protocol.h"
1617

1718
#ifndef __FreeBSD__
1819
static void waylandDetectWM(int fd, FFDisplayServerResult* result)
@@ -58,6 +59,10 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
5859
{
5960
ffWaylandHandleKdeOutputOrder(wldata, registry, name, version);
6061
}
62+
else if(wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_GLOBAL && ffStrEquals(interface, zxdg_output_manager_v1_interface.name))
63+
{
64+
ffWaylandHandleXdgOutput(wldata, registry, name, version);
65+
}
6166
}
6267

6368
bool detectWayland(FFDisplayServerResult* result)
@@ -101,6 +106,9 @@ bool detectWayland(FFDisplayServerResult* result)
101106
data.ffwl_proxy_add_listener(registry, (void(**)(void)) &registry_listener, &data);
102107
data.ffwl_display_roundtrip(data.display);
103108

109+
if (data.zxdgOutputManager)
110+
data.ffwl_proxy_destroy(data.zxdgOutputManager);
111+
104112
data.ffwl_proxy_destroy(registry);
105113
ffwl_display_disconnect(data.display);
106114

src/detection/displayserver/linux/wayland/wayland.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ typedef struct WaylandData
2828
const struct wl_interface* ffwl_output_interface;
2929
WaylandProtocolType protocolType;
3030
uint64_t primaryDisplayId;
31+
struct wl_proxy* zxdgOutputManager;
3132
} WaylandData;
3233

3334
typedef struct WaylandDisplay
@@ -58,5 +59,6 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
5859
void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
5960
void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
6061
void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
62+
void ffWaylandHandleXdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
6163

6264
#endif

0 commit comments

Comments
 (0)