WINGs: add Phase D vtable slots, port wballoon.c
Adds window_set_title, window_realize, window_set_geometry, window_withdraw, pointer_grab, pointer_ungrab, bell, balloon_draw slots to W_ViewBackend. Ports wballoon.c: - XTranslateCoordinates replaced with get_screen_position vtable - showText replaced with balloon_draw vtable dispatch - X11 backend calls existing rendering code - Wayland backend is no-op (WM-level balloon handles dock tooltips)
This commit is contained in:
parent
eeda48d24e
commit
11c5625d1e
|
|
@ -636,6 +636,20 @@ typedef struct W_ViewBackend {
|
|||
|
||||
/* Drag and drop */
|
||||
void (*drag_begin)(void *vctx, struct W_View *view, WMEvent *event);
|
||||
|
||||
/* Window properties (ICCCM/EWMH) — X11 sets properties, Wayland no-ops */
|
||||
void (*window_set_title)(void *vctx, struct W_View *view, const char *title);
|
||||
void (*window_set_icon_title)(void *vctx, struct W_View *view, const char *title);
|
||||
void (*window_set_icon_image)(void *vctx, struct W_View *view, RImage *image);
|
||||
void (*window_realize)(void *vctx, struct W_View *view, const char *name,
|
||||
const char *class, struct W_View *owner);
|
||||
void (*window_set_geometry)(void *vctx, struct W_View *view);
|
||||
void (*window_withdraw)(void *vctx, struct W_View *view);
|
||||
void (*pointer_grab)(void *vctx, struct W_View *view, int owner_events, unsigned long time);
|
||||
void (*pointer_ungrab)(void *vctx, unsigned long time);
|
||||
void (*bell)(void *vctx);
|
||||
void (*balloon_draw)(void *vctx, struct W_View *view, int x, int y,
|
||||
int w, int h, const char *text);
|
||||
} W_ViewBackend;
|
||||
|
||||
extern const W_ViewBackend W_ViewBackendX11;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ static void destroyBalloon(Balloon * bPtr);
|
|||
|
||||
static void handleEvents(WMEvent * event, void *data);
|
||||
|
||||
static void showText(Balloon * bPtr, int x, int y, int w, int h, const char *text);
|
||||
void W_BalloonShowText(void *bPtr, int x, int y, int w, int h, const char *text);
|
||||
|
||||
struct W_Balloon *W_CreateBalloon(WMScreen * scr)
|
||||
{
|
||||
|
|
@ -171,7 +171,6 @@ static void showBalloon(void *data)
|
|||
WMView *view = (WMView *) data;
|
||||
Balloon *bPtr = view->screen->balloon;
|
||||
int x, y;
|
||||
Window foo;
|
||||
|
||||
bPtr->timer = NULL;
|
||||
|
||||
|
|
@ -179,12 +178,19 @@ static void showBalloon(void *data)
|
|||
if (!text)
|
||||
return;
|
||||
|
||||
XTranslateCoordinates(view->screen->display, view->window, view->screen->rootWin, 0, 0, &x, &y, &foo);
|
||||
{
|
||||
WMPoint pos = view->screen->viewBackend->get_screen_position(
|
||||
view->screen->viewBackendCtx, view);
|
||||
x = pos.x;
|
||||
y = pos.y;
|
||||
}
|
||||
|
||||
if (!bPtr->view->flags.realized)
|
||||
W_RealizeView(bPtr->view);
|
||||
|
||||
showText(bPtr, x, y, view->size.width, view->size.height, text);
|
||||
view->screen->viewBackend->balloon_draw(
|
||||
view->screen->viewBackendCtx, bPtr->view,
|
||||
x, y, view->size.width, view->size.height, text);
|
||||
|
||||
bPtr->flags.noDelay = 1;
|
||||
}
|
||||
|
|
@ -356,8 +362,9 @@ static Pixmap makePixmap(WMScreen * scr, int width, int height, int side, Pixmap
|
|||
return pixmap;
|
||||
}
|
||||
|
||||
static void showText(Balloon * bPtr, int x, int y, int w, int h, const char *text)
|
||||
void W_BalloonShowText(void *bPtr_v, int x, int y, int w, int h, const char *text)
|
||||
{
|
||||
Balloon *bPtr = (Balloon *)bPtr_v;
|
||||
WMScreen *scr = bPtr->view->screen;
|
||||
Display *dpy = WMScreenDisplay(scr);
|
||||
int width;
|
||||
|
|
|
|||
|
|
@ -531,6 +531,12 @@ static char *wl_clipboard_fetch(void *vctx, int *len_out)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void wl_balloon_draw(void *vctx, W_View *view, int x, int y,
|
||||
int w, int h, const char *text)
|
||||
{
|
||||
(void)vctx; (void)view; (void)x; (void)y; (void)w; (void)h; (void)text;
|
||||
}
|
||||
|
||||
static void wl_drag_begin(void *vctx, W_View *view, WMEvent *event)
|
||||
{
|
||||
(void)vctx; (void)view; (void)event;
|
||||
|
|
@ -567,4 +573,14 @@ const W_ViewBackend W_ViewBackendWL = {
|
|||
.clipboard_store = wl_clipboard_store,
|
||||
.clipboard_fetch = wl_clipboard_fetch,
|
||||
.drag_begin = wl_drag_begin,
|
||||
.window_set_title = NULL,
|
||||
.window_set_icon_title = NULL,
|
||||
.window_set_icon_image = NULL,
|
||||
.window_realize = NULL,
|
||||
.window_set_geometry = NULL,
|
||||
.window_withdraw = NULL,
|
||||
.pointer_grab = NULL,
|
||||
.pointer_ungrab = NULL,
|
||||
.bell = NULL,
|
||||
.balloon_draw = wl_balloon_draw,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@
|
|||
*/
|
||||
|
||||
#include "WINGsP.h"
|
||||
#include "wwindow_p.h"
|
||||
#include <X11/Xresource.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include "../src/GNUstep.h"
|
||||
|
||||
extern void W_X11PlatformInit(W_Screen *scr);
|
||||
|
||||
|
|
@ -231,12 +234,244 @@ static char *x11_clipboard_fetch(void *vctx, int *len_out)
|
|||
return copy;
|
||||
}
|
||||
|
||||
static void x11_balloon_draw(void *vctx, W_View *view, int x, int y,
|
||||
int w, int h, const char *text)
|
||||
{
|
||||
W_Screen *scr = (W_Screen *)vctx;
|
||||
(void)scr;
|
||||
extern void W_BalloonShowText(void *bPtr, int x, int y, int w, int h, const char *text);
|
||||
W_BalloonShowText(view->screen->balloon, x, y, w, h, text);
|
||||
}
|
||||
|
||||
static void x11_flush(void *vctx)
|
||||
{
|
||||
W_Screen *scr = (W_Screen *)vctx;
|
||||
XFlush(scr->display);
|
||||
}
|
||||
|
||||
static void x11_window_set_title(void *vctx, W_View *view, const char *title)
|
||||
{
|
||||
W_Screen *scr = (W_Screen *)vctx;
|
||||
XTextProperty property;
|
||||
int result;
|
||||
|
||||
result = XmbTextListToTextProperty(scr->display, (char **)&title, 1, XStdICCTextStyle, &property);
|
||||
if (result == XNoMemory || result == XLocaleNotSupported) {
|
||||
XStoreName(scr->display, view->window, title);
|
||||
} else {
|
||||
XSetWMName(scr->display, view->window, &property);
|
||||
if (property.value)
|
||||
XFree(property.value);
|
||||
}
|
||||
|
||||
XChangeProperty(scr->display, view->window,
|
||||
scr->netwmName, scr->utf8String, 8,
|
||||
PropModeReplace, (unsigned char *)title, strlen(title));
|
||||
}
|
||||
|
||||
static void x11_window_set_icon_title(void *vctx, W_View *view, const char *title)
|
||||
{
|
||||
W_Screen *scr = (W_Screen *)vctx;
|
||||
XTextProperty property;
|
||||
int result;
|
||||
|
||||
result = XmbTextListToTextProperty(scr->display, (char **)&title, 1, XStdICCTextStyle, &property);
|
||||
if (result == XNoMemory || result == XLocaleNotSupported) {
|
||||
XSetIconName(scr->display, view->window, title);
|
||||
} else {
|
||||
XSetWMIconName(scr->display, view->window, &property);
|
||||
if (property.value)
|
||||
XFree(property.value);
|
||||
}
|
||||
|
||||
XChangeProperty(scr->display, view->window,
|
||||
scr->netwmIconName, scr->utf8String, 8,
|
||||
PropModeReplace, (unsigned char *)title, strlen(title));
|
||||
}
|
||||
|
||||
static void x11_window_set_icon_image(void *vctx, W_View *view, RImage *image)
|
||||
{
|
||||
W_Screen *scr = (W_Screen *)vctx;
|
||||
unsigned long *data;
|
||||
int x, y, o;
|
||||
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
data = wmalloc((image->width * image->height + 2) * sizeof(long));
|
||||
|
||||
o = 0;
|
||||
data[o++] = image->width;
|
||||
data[o++] = image->height;
|
||||
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
unsigned long pixel;
|
||||
int offs = (x + y * image->width);
|
||||
|
||||
if (image->format == RRGBFormat) {
|
||||
pixel = ((unsigned long) image->data[offs * 3 ]) << 16;
|
||||
pixel |= ((unsigned long) image->data[offs * 3 + 1]) << 8;
|
||||
pixel |= ((unsigned long) image->data[offs * 3 + 2]);
|
||||
} else {
|
||||
pixel = ((unsigned long) image->data[offs * 4 ]) << 16;
|
||||
pixel |= ((unsigned long) image->data[offs * 4 + 1]) << 8;
|
||||
pixel |= ((unsigned long) image->data[offs * 4 + 2]);
|
||||
pixel |= ((unsigned long) image->data[offs * 4 + 3]) << 24;
|
||||
}
|
||||
|
||||
data[o++] = pixel;
|
||||
}
|
||||
}
|
||||
|
||||
XChangeProperty(scr->display, view->window, scr->netwmIcon,
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
(unsigned char *)data, (image->width * image->height + 2));
|
||||
|
||||
wfree(data);
|
||||
}
|
||||
|
||||
static void x11_writeGNUstepWMAttr(W_Screen *scr, Window window, GNUstepWMAttributes *attr)
|
||||
{
|
||||
unsigned long data[9];
|
||||
|
||||
data[0] = attr->flags;
|
||||
data[1] = attr->window_style;
|
||||
data[2] = attr->window_level;
|
||||
data[3] = 0;
|
||||
data[4] = attr->miniaturize_pixmap;
|
||||
data[5] = attr->close_pixmap;
|
||||
data[6] = attr->miniaturize_mask;
|
||||
data[7] = attr->close_mask;
|
||||
data[8] = attr->extra_flags;
|
||||
XChangeProperty(scr->display, window, scr->attribsAtom, scr->attribsAtom,
|
||||
32, PropModeReplace, (unsigned char *)data, 9);
|
||||
}
|
||||
|
||||
static void x11_window_realize(void *vctx, W_View *view, const char *name,
|
||||
const char *class, W_View *owner)
|
||||
{
|
||||
W_Screen *scr = (W_Screen *)vctx;
|
||||
_Window *win = (_Window *)view->self;
|
||||
XWMHints *hints;
|
||||
XClassHint *classHint;
|
||||
Atom atoms[4];
|
||||
int count;
|
||||
GNUstepWMAttributes attribs;
|
||||
|
||||
classHint = XAllocClassHint();
|
||||
classHint->res_name = (char *)name;
|
||||
classHint->res_class = (char *)class;
|
||||
XSetClassHint(scr->display, view->window, classHint);
|
||||
XFree(classHint);
|
||||
|
||||
hints = XAllocWMHints();
|
||||
hints->flags = 0;
|
||||
if (!scr->aflags.simpleApplication) {
|
||||
hints->flags |= WindowGroupHint;
|
||||
hints->window_group = scr->groupLeader;
|
||||
}
|
||||
if (win->miniImage) {
|
||||
hints->flags |= IconPixmapHint;
|
||||
hints->icon_pixmap = WMGetPixmapXID(win->miniImage);
|
||||
hints->icon_mask = WMGetPixmapMaskXID(win->miniImage);
|
||||
if (hints->icon_mask != None) {
|
||||
hints->flags |= IconMaskHint;
|
||||
}
|
||||
}
|
||||
if (hints->flags != 0)
|
||||
XSetWMHints(scr->display, view->window, hints);
|
||||
XFree(hints);
|
||||
|
||||
count = 0;
|
||||
if (win->closeAction)
|
||||
atoms[count++] = scr->deleteWindowAtom;
|
||||
if (count > 0)
|
||||
XSetWMProtocols(scr->display, view->window, atoms, count);
|
||||
|
||||
if (win->title || win->miniTitle)
|
||||
XmbSetWMProperties(scr->display, view->window, win->title,
|
||||
win->miniTitle, NULL, 0, NULL, NULL, NULL);
|
||||
|
||||
/* GNUstep/Window Maker attributes */
|
||||
memset(&attribs, 0, sizeof(GNUstepWMAttributes));
|
||||
attribs.flags = GSWindowStyleAttr | GSWindowLevelAttr | GSExtraFlagsAttr;
|
||||
if (win->minSize.width == win->maxSize.width && win->minSize.height == win->maxSize.height)
|
||||
win->flags.style &= ~WMResizableWindowMask;
|
||||
attribs.window_style = win->flags.style;
|
||||
attribs.window_level = win->level;
|
||||
attribs.extra_flags = win->flags.documentEdited ? GSDocumentEditedFlag : 0;
|
||||
x11_writeGNUstepWMAttr(scr, view->window, &attribs);
|
||||
|
||||
if (owner)
|
||||
XSetTransientForHint(scr->display, view->window, owner->window);
|
||||
|
||||
if (win->title)
|
||||
x11_window_set_title(vctx, view, win->title);
|
||||
}
|
||||
|
||||
static void x11_window_set_geometry(void *vctx, W_View *view)
|
||||
{
|
||||
W_Screen *scr = (W_Screen *)vctx;
|
||||
_Window *win = (_Window *)view->self;
|
||||
XSizeHints *hints;
|
||||
|
||||
hints = XAllocSizeHints();
|
||||
if (!hints)
|
||||
return;
|
||||
|
||||
hints->flags = 0;
|
||||
|
||||
if (win->flags.setPPos) {
|
||||
hints->flags |= PPosition;
|
||||
hints->x = win->ppos.x;
|
||||
hints->y = win->ppos.y;
|
||||
}
|
||||
if (win->flags.setUPos) {
|
||||
hints->flags |= USPosition;
|
||||
hints->x = win->upos.x;
|
||||
hints->y = win->upos.y;
|
||||
}
|
||||
if (win->minSize.width > 0 && win->minSize.height > 0) {
|
||||
hints->flags |= PMinSize;
|
||||
hints->min_width = win->minSize.width;
|
||||
hints->min_height = win->minSize.height;
|
||||
}
|
||||
if (win->maxSize.width > 0 && win->maxSize.height > 0) {
|
||||
hints->flags |= PMaxSize;
|
||||
hints->max_width = win->maxSize.width;
|
||||
hints->max_height = win->maxSize.height;
|
||||
}
|
||||
if (win->baseSize.width > 0 && win->baseSize.height > 0) {
|
||||
hints->flags |= PBaseSize;
|
||||
hints->base_width = win->baseSize.width;
|
||||
hints->base_height = win->baseSize.height;
|
||||
}
|
||||
if (win->resizeIncrement.width > 0 && win->resizeIncrement.height > 0) {
|
||||
hints->flags |= PResizeInc;
|
||||
hints->width_inc = win->resizeIncrement.width;
|
||||
hints->height_inc = win->resizeIncrement.height;
|
||||
}
|
||||
if (win->flags.setAspect) {
|
||||
hints->flags |= PAspect;
|
||||
hints->min_aspect.x = win->minAspect.x;
|
||||
hints->min_aspect.y = win->minAspect.y;
|
||||
hints->max_aspect.x = win->maxAspect.x;
|
||||
hints->max_aspect.y = win->maxAspect.y;
|
||||
}
|
||||
|
||||
if (hints->flags)
|
||||
XSetWMNormalHints(scr->display, view->window, hints);
|
||||
XFree(hints);
|
||||
}
|
||||
|
||||
static void x11_window_withdraw(void *vctx, W_View *view)
|
||||
{
|
||||
W_Screen *scr = (W_Screen *)vctx;
|
||||
|
||||
XWithdrawWindow(scr->display, view->window, scr->screen);
|
||||
}
|
||||
|
||||
const W_ViewBackend W_ViewBackendX11 = {
|
||||
.screen_init = x11_screen_init,
|
||||
.screen_fini = x11_screen_fini,
|
||||
|
|
@ -263,4 +498,14 @@ const W_ViewBackend W_ViewBackendX11 = {
|
|||
.clipboard_store = x11_clipboard_store,
|
||||
.clipboard_fetch = x11_clipboard_fetch,
|
||||
.drag_begin = NULL,
|
||||
.window_set_title = NULL,
|
||||
.window_set_icon_title = NULL,
|
||||
.window_set_icon_image = NULL,
|
||||
.window_realize = NULL,
|
||||
.window_set_geometry = NULL,
|
||||
.window_withdraw = NULL,
|
||||
.pointer_grab = NULL,
|
||||
.pointer_ungrab = NULL,
|
||||
.bell = NULL,
|
||||
.balloon_draw = x11_balloon_draw,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue