더 나은 디스플레이를 사용했을 때 역효과: Hyprland에서 '흐릿한' VLC 고치기
Source: Dev.to
Background
왜 간단한 비디오 플레이어가 흐릿하게 보이는지 이해하려면 몇 가지 기술적 배경이 필요합니다.
1. HiDPI (High Dots‑Per‑Inch) 디스플레이
- 물리적 현실: 전통적인 화면은 약 96 PPI였으며, 50 픽셀짜리 버튼은 대략 ½ 인치 정도의 너비였습니다. 현대 화면은 동일한 물리적 공간에 거의 두 배에 해당하는 픽셀을 담고 있습니다.
- 논리 픽셀 vs. 물리 픽셀: Qt가 같은 50 픽셀 버튼을 HiDPI 화면에 그리면 물리적으로는 매우 작게(≈ ¼ 인치) 표시됩니다. 올바르게 보이게 하려면 Qt는 100 픽셀 버튼을 래스터화해야 합니다.
- 스케일 팩터: 시스템은 스케일 팩터(예: 200 %)를 적용해 각 논리 픽셀이 두 개의 물리 픽셀에 매핑되도록 합니다. 이를 통해 UI가 픽셀 밀도와 관계없이 읽기 쉽고 선명하게 유지됩니다.
2. Qt
Qt는 VLC가 인터페이스에 사용하는 프레임워크이며, 주요 역할은 래스터화입니다.
래스터화란?
청사진과 사진의 차이를 생각해 보세요.
- 청사진 (벡터): UI가 수학적으로 기술됩니다. 예를 들어 “반경 50 단위인 완벽한 원을 그려라”와 같이 무한한 해상도를 갖는 설명입니다.
- 사진 (래스터): UI를 화면에 표시하기 위해 Qt는 수학적 설명을 색이 입힌 점(픽셀)들의 격자로 변환합니다. 이 과정을 래스터화라고 합니다.
래스터화가 끝나면 Qt는 결과를 그래픽 버퍼에 저장합니다—실질적으로 RAM에 있는 비트맵 이미지이며, 이를 디스플레이 서버에 넘겨 화면에 배치됩니다.

