mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-23 11:51:27 +00:00
wayland backend: delayed toplevel creation
This commit is contained in:
parent
3227b39c58
commit
c6ce795898
3 changed files with 117 additions and 74 deletions
|
@ -107,6 +107,7 @@ struct window {
|
||||||
int window_id;
|
int window_id;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
BOOL configured; // surface has been configured once
|
BOOL configured; // surface has been configured once
|
||||||
|
BOOL buffer_needs_attach; // surface has been configured once
|
||||||
|
|
||||||
float pos_x;
|
float pos_x;
|
||||||
float pos_y;
|
float pos_y;
|
||||||
|
|
|
@ -141,12 +141,20 @@ create_shm_buffer(struct window *window)
|
||||||
gsDevice = device;
|
gsDevice = device;
|
||||||
|
|
||||||
_surface = create_shm_buffer(window);
|
_surface = create_shm_buffer(window);
|
||||||
|
window->buffer_needs_attach = YES;
|
||||||
if (_surface == NULL) {
|
if (_surface == NULL) {
|
||||||
NSDebugLog(@"can't create cairo surface");
|
NSDebugLog(@"can't create cairo surface");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_attach(window->surface, window->buffer, 0, 0);
|
if(window->toplevel != NULL && window->configured) {
|
||||||
|
// if the window has a toplevel then it should appear on screen
|
||||||
|
// we can attach a buffer only if the xdg surface is configured
|
||||||
|
NSDebugLog(@"wl_surface_attach: win=%d toplevel_surface", window->window_id);
|
||||||
|
window->buffer_needs_attach = NO;
|
||||||
|
wl_surface_attach(window->surface, window->buffer, 0, 0);
|
||||||
|
wl_surface_commit(window->surface);
|
||||||
|
}
|
||||||
window->wcs = self;
|
window->wcs = self;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -176,7 +184,7 @@ create_shm_buffer(struct window *window)
|
||||||
|
|
||||||
- (NSSize) size
|
- (NSSize) size
|
||||||
{
|
{
|
||||||
NSDebugLog(@"WaylandCairoSurface: size");
|
// NSDebugLog(@"WaylandCairoSurface: size");
|
||||||
struct window *window = (struct window*) gsDevice;
|
struct window *window = (struct window*) gsDevice;
|
||||||
return NSMakeSize(window->width, window->height);
|
return NSMakeSize(window->width, window->height);
|
||||||
}
|
}
|
||||||
|
@ -189,7 +197,7 @@ create_shm_buffer(struct window *window)
|
||||||
|
|
||||||
- (void) handleExposeRect: (NSRect)rect
|
- (void) handleExposeRect: (NSRect)rect
|
||||||
{
|
{
|
||||||
NSDebugLog(@"handleExposeRect");
|
NSDebugLog(@"[CairoSurface handleExposeRect]");
|
||||||
struct window *window = (struct window*) gsDevice;
|
struct window *window = (struct window*) gsDevice;
|
||||||
cairo_surface_t *cairo_surface = _surface;
|
cairo_surface_t *cairo_surface = _surface;
|
||||||
double backupOffsetX = 0;
|
double backupOffsetX = 0;
|
||||||
|
@ -199,39 +207,28 @@ create_shm_buffer(struct window *window)
|
||||||
int width = NSWidth(rect);
|
int width = NSWidth(rect);
|
||||||
int height = NSHeight(rect);
|
int height = NSHeight(rect);
|
||||||
|
|
||||||
NSDebugLog(@"updating region: %dx%d %dx%d", x, y, width, height);
|
NSDebugLog(@"...updating region: %dx%d %dx%d", x, y, width, height);
|
||||||
|
|
||||||
if (cairo_surface_status(cairo_surface) != CAIRO_STATUS_SUCCESS)
|
if (cairo_surface_status(cairo_surface) != CAIRO_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
NSWarnMLog(@"cairo initial window error status: %s\n",
|
NSWarnMLog(@"...cairo initial window error status: %s\n",
|
||||||
cairo_status_to_string(cairo_surface_status(_surface)));
|
cairo_status_to_string(cairo_surface_status(_surface)));
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_surface_get_device_offset(cairo_surface, &backupOffsetX, &backupOffsetY);
|
if (window->configured) {
|
||||||
cairo_surface_set_device_offset(cairo_surface, 0, 0);
|
if(window->buffer_needs_attach) {
|
||||||
|
window->buffer_needs_attach = NO;
|
||||||
|
wl_surface_attach(window->surface, window->buffer, 0, 0);
|
||||||
|
}
|
||||||
|
wl_surface_damage(window->surface, 0, 0, width, height);
|
||||||
|
wl_surface_commit(window->surface);
|
||||||
|
//wl_display_dispatch_pending(window->wlconfig->display);
|
||||||
|
//wl_display_flush(window->wlconfig->display);
|
||||||
|
} else {
|
||||||
|
window->buffer_needs_attach = YES;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: This seems to be creating a context to paint into cairo_surface,
|
NSDebugLog(@"[CairoSurface handleExposeRect end]");
|
||||||
// and then copies back into the same cairo_surface.
|
|
||||||
cairo_t *cr = cairo_create(cairo_surface);
|
|
||||||
|
|
||||||
cairo_rectangle(cr, x, y, width, height);
|
|
||||||
cairo_clip(cr);
|
|
||||||
cairo_set_source_surface(cr, cairo_surface, 0, 0);
|
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
|
||||||
cairo_paint(cr);
|
|
||||||
|
|
||||||
cairo_destroy(cr);
|
|
||||||
|
|
||||||
NSDebugLog(@"trying to commit cairo surface for window %d", window->window_id);
|
|
||||||
if (window->configured)
|
|
||||||
wl_surface_commit(window->surface);
|
|
||||||
NSDebugLog(@"done trying to commit cairo surface for window %d", window->window_id);
|
|
||||||
wl_display_dispatch_pending(window->wlconfig->display);
|
|
||||||
wl_display_flush(window->wlconfig->display);
|
|
||||||
|
|
||||||
cairo_surface_set_device_offset(_surface, backupOffsetX, backupOffsetY);
|
|
||||||
|
|
||||||
NSDebugLog(@"handleExposeRect exit");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -689,14 +689,12 @@ xdg_surface_on_configure(void *data, struct xdg_surface *xdg_surface,
|
||||||
xdg_surface_ack_configure(xdg_surface, serial);
|
xdg_surface_ack_configure(xdg_surface, serial);
|
||||||
window->configured = YES;
|
window->configured = YES;
|
||||||
|
|
||||||
// TODO: do we need to check that the surface has been painted to?
|
|
||||||
if (window->surface)
|
if(window->buffer_needs_attach) {
|
||||||
{
|
NSDebugLog(@"attach: win=%d toplevel", window->window_id);
|
||||||
// TODO: is this ever going to be null when we get here?
|
wl_surface_attach(window->surface, window->buffer, 0, 0);
|
||||||
wl_surface_commit(window->surface);
|
wl_surface_commit(window->surface);
|
||||||
wl_display_dispatch_pending(window->wlconfig->display);
|
}
|
||||||
wl_display_flush(window->wlconfig->display);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (wlconfig->pointer.focus &&
|
if (wlconfig->pointer.focus &&
|
||||||
|
@ -1081,35 +1079,23 @@ int NSToWayland(struct window *window, int ns_y)
|
||||||
window->pos_x = frame.origin.x;
|
window->pos_x = frame.origin.x;
|
||||||
window->pos_y = NSToWayland(window, frame.origin.y);
|
window->pos_y = NSToWayland(window, frame.origin.y);
|
||||||
window->window_id = wlconfig->last_window_id;
|
window->window_id = wlconfig->last_window_id;
|
||||||
window->surface = wl_compositor_create_surface(wlconfig->compositor);
|
window->xdg_surface = NULL;
|
||||||
if (!window->surface) {
|
window->toplevel = NULL;
|
||||||
NSDebugLog(@"can't create wayland surface");
|
window->configured = NO;
|
||||||
free(window);
|
window->buffer_needs_attach = NO;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
wl_surface_set_user_data(window->surface, window);
|
|
||||||
|
|
||||||
window->xdg_surface =
|
|
||||||
xdg_wm_base_get_xdg_surface(wlconfig->wm_base, window->surface);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// TODO: xdg_shell_get_xdg_surface_special() no longer exists,
|
if (style & NSMiniWindowMask) {
|
||||||
// so we need to find another way, see *get_popup for menus
|
NSDebugLog(@"window id=%d will be a NSMiniWindowMask", window->window_id);
|
||||||
if (style & NSMainMenuWindowMask) {
|
} else if (style & NSIconWindowMask) {
|
||||||
NSDebugLog(@"window id=%d will be a panel", window->window_id);
|
NSDebugLog(@"window id=%d will be a NSIconWindowMask", window->window_id);
|
||||||
} else if (style & NSBackgroundWindowMask) {
|
} else if (style & NSBorderlessWindowMask) {
|
||||||
NSDebugLog(@"window id=%d will be a ?", window->window_id);
|
NSDebugLog(@"window id=%d will be a NSBorderlessWindowMask", window->window_id);
|
||||||
} else {
|
} else {
|
||||||
NSDebugLog(@"window id=%d will be ordinary", window->window_id);
|
NSDebugLog(@"window id=%d will be ordinary", window->window_id);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
window->toplevel = xdg_surface_get_toplevel(window->xdg_surface);
|
|
||||||
|
|
||||||
xdg_surface_set_user_data(window->xdg_surface, window);
|
|
||||||
xdg_surface_add_listener(window->xdg_surface,
|
|
||||||
&xdg_surface_listener, window);
|
|
||||||
|
|
||||||
if (window->pos_x < 0) {
|
if (window->pos_x < 0) {
|
||||||
window->pos_x = 0;
|
window->pos_x = 0;
|
||||||
altered = 1;
|
altered = 1;
|
||||||
|
@ -1125,18 +1111,13 @@ int NSToWayland(struct window *window, int ns_y)
|
||||||
NSDebugLog(@"creating new window with id=%d: pos=%fx%f, size=%fx%f",
|
NSDebugLog(@"creating new window with id=%d: pos=%fx%f, size=%fx%f",
|
||||||
window->window_id, window->pos_x, window->pos_y,
|
window->window_id, window->pos_x, window->pos_y,
|
||||||
window->width, window->height);
|
window->width, window->height);
|
||||||
xdg_surface_set_window_geometry(window->xdg_surface,
|
|
||||||
window->pos_x,
|
|
||||||
window->pos_y,
|
|
||||||
window->width,
|
|
||||||
window->height);
|
|
||||||
wl_surface_commit(window->surface);
|
|
||||||
wl_display_flush(wlconfig->display);
|
|
||||||
|
|
||||||
wl_list_insert(wlconfig->window_list.prev, &window->link);
|
wl_list_insert(wlconfig->window_list.prev, &window->link);
|
||||||
wlconfig->last_window_id++;
|
wlconfig->last_window_id++;
|
||||||
wlconfig->window_count++;
|
wlconfig->window_count++;
|
||||||
|
|
||||||
|
|
||||||
|
// creates a buffer for the window
|
||||||
[self _setWindowOwnedByServer: (int)window->window_id];
|
[self _setWindowOwnedByServer: (int)window->window_id];
|
||||||
|
|
||||||
if (altered) {
|
if (altered) {
|
||||||
|
@ -1156,7 +1137,49 @@ int NSToWayland(struct window *window, int ns_y)
|
||||||
|
|
||||||
return window->window_id;
|
return window->window_id;
|
||||||
}
|
}
|
||||||
|
- (void) makeWindowTopLevel: (int) win
|
||||||
|
{
|
||||||
|
NSDebugLog(@"makeWindowTopLevel");
|
||||||
|
|
||||||
|
struct window *window = get_window_with_id(wlconfig, win);
|
||||||
|
window->surface = wl_compositor_create_surface(wlconfig->compositor);
|
||||||
|
if (!window->surface) {
|
||||||
|
NSDebugLog(@"can't create wayland surface");
|
||||||
|
free(window);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wl_surface_set_user_data(window->surface, window);
|
||||||
|
window->xdg_surface =
|
||||||
|
xdg_wm_base_get_xdg_surface(wlconfig->wm_base, window->surface);
|
||||||
|
window->toplevel = xdg_surface_get_toplevel(window->xdg_surface);
|
||||||
|
xdg_surface_add_listener(window->xdg_surface,
|
||||||
|
&xdg_surface_listener, window);
|
||||||
|
|
||||||
|
xdg_surface_set_window_geometry(window->xdg_surface,
|
||||||
|
window->pos_x,
|
||||||
|
window->pos_y,
|
||||||
|
window->width,
|
||||||
|
window->height);
|
||||||
|
|
||||||
|
NSDebugLog(@"wl_surface_commit: win=%d toplevel", window->window_id);
|
||||||
|
wl_surface_commit(window->surface);
|
||||||
|
wl_display_dispatch_pending(window->wlconfig->display);
|
||||||
|
wl_display_flush(window->wlconfig->display);
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// TODO: xdg_shell_get_xdg_surface_special() no longer exists,
|
||||||
|
// so we need to find another way, see *get_popup for menus
|
||||||
|
if (style & NSMainMenuWindowMask) {
|
||||||
|
NSDebugLog(@"window id=%d will be a panel", window->window_id);
|
||||||
|
} else if (style & NSBackgroundWindowMask) {
|
||||||
|
NSDebugLog(@"window id=%d will be a ?", window->window_id);
|
||||||
|
} else {
|
||||||
|
NSDebugLog(@"window id=%d will be ordinary", window->window_id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
- (void) termwindow: (int) win
|
- (void) termwindow: (int) win
|
||||||
{
|
{
|
||||||
NSDebugLog(@"termwindow: win=%d", win);
|
NSDebugLog(@"termwindow: win=%d", win);
|
||||||
|
@ -1199,7 +1222,8 @@ int NSToWayland(struct window *window, int ns_y)
|
||||||
struct window *window = get_window_with_id(wlconfig, win);
|
struct window *window = get_window_with_id(wlconfig, win);
|
||||||
const char *cString = [window_title UTF8String];
|
const char *cString = [window_title UTF8String];
|
||||||
|
|
||||||
xdg_toplevel_set_title(window->toplevel, cString);
|
if(window->toplevel)
|
||||||
|
xdg_toplevel_set_title(window->toplevel, cString);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) miniwindow: (int) win
|
- (void) miniwindow: (int) win
|
||||||
|
@ -1210,6 +1234,8 @@ int NSToWayland(struct window *window, int ns_y)
|
||||||
|
|
||||||
- (void) setWindowdevice: (int) winId forContext: (NSGraphicsContext *)ctxt
|
- (void) setWindowdevice: (int) winId forContext: (NSGraphicsContext *)ctxt
|
||||||
{
|
{
|
||||||
|
// creates a new shm buffer
|
||||||
|
NSDebugLog(@"creating a new shm buffer: %d", winId);
|
||||||
NSDebugLog(@"setWindowdevice: %d", winId);
|
NSDebugLog(@"setWindowdevice: %d", winId);
|
||||||
struct window *window;
|
struct window *window;
|
||||||
|
|
||||||
|
@ -1228,21 +1254,28 @@ int NSToWayland(struct window *window, int ns_y)
|
||||||
if (op == NSWindowOut) {
|
if (op == NSWindowOut) {
|
||||||
NSDebugLog(@"orderwindow: NSWindowOut");
|
NSDebugLog(@"orderwindow: NSWindowOut");
|
||||||
window->is_out = 1;
|
window->is_out = 1;
|
||||||
|
if(window->xdg_surface) {
|
||||||
xdg_surface_set_window_geometry(window->xdg_surface,
|
xdg_surface_set_window_geometry(window->xdg_surface,
|
||||||
window->pos_x + 32000,
|
window->pos_x + 32000,
|
||||||
window->pos_y + 32000,
|
window->pos_y + 32000,
|
||||||
window->width,
|
window->width,
|
||||||
window->height);
|
window->height);
|
||||||
|
}
|
||||||
NSRect rect = NSMakeRect(0, 0,
|
NSRect rect = NSMakeRect(0, 0,
|
||||||
window->width, window->height);
|
window->width, window->height);
|
||||||
[window->instance flushwindowrect:rect :window->window_id];
|
[window->instance flushwindowrect:rect :window->window_id];
|
||||||
|
if(window->toplevel != NULL) {
|
||||||
|
xdg_toplevel_set_minimized(window->toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
xdg_toplevel_set_minimized(window->toplevel);
|
|
||||||
|
|
||||||
wl_display_dispatch_pending(window->wlconfig->display);
|
wl_display_dispatch_pending(window->wlconfig->display);
|
||||||
wl_display_flush(window->wlconfig->display);
|
wl_display_flush(window->wlconfig->display);
|
||||||
} else /*if (window->is_out)*/ {
|
} else /*if (window->is_out)*/ {
|
||||||
NSDebugLog(@"orderwindow: restoring to %fx%f", window->pos_x, window->pos_y);
|
if(window->toplevel == NULL) {
|
||||||
|
[self makeWindowTopLevel: win];
|
||||||
|
}
|
||||||
|
NSDebugLog(@"orderwindow: %d restoring to %fx%f", win, window->pos_x, window->pos_y);
|
||||||
xdg_surface_set_window_geometry(window->xdg_surface,
|
xdg_surface_set_window_geometry(window->xdg_surface,
|
||||||
window->pos_x,
|
window->pos_x,
|
||||||
window->pos_y,
|
window->pos_y,
|
||||||
|
@ -1325,10 +1358,13 @@ int NSToWayland(struct window *window, int ns_y)
|
||||||
|
|
||||||
[GSCurrentServer() postEvent: event atStart: NO];
|
[GSCurrentServer() postEvent: event atStart: NO];
|
||||||
|
|
||||||
xdg_toplevel_move(window->toplevel,
|
//xdg_toplevel_move(window->toplevel,
|
||||||
config->seat,
|
// config->seat,
|
||||||
config->pointer.serial);
|
// config->pointer.serial);
|
||||||
} else {
|
} else {
|
||||||
|
if(window->toplevel == NULL) {
|
||||||
|
[self makeWindowTopLevel: win];
|
||||||
|
}
|
||||||
NSDebugLog(@"placewindow: oldpos=%fx%f", window->pos_x, window->pos_y);
|
NSDebugLog(@"placewindow: oldpos=%fx%f", window->pos_x, window->pos_y);
|
||||||
NSDebugLog(@"placewindow: oldsize=%fx%f", window->width, window->height);
|
NSDebugLog(@"placewindow: oldsize=%fx%f", window->width, window->height);
|
||||||
NSRect frame;
|
NSRect frame;
|
||||||
|
@ -1384,8 +1420,10 @@ int NSToWayland(struct window *window, int ns_y)
|
||||||
subtype: GSAppKitWindowResized
|
subtype: GSAppKitWindowResized
|
||||||
data1: rect.size.width
|
data1: rect.size.width
|
||||||
data2: rect.size.height];
|
data2: rect.size.height];
|
||||||
|
NSDebugLog(@"notify resize=%fx%f", rect.size.width, rect.size.height);
|
||||||
[(GSWindowWithNumber(window->window_id)) sendEvent: ev];
|
[(GSWindowWithNumber(window->window_id)) sendEvent: ev];
|
||||||
NSDebugLog(@"placewindow notify resized=%fx%f", rect.size.width, rect.size.height);
|
NSDebugLog(@"notified resize=%fx%f", rect.size.width, rect.size.height);
|
||||||
|
// we have a new buffer
|
||||||
} else if (move == YES) {
|
} else if (move == YES) {
|
||||||
NSEvent *ev = [NSEvent otherEventWithType: NSAppKitDefined
|
NSEvent *ev = [NSEvent otherEventWithType: NSAppKitDefined
|
||||||
location: NSZeroPoint
|
location: NSZeroPoint
|
||||||
|
@ -1454,6 +1492,7 @@ int NSToWayland(struct window *window, int ns_y)
|
||||||
struct window *window = get_window_with_id(wlconfig, win);
|
struct window *window = get_window_with_id(wlconfig, win);
|
||||||
|
|
||||||
[[GSCurrentContext() class] handleExposeRect: rect forDriver: window->wcs];
|
[[GSCurrentContext() class] handleExposeRect: rect forDriver: window->wcs];
|
||||||
|
// [(CairoSurface *)driver handleExposeRect: rect];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) styleoffsets: (float*) l : (float*) r : (float*) t : (float*) b
|
- (void) styleoffsets: (float*) l : (float*) r : (float*) t : (float*) b
|
||||||
|
@ -1612,10 +1651,16 @@ int NSToWayland(struct window *window, int ns_y)
|
||||||
struct window *parent = get_window_with_id(wlconfig, parentWin);
|
struct window *parent = get_window_with_id(wlconfig, parentWin);
|
||||||
struct window *child = get_window_with_id(wlconfig, childWin);
|
struct window *child = get_window_with_id(wlconfig, childWin);
|
||||||
|
|
||||||
|
if(!child->toplevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (parent) {
|
if (parent) {
|
||||||
xdg_toplevel_set_parent(child->toplevel, parent->toplevel);
|
if(!parent->toplevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xdg_toplevel_set_parent(child->toplevel, parent->toplevel);
|
||||||
} else {
|
} else {
|
||||||
xdg_toplevel_set_parent(child->toplevel, NULL);
|
xdg_toplevel_set_parent(child->toplevel, NULL);
|
||||||
}
|
}
|
||||||
xdg_toplevel_set_minimized(child->toplevel);
|
xdg_toplevel_set_minimized(child->toplevel);
|
||||||
wl_display_dispatch_pending(wlconfig->display);
|
wl_display_dispatch_pending(wlconfig->display);
|
||||||
|
|
Loading…
Reference in a new issue