19#include "sdl_rail_platform.hpp"
20#include "sdl_utils.hpp"
21#include "sdl_wayland.hpp"
22#include "sdl_win32.hpp"
25#include <freerdp/log.h>
26#include <freerdp/rail.h>
28#define TAG CLIENT_TAG("sdl.rail")
33 if (sdl::utils::isWaylandDriver())
36 caps.kind = RailPlatformKind::Wayland;
37 caps.supportsWindowPositions =
false;
38 caps.supportsTransparentWindows =
true;
39 caps.supportsRestack =
false;
40 caps.band = RailBandMechanism::None;
41 caps.drag = RailDragModel::CompositorResize;
43 else if (sdl::utils::isX11Driver())
46 caps.kind = RailPlatformKind::X11;
47 caps.supportsWindowPositions =
true;
48 caps.supportsTransparentWindows = sdl_x11_has_compositor();
49 caps.supportsRestack =
true;
50 caps.band = caps.supportsTransparentWindows ? RailBandMechanism::FrameExtents
51 : RailBandMechanism::None;
52 caps.drag = RailDragModel::WmMoveResize;
54 else if (sdl::utils::isWindowsDriver())
57 caps.kind = RailPlatformKind::Win32;
58 caps.supportsWindowPositions =
true;
59 caps.supportsTransparentWindows =
true;
60 caps.supportsRestack =
true;
61 caps.band = RailBandMechanism::NativeFrame;
62 caps.drag = RailDragModel::ModalLoop;
74[[nodiscard]]
static int railToNetDirection(uint16_t moveType)
78 case RAIL_WMSZ_TOPLEFT:
82 case RAIL_WMSZ_TOPRIGHT:
86 case RAIL_WMSZ_BOTTOMRIGHT:
88 case RAIL_WMSZ_BOTTOM:
90 case RAIL_WMSZ_BOTTOMLEFT:
100static constexpr struct
105 { RAIL_WMSZ_TOP, 1 }, { RAIL_WMSZ_BOTTOM, 2 }, { RAIL_WMSZ_LEFT, 4 },
106 { RAIL_WMSZ_TOPLEFT, 5 }, { RAIL_WMSZ_BOTTOMLEFT, 6 }, { RAIL_WMSZ_RIGHT, 8 },
107 { RAIL_WMSZ_TOPRIGHT, 9 }, { RAIL_WMSZ_BOTTOMRIGHT, 10 },
111[[nodiscard]]
static uint32_t railToXdgEdge(uint16_t moveType)
113 for (
const auto& e : kRailXdgEdges)
114 if (e.rail == moveType)
121 return { (moveType == RAIL_WMSZ_TOPLEFT) || (moveType == RAIL_WMSZ_LEFT) ||
122 (moveType == RAIL_WMSZ_BOTTOMLEFT),
123 (moveType == RAIL_WMSZ_TOPRIGHT) || (moveType == RAIL_WMSZ_RIGHT) ||
124 (moveType == RAIL_WMSZ_BOTTOMRIGHT),
125 (moveType == RAIL_WMSZ_TOPLEFT) || (moveType == RAIL_WMSZ_TOP) ||
126 (moveType == RAIL_WMSZ_TOPRIGHT),
127 (moveType == RAIL_WMSZ_BOTTOMLEFT) || (moveType == RAIL_WMSZ_BOTTOM) ||
128 (moveType == RAIL_WMSZ_BOTTOMRIGHT) };
131void railPlatformPrepareWindow(SDL_Window* window)
133 switch (railPlatformCaps().kind)
135 case RailPlatformKind::Wayland:
136 sdl_wayland_move_prepare(window);
138 case RailPlatformKind::Win32:
139 if (!sdl_win32_use_native_frame(window))
140 WLog_WARN(TAG,
"native window frame not available");
147bool railPlatformSetWindowRect(SDL_Window* window,
const SDL_Rect& rect)
149 if (railPlatformCaps().kind == RailPlatformKind::Win32)
150 return sdl_win32_set_client_rect(window, rect);
157 if (railPlatformCaps().kind == RailPlatformKind::Win32)
158 sdl_win32_set_size_move_handler({ handler.userdata, handler.redraw, handler.resize });
161bool railPlatformSetBand(SDL_Window* window,
const SDL_Rect& insets)
163 const auto& caps = railPlatformCaps();
164 if (caps.band == RailBandMechanism::None)
168 case RailPlatformKind::X11:
169 return sdl_x11_set_frame_extents(window, insets.x, insets.w, insets.y, insets.h);
170 case RailPlatformKind::Win32:
176bool railPlatformRestack(
const std::vector<SDL_Window*>& topToBottom)
178 switch (railPlatformCaps().kind)
180 case RailPlatformKind::X11:
181 return sdl_x11_restack_windows(topToBottom);
182 case RailPlatformKind::Win32:
183 return sdl_win32_restack_windows(topToBottom);
189bool railPlatformBeginDrag(SDL_Window* window, uint16_t moveType)
191 switch (railPlatformCaps().kind)
193 case RailPlatformKind::Wayland:
194 if (moveType == RAIL_WMSZ_MOVE)
195 return sdl_wayland_begin_move(window);
196 return sdl_wayland_begin_resize(window, railToXdgEdge(moveType));
197 case RailPlatformKind::X11:
199 if (!sdl_x11_begin_move_size(window, railToNetDirection(moveType)))
203 const int row = e.top ? 2 : (e.bottom ? 0 : 1);
204 const int col = e.left ? 2 : (e.right ? 0 : 1);
205 if (!sdl_x11_set_bit_gravity(window, row * 3 + col + 1))
206 WLog_DBG(TAG,
"setting the X11 bit gravity failed");
209 case RailPlatformKind::Win32:
211 return sdl_win32_can_move_size(window, moveType == RAIL_WMSZ_MOVE, moveType);
217void railPlatformRunModalDrag(SDL_Window* window, uint16_t moveType)
220 if (railPlatformCaps().kind == RailPlatformKind::Win32)
221 sdl_win32_run_move_size(window, moveType == RAIL_WMSZ_MOVE, moveType);
224bool railPlatformReleaseButton(SDL_Window* window)
226 switch (railPlatformCaps().kind)
228 case RailPlatformKind::X11:
229 return sdl_x11_send_left_button_release(window);
230 case RailPlatformKind::Win32:
231 return sdl_win32_send_left_button_release(window);
237bool railPlatformRaiseOwned(SDL_Window* window)
240 if (railPlatformCaps().kind != RailPlatformKind::X11)
242 return sdl_x11_raise_window(window);
245void railPlatformEndDrag(SDL_Window* window)
247 if (railPlatformCaps().kind == RailPlatformKind::X11)
248 if (!sdl_x11_set_bit_gravity(window, 0 ))
249 WLog_DBG(TAG,
"resetting the X11 bit gravity failed");