mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Implement part of the XEmbed protocol
This commit is contained in:
@@ -1,10 +1,23 @@
|
|||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
|
|
||||||
|
constexpr char xembed_info_proeprty[] = "_XEMBED_INFO";
|
||||||
|
|
||||||
ATOM register_window_class(std::string window_class_name);
|
ATOM register_window_class(std::string window_class_name);
|
||||||
|
|
||||||
Editor::Editor(std::string window_class_name)
|
Editor::Editor(std::string window_class_name)
|
||||||
: window_class(register_window_class(window_class_name)),
|
: window_class(register_window_class(window_class_name)),
|
||||||
x11_connection(xcb_connect(nullptr, nullptr), &xcb_disconnect) {}
|
x11_connection(xcb_connect(nullptr, nullptr), &xcb_disconnect) {
|
||||||
|
// We need a bunch of property atoms for the XEmbed protocol
|
||||||
|
xcb_generic_error_t* err;
|
||||||
|
|
||||||
|
const auto xembed_info_cookie =
|
||||||
|
xcb_intern_atom(x11_connection.get(), 0, strlen(xembed_info_proeprty),
|
||||||
|
xembed_info_proeprty);
|
||||||
|
|
||||||
|
xcb_xembed_info =
|
||||||
|
xcb_intern_atom_reply(x11_connection.get(), xembed_info_cookie, &err)
|
||||||
|
->atom;
|
||||||
|
}
|
||||||
|
|
||||||
HWND Editor::open() {
|
HWND Editor::open() {
|
||||||
// Create a window without any decoratiosn for easy embedding. The
|
// Create a window without any decoratiosn for easy embedding. The
|
||||||
@@ -49,14 +62,23 @@ bool Editor::embed_into(const size_t parent_window_handle) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This follows the embedding procedure specified in the XEmbed sped:
|
||||||
|
// https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html
|
||||||
|
// under 'Embedding life cycle
|
||||||
|
// Sadly there's doesn't seem to be any implementation of this available as
|
||||||
|
// a library
|
||||||
const size_t child_window_handle = get_x11_handle().value();
|
const size_t child_window_handle = get_x11_handle().value();
|
||||||
|
|
||||||
// TODO: Reparenting works, but the Wine window is not updating so that
|
|
||||||
// might cause it to look like it doesn't work
|
|
||||||
xcb_reparent_window(x11_connection.get(), child_window_handle,
|
xcb_reparent_window(x11_connection.get(), child_window_handle,
|
||||||
parent_window_handle, 0, 0);
|
parent_window_handle, 0, 0);
|
||||||
|
|
||||||
// TODO: Is this needed?
|
// This tells the WM that the parent window embedding and mapping/uumapping
|
||||||
|
// a child window. Requires the PROPERTY_NOTIFY event.
|
||||||
|
std::array<int, 2> xembed_info_values{0, 1};
|
||||||
|
xcb_change_property(x11_connection.get(), XCB_PROP_MODE_REPLACE,
|
||||||
|
parent_window_handle, xcb_xembed_info, xcb_xembed_info,
|
||||||
|
32, 2, xembed_info_values.data());
|
||||||
|
|
||||||
const int parent_events = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
|
const int parent_events = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
|
||||||
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
||||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||||
@@ -69,14 +91,16 @@ bool Editor::embed_into(const size_t parent_window_handle) {
|
|||||||
xcb_change_window_attributes(x11_connection.get(), child_window_handle,
|
xcb_change_window_attributes(x11_connection.get(), child_window_handle,
|
||||||
XCB_CW_EVENT_MASK, &child_events);
|
XCB_CW_EVENT_MASK, &child_events);
|
||||||
|
|
||||||
|
// TODO: Send XEMBED_EMBEDDED_NOTIFY XEMBED_FOCUS_IN, XEMBED_WINDOW_ACTIVATE
|
||||||
|
// and XEMBED_MODALITY_ON from the parent window Before or after
|
||||||
|
// embedding?
|
||||||
|
|
||||||
// TODO: Is this map needed?
|
// TODO: Is this map needed?
|
||||||
xcb_map_window(x11_connection.get(), child_window_handle);
|
xcb_map_window(x11_connection.get(), child_window_handle);
|
||||||
xcb_flush(x11_connection.get());
|
xcb_flush(x11_connection.get());
|
||||||
|
|
||||||
ShowWindow(win32_handle->get(), SW_SHOWNORMAL);
|
// TODO: Should this be done before reparenting and mapping?
|
||||||
// TODO: We should just immediatly resize the window to the right size
|
ShowWindow(win32_handle->get(), SW_SHOW);
|
||||||
// isntead
|
|
||||||
UpdateWindow(win32_handle->get());
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,4 +84,5 @@ class Editor {
|
|||||||
win32_handle;
|
win32_handle;
|
||||||
|
|
||||||
std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> x11_connection;
|
std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> x11_connection;
|
||||||
|
xcb_atom_t xcb_xembed_info;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user