mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-06-20 19:03:56 +02:00
Use maximum display resolution for the window size
Instead of it being hardcoded to 1440p.
This commit is contained in:
@@ -8,9 +8,8 @@ compatibility while also being easy to debug and maintain.
|
|||||||
|
|
||||||
There are a few things that should be done before releasing this, including:
|
There are a few things that should be done before releasing this, including:
|
||||||
|
|
||||||
- Fix implementation bugs:
|
- Do some final refactoring/clean up. There are a few small todos left for
|
||||||
- Polish GUIs even further. There are some todos left in
|
things that could be a made little bit prettier.
|
||||||
`src/wine-host/editor.{h,cpp}`.
|
|
||||||
- Add missing details if any to the architecture section.
|
- Add missing details if any to the architecture section.
|
||||||
- Rewrite parts of this readme.
|
- Rewrite parts of this readme.
|
||||||
- Briefly verify that this also works fine in Reaper and Ardour.
|
- Briefly verify that this also works fine in Reaper and Ardour.
|
||||||
|
|||||||
+40
-24
@@ -25,25 +25,15 @@ constexpr size_t idle_timer_id = 1337;
|
|||||||
*/
|
*/
|
||||||
constexpr uint16_t event_type_mask = ((1 << 7) - 1);
|
constexpr uint16_t event_type_mask = ((1 << 7) - 1);
|
||||||
|
|
||||||
// TODO: The (maximum) client area is now set at 1440p, to prevent unnecessary
|
|
||||||
// overhead and to support fullscreen windows at 4k resolutions we should
|
|
||||||
// just use the dimensions of the X11 root window instead.
|
|
||||||
/**
|
/**
|
||||||
* The initial and maximum width of the Wine window hosting the plugin's editor
|
* Compute the size a window would have to be to be allowed to fullscreened on
|
||||||
* window. This is set at a fixed size to make window resizing feel native.
|
* any of the connected screens.
|
||||||
*/
|
*/
|
||||||
constexpr uint16_t client_area_width = 2560;
|
Size get_maximum_screen_dimensions(xcb_connection_t& x11_connection);
|
||||||
/**
|
|
||||||
* The initial and maximum width of the Wine window hosting the plugin's editor
|
|
||||||
* window. This is set at a fixed size to make window resizing feel native.
|
|
||||||
*/
|
|
||||||
constexpr uint16_t client_area_height = 1440;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the X11 window handle for the window if it's currently open.
|
* Return the X11 window handle for the window if it's currently open.
|
||||||
*/
|
*/
|
||||||
xcb_window_t get_x11_handle(HWND win32_handle);
|
xcb_window_t get_x11_handle(HWND win32_handle);
|
||||||
|
|
||||||
ATOM register_window_class(std::string window_class_name);
|
ATOM register_window_class(std::string window_class_name);
|
||||||
|
|
||||||
WindowClass::WindowClass(std::string name)
|
WindowClass::WindowClass(std::string name)
|
||||||
@@ -56,7 +46,9 @@ WindowClass::~WindowClass() {
|
|||||||
Editor::Editor(const std::string& window_class_name,
|
Editor::Editor(const std::string& window_class_name,
|
||||||
AEffect* effect,
|
AEffect* effect,
|
||||||
const size_t parent_window_handle)
|
const size_t parent_window_handle)
|
||||||
: window_class(window_class_name),
|
: x11_connection(xcb_connect(nullptr, nullptr), xcb_disconnect),
|
||||||
|
client_area(get_maximum_screen_dimensions(*x11_connection)),
|
||||||
|
window_class(window_class_name),
|
||||||
// Create a window without any decoratiosn for easy embedding. The
|
// Create a window without any decoratiosn for easy embedding. The
|
||||||
// combination of `WS_EX_TOOLWINDOW` and `WS_POPUP` causes the window to
|
// combination of `WS_EX_TOOLWINDOW` and `WS_POPUP` causes the window to
|
||||||
// be drawn without any decorations (making resizes behave as you'd
|
// be drawn without any decorations (making resizes behave as you'd
|
||||||
@@ -68,8 +60,8 @@ Editor::Editor(const std::string& window_class_name,
|
|||||||
WS_POPUP,
|
WS_POPUP,
|
||||||
CW_USEDEFAULT,
|
CW_USEDEFAULT,
|
||||||
CW_USEDEFAULT,
|
CW_USEDEFAULT,
|
||||||
client_area_width,
|
client_area.width,
|
||||||
client_area_height,
|
client_area.height,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
GetModuleHandle(nullptr),
|
GetModuleHandle(nullptr),
|
||||||
@@ -78,8 +70,7 @@ Editor::Editor(const std::string& window_class_name,
|
|||||||
parent_window(parent_window_handle),
|
parent_window(parent_window_handle),
|
||||||
child_window(get_x11_handle(win32_handle.get())),
|
child_window(get_x11_handle(win32_handle.get())),
|
||||||
// Needed to send update messages on a timer
|
// Needed to send update messages on a timer
|
||||||
plugin(effect),
|
plugin(effect) {
|
||||||
x11_connection(xcb_connect(nullptr, nullptr), xcb_disconnect) {
|
|
||||||
// The Win32 API will block the `DispatchMessage` call when opening e.g. a
|
// The Win32 API will block the `DispatchMessage` call when opening e.g. a
|
||||||
// dropdown, but it will still allow timers to be run so the GUI can still
|
// dropdown, but it will still allow timers to be run so the GUI can still
|
||||||
// update in the background. Because of this we send `effEditIdle` to the
|
// update in the background. Because of this we send `effEditIdle` to the
|
||||||
@@ -153,10 +144,9 @@ void Editor::handle_events() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle X11 events
|
// Handle X11 events
|
||||||
// TODO: Initiating drag-and-drop _sometimes_ causes the GUI to update while
|
// TODO: Initiating drag-and-drop in Serum _sometimes_ causes the GUI to
|
||||||
// dragging while other times it does not. Not sure why this is
|
// update while dragging while other times it does not. From all the
|
||||||
// happening. Forwarding XDND requests manually is very clunky and
|
// plugins I've tested this only happens in Serum though.
|
||||||
// causes different problems.
|
|
||||||
xcb_generic_event_t* generic_event;
|
xcb_generic_event_t* generic_event;
|
||||||
while ((generic_event = xcb_poll_for_event(x11_connection.get())) !=
|
while ((generic_event = xcb_poll_for_event(x11_connection.get())) !=
|
||||||
nullptr) {
|
nullptr) {
|
||||||
@@ -189,8 +179,13 @@ void Editor::handle_events() {
|
|||||||
translated_event.response_type = XCB_CONFIGURE_NOTIFY;
|
translated_event.response_type = XCB_CONFIGURE_NOTIFY;
|
||||||
translated_event.event = child_window;
|
translated_event.event = child_window;
|
||||||
translated_event.window = child_window;
|
translated_event.window = child_window;
|
||||||
translated_event.width = client_area_width;
|
// This should be set to the same sizes the window was created
|
||||||
translated_event.height = client_area_height;
|
// on. Since we're not using `SetWindowPos` to resize the
|
||||||
|
// Window, Wine can get a bit confused when we suddenly report a
|
||||||
|
// different client area size. Without this certain plugins
|
||||||
|
// (such as those by Valhalla DSP) would break.
|
||||||
|
translated_event.width = client_area.width;
|
||||||
|
translated_event.height = client_area.height;
|
||||||
translated_event.x = event.x;
|
translated_event.x = event.x;
|
||||||
translated_event.y = event.y;
|
translated_event.y = event.y;
|
||||||
|
|
||||||
@@ -246,6 +241,27 @@ LRESULT CALLBACK window_proc(HWND handle,
|
|||||||
return DefWindowProc(handle, message, wParam, lParam);
|
return DefWindowProc(handle, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Size get_maximum_screen_dimensions(xcb_connection_t& x11_connection) {
|
||||||
|
xcb_screen_iterator_t iter =
|
||||||
|
xcb_setup_roots_iterator(xcb_get_setup(&x11_connection));
|
||||||
|
|
||||||
|
// Find the maximum dimensions the window would have to be to be able to be
|
||||||
|
// fullscreened on any screen, disregarding the possibility that someone
|
||||||
|
// would try to stretch the window accross all displays (because who would
|
||||||
|
// do such a thing?)
|
||||||
|
Size maximum_screen_size{};
|
||||||
|
while (iter.rem > 0) {
|
||||||
|
xcb_screen_next(&iter);
|
||||||
|
|
||||||
|
maximum_screen_size.width =
|
||||||
|
std::max(maximum_screen_size.width, iter.data->width_in_pixels);
|
||||||
|
maximum_screen_size.height =
|
||||||
|
std::max(maximum_screen_size.height, iter.data->height_in_pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
return maximum_screen_size;
|
||||||
|
}
|
||||||
|
|
||||||
xcb_window_t get_x11_handle(HWND win32_handle) {
|
xcb_window_t get_x11_handle(HWND win32_handle) {
|
||||||
return reinterpret_cast<size_t>(
|
return reinterpret_cast<size_t>(
|
||||||
GetProp(win32_handle, "__wine_x11_whole_window"));
|
GetProp(win32_handle, "__wine_x11_whole_window"));
|
||||||
|
|||||||
+28
-9
@@ -32,6 +32,14 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to store the maximum width and height of a screen.
|
||||||
|
*/
|
||||||
|
struct Size {
|
||||||
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A basic RAII wrapper around the Win32 window class system, for use in the
|
* A basic RAII wrapper around the Win32 window class system, for use in the
|
||||||
* Editor class below.
|
* Editor class below.
|
||||||
@@ -100,10 +108,27 @@ class Editor {
|
|||||||
void handle_events();
|
void handle_events();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* A pointer to the currently active window. Will be a null pointer if no
|
||||||
|
* window is active.
|
||||||
|
*/
|
||||||
|
std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> x11_connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Wine window's client area, or the maximum size of that window. This
|
||||||
|
* will be set to a size that's large enough to be able to enter full screen
|
||||||
|
* on a single display. This is more of a theoretical maximum size, as the
|
||||||
|
* plugin will only use a portion of this window to draw to. Because we're
|
||||||
|
* not changing the size of the Wine window and simply letting the user or
|
||||||
|
* the host resize the X11 parent window it's been embedded in instead,
|
||||||
|
* resizing will feel smooth and native.
|
||||||
|
*/
|
||||||
|
const Size client_area;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Win32 window class registered for the windows window.
|
* The Win32 window class registered for the windows window.
|
||||||
*/
|
*/
|
||||||
WindowClass window_class;
|
const WindowClass window_class;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -117,20 +142,14 @@ class Editor {
|
|||||||
/**
|
/**
|
||||||
* The window handle of the editor window created by the DAW.
|
* The window handle of the editor window created by the DAW.
|
||||||
*/
|
*/
|
||||||
xcb_window_t parent_window;
|
const xcb_window_t parent_window;
|
||||||
/**
|
/**
|
||||||
* The X11 window handle of the window belonging to `win32_handle`.
|
* The X11 window handle of the window belonging to `win32_handle`.
|
||||||
*/
|
*/
|
||||||
xcb_window_t child_window;
|
const xcb_window_t child_window;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Needed to handle idle updates through a timer
|
*Needed to handle idle updates through a timer
|
||||||
*/
|
*/
|
||||||
AEffect* plugin;
|
AEffect* plugin;
|
||||||
|
|
||||||
/**
|
|
||||||
* A pointer to the currently active window. Will be a null pointer if no
|
|
||||||
* window is active.
|
|
||||||
*/
|
|
||||||
std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> x11_connection;
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user