3. 디스플레이 서버
디스플레이 서버는 애플리케이션(클라이언트)과 하드웨어(커널/GPU) 사이에 위치합니다. 역할은 모든 열린 앱으로부터 버퍼(이미지)를 받아 물리적 화면에 정확히 어디에 표시할지 결정하는 것입니다.
4. 프로토콜: X11 vs. Wayland
이들은 애플리케이션이 디스플레이 하드웨어와 통신하는 방식을 정의하는 표준입니다.
X11
- 1980년대에 네트워크 투명 프로토콜로 설계되었습니다.
- 세 가지 별도 구성 요소가 필요합니다:
- 클라이언트(앱): 창을 그리려는 요청을 보냅니다.
- X 서버(디스플레이 서버): 하드웨어를 제어하지만 창 배치에 대한 로직이 없는 “멍청한” 중개자입니다.
- 윈도우 매니저: 창이 어디에 배치될지 결정합니다.
- X11 프로토콜은 디스플레이 서버가 정책 결정(예: 창 배치)을 하는 것을 금지하므로, 모든 동작이 세 갈래 대화(App ↔ Server ↔ WM)를 필요로 합니다.
- X11은 전역 좌표 공간에 의존합니다—모든 화면에 걸쳐 하나의 통합 캔버스가 존재합니다. 모든 앱은 그 격자의 스케일에 동의해야 합니다. HiDPI와 일반 DPI 모니터를 동시에 사용할 경우, X11은 캔버스의 일부분만을 확대하기가 어렵습니다.
- DPI 인식은 시스템 전체에 적용됩니다(예:
Xft.dpi). 많은 레거시 앱이 이를 무시하기 때문에 모니터별 스케일링이 힘듭니다.
Wayland
- X11의 비효율성을 없애기 위해 설계되었습니다.
- “디스플레이 서버”와 “윈도우 매니저”가 컴포지터라는 하나의 소프트웨어로 합쳐집니다(우리 경우 Hyprland).
- 직접 제어: 클라이언트가 자체 버퍼를 할당하고 이를 바로 컴포지터에 전달합니다.
- 격리: 각 앱은 자체 서피스(개인용 종이 한 장)를 갖습니다. 컴포지터는 한 서피스를 2×로 스케일링하고 다른 서피스를 1×로 유지할 수 있어, 현대 HiDPI 화면이 요구하는 창별 유연성을 제공합니다.
- Wayland는 HiDPI를 원활히 처리합니다—컴포지터가 각 서피스에 어떻게 스케일링할지 명시적으로 알려주므로 전역 DPI 설정이 필요 없습니다.
5. 브리지: XWayland
X11은 30년 넘게 표준이었습니다. 수천 개의 애플리케이션(구형 게임, Steam, VLC 3.0 등)이 X11만을 사용하도록 작성되었습니다. 표준 X11 애플리케이션은 Wayland 프로토콜을 통해 통신할 수 없기 때문에, XWayland가 번역 계층 역할을 합니다. 이는 Wayland 세션 내부에서 실행되는 완전한 기능을 갖춘 X 서버입니다.
- 앱(VLC) 입장에서는: XWayland가 일반적인 X 서버처럼 보입니다.
- 컴포지터(Hyprland) 입장에서는: XWayland가 X 서버 역할을 수행합니다.
yland는 단일 애플리케이션 창처럼 보입니다.
하지만 이것은 문제를 일으킵니다. XWayland 앱은 X11의 스케일링 제한을 물려받아—Wayland 컴포지터로부터 창별 스케일링 지시를 받을 수 없습니다. 이 때문에 Hyprland는 다음과 같은 절충안을 선택해야 합니다:
- 네이티브 1× 해상도로 렌더링하도록 허용 (선명하지만 매우 작음).
xwayland:force_zero_scaling을 사용해 확대 (읽기 쉬운 크기지만 흐림).
Hyprland의 xwayland:force_zero_scaling 설정(기본적으로 활성화)은 두 번째 옵션을 선택합니다: XWayland 앱에 저 DPI 디스플레이에 있다고 알려준 뒤, 그 출력물을 확대합니다. 그 결과는 텍스트가 읽기 쉬워지지만 흐릿해지는 것입니다—앱이 표준 디스플레이라고 가정하고 1× 해상도로 그렸고, Hyprland가 그 픽셀을 HiDPI 화면에 맞게 늘렸기 때문입니다.
문제와 해결 방법
VLC 3.0은 네이티브 Wayland 지원이 없어서 XWayland를 사용합니다. 이 때문에 스케일링 문제가 발생합니다: VLC 3.0은 X11의 DPI 힌트를 무시하고 기본 1× 해상도로 렌더링합니다. Hyprland의 xwayland:force_zero_scaling이 비활성화된 상태(기본값)에서는 VLC의 1× 출력이 확대되어 흐릿하게 보입니다.
1단계 – Hyprland에서 강제 스케일링 비활성화
Hyprland 설정 파일에 다음을 추가합니다:
xwayland {
force_zero_scaling = true
}
결과: VLC가 선명하게 렌더링되지만 화면이 매우 작아집니다.
2단계 – Qt에 2× 스케일링을 지정
X11의 DPI 시스템을 완전히 우회하고, Qt의 스케일링 팩터를 사용해 VLC를 실행합니다:
QT_SCALE_FACTOR=2 vlc
결과: VLC가 Qt 환경 변수를 인식해 UI를 내부적으로 2×로 렌더링하고, 강제 스케일링이 비활성화되어 Hyprland가 다시 확대하지 않으므로 텍스트가 선명하고 적절한 크기로 표시됩니다.
마무리 생각
이번 여정을 통해 Linux GUI 생태계를 조금 더 알게 되는 기회를 가졌습니다. 저는 아직 Linux 그래픽 스택의 복잡한 구조를 배우고 있는 중이며(정말 깊은 토끼굴이죠!). 제가 어떤 아키텍처 세부 사항을 과도하게 단순화했거나, Hyprland에서 이를 처리하는 더 깔끔한 방법을 알고 계시다면 피드백을 주시면 감사하겠습니다. 언제든지 연락하거나 정정해 주세요!