From 3dcab961803ad534f68911711646a85c47f2e95c Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Apr 2003 03:34:43 +0000 Subject: [PATCH] - Support for multiline balloons (Vitaly Ovtchinnikov ) --- ChangeLog | 1 + src/balloon.c | 474 +++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 284 insertions(+), 191 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce95a65b..16854d8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -80,6 +80,7 @@ Changes since version 0.80.2: - Fixed e memory leak in the code that reads a localized root menu - Added support for generating pkgconfig files for WINGS, wmlib and wrlib. ("Marcelo E. Magallon" ) +- Support for multiline balloons (Vitaly Ovtchinnikov ) Changes since version 0.80.1: diff --git a/src/balloon.c b/src/balloon.c index 2ba09077..f7515081 100644 --- a/src/balloon.c +++ b/src/balloon.c @@ -1,8 +1,8 @@ -/* +/* * Window Maker window manager - * + * * Copyright (c) 1998-2003 Alfredo K. Kojima - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ @@ -60,11 +60,11 @@ typedef struct _WBalloon { Window objectWindow; char *text; int h; - + WMHandlerID timer; - + Pixmap contents; - + char mapped; char ignoreTimer; } WBalloon; @@ -81,6 +81,79 @@ typedef struct _WBalloon { #define BRIGHT (BOTTOM|RIGHT) +static int +countLines(const char *text) +{ + const char *p = text; + int h = 1; + + while (*p) { + if (*p == '\n' && p[1] != 0) + h++; + p++; + } + return h; +} + + +static int +getMaxStringWidth(WMFont *font, char *text) +{ + char *p = text; + char *pb = p; + int pos = 0; + int w = 0, wt; + + while (*p) { + if (*p == '\n') { + wt = WMWidthOfString(font, pb, pos); + if (wt > w) + w = wt; + pos = 0; + pb = p + 1; + } else { + pos++; + } + p++; + } + if (pos > 0) { + wt = WMWidthOfString(font, pb, pos); + if (wt > w) + w = wt; + } + return w; +} + + +static void +drawMultiLineString(WMScreen *scr, Pixmap pixmap, WMColor *color, + WMFont *font, int x, int y, char *text, int len) +{ + char *p = text; + char *pb = p; + int l = 0, pos = 0; + int height = WMFontHeight(font); + + while (*p && p - text < len) { + if (*p == '\n') { + WMDrawString(scr, pixmap, color, font, x, y + l * height, pb, + pos); + l++; + pos = 0; + pb = p + 1; + } else { + pos++; + } + p++; + } + if (pos > 0) { + WMDrawString(scr, pixmap, color, font, x, y + l * height, pb, pos); + } +} + + + + #ifdef SHAPED_BALLOON #define SPACE 12 @@ -92,73 +165,81 @@ drawBalloon(WScreen *scr, Pixmap bitmap, Pixmap pix, int x, int y, int w, { GC bgc = scr->balloon->monoGC; GC gc = scr->draw_gc; - int rad = h*3/10; + int rad = h * 3 / 10; XPoint pt[3], ipt[3]; int w1; /* outline */ XSetForeground(dpy, bgc, 1); - XFillArc(dpy, bitmap, bgc, x, y, rad, rad, 90*64, 90*64); - XFillArc(dpy, bitmap, bgc, x, y+h-1-rad, rad, rad, 180*64, 90*64); + XFillArc(dpy, bitmap, bgc, x, y, rad, rad, 90 * 64, 90 * 64); + XFillArc(dpy, bitmap, bgc, x, y + h - 1 - rad, rad, rad, 180 * 64, + 90 * 64); - XFillArc(dpy, bitmap, bgc, x+w-1-rad, y, rad, rad, 0*64, 90*64); - XFillArc(dpy, bitmap, bgc, x+w-1-rad, y+h-1-rad, rad, rad, 270*64, 90*64); + XFillArc(dpy, bitmap, bgc, x + w - 1 - rad, y, rad, rad, 0 * 64, + 90 * 64); + XFillArc(dpy, bitmap, bgc, x + w - 1 - rad, y + h - 1 - rad, rad, rad, + 270 * 64, 90 * 64); - XFillRectangle(dpy, bitmap, bgc, x, y+rad/2, w, h-rad); - XFillRectangle(dpy, bitmap, bgc, x+rad/2, y, w-rad, h); + XFillRectangle(dpy, bitmap, bgc, x, y + rad / 2, w, h - rad); + XFillRectangle(dpy, bitmap, bgc, x + rad / 2, y, w - rad, h); /* interior */ XSetForeground(dpy, gc, scr->white_pixel); - XFillArc(dpy, pix, gc, x+1, y+1, rad, rad, 90*64, 90*64); - XFillArc(dpy, pix, gc, x+1, y+h-2-rad, rad, rad, 180*64, 90*64); + XFillArc(dpy, pix, gc, x + 1, y + 1, rad, rad, 90 * 64, 90 * 64); + XFillArc(dpy, pix, gc, x + 1, y + h - 2 - rad, rad, rad, 180 * 64, + 90 * 64); - XFillArc(dpy, pix, gc, x+w-2-rad, y+1, rad, rad, 0*64, 90*64); - XFillArc(dpy, pix, gc, x+w-2-rad, y+h-2-rad, rad, rad, 270*64, 90*64); + XFillArc(dpy, pix, gc, x + w - 2 - rad, y + 1, rad, rad, 0 * 64, + 90 * 64); + XFillArc(dpy, pix, gc, x + w - 2 - rad, y + h - 2 - rad, rad, rad, + 270 * 64, 90 * 64); - XFillRectangle(dpy, pix, gc, x+1, y+1+rad/2, w-2, h-2-rad); - XFillRectangle(dpy, pix, gc, x+1+rad/2, y+1, w-2-rad, h-2); + XFillRectangle(dpy, pix, gc, x + 1, y + 1 + rad / 2, w - 2, + h - 2 - rad); + XFillRectangle(dpy, pix, gc, x + 1 + rad / 2, y + 1, w - 2 - rad, + h - 2); if (side & BOTTOM) { - pt[0].y = y+h-1; - pt[1].y = y+h-1+SPACE; - pt[2].y = y+h-1; - ipt[0].y = pt[0].y-1; - ipt[1].y = pt[1].y-1; - ipt[2].y = pt[2].y-1; + pt[0].y = y + h - 1; + pt[1].y = y + h - 1 + SPACE; + pt[2].y = y + h - 1; + ipt[0].y = pt[0].y - 1; + ipt[1].y = pt[1].y - 1; + ipt[2].y = pt[2].y - 1; } else { pt[0].y = y; - pt[1].y = y-SPACE; - pt[2].y = y; - ipt[0].y = pt[0].y+1; - ipt[1].y = pt[1].y+1; - ipt[2].y = pt[2].y+1; + pt[1].y = y - SPACE; + pt[2].y = y; + ipt[0].y = pt[0].y + 1; + ipt[1].y = pt[1].y + 1; + ipt[2].y = pt[2].y + 1; } - /*w1 = WMAX(h, 24);*/ + /*w1 = WMAX(h, 24); */ w1 = WMAX(h, 21); if (side & RIGHT) { - pt[0].x = x+w-w1+2*w1/16; - pt[1].x = x+w-w1+11*w1/16; - pt[2].x = x+w-w1+7*w1/16; - ipt[0].x = x+1+w-w1+2*(w1-1)/16; - ipt[1].x = x+1+w-w1+11*(w1-1)/16; - ipt[2].x = x+1+w-w1+7*(w1-1)/16; + pt[0].x = x + w - w1 + 2 * w1 / 16; + pt[1].x = x + w - w1 + 11 * w1 / 16; + pt[2].x = x + w - w1 + 7 * w1 / 16; + ipt[0].x = x + 1 + w - w1 + 2 * (w1 - 1) / 16; + ipt[1].x = x + 1 + w - w1 + 11 * (w1 - 1) / 16; + ipt[2].x = x + 1 + w - w1 + 7 * (w1 - 1) / 16; /*ipt[0].x = pt[0].x+1; - ipt[1].x = pt[1].x; - ipt[2].x = pt[2].x;*/ + ipt[1].x = pt[1].x; + ipt[2].x = pt[2].x; */ } else { - pt[0].x = x+w1-2*w1/16; - pt[1].x = x+w1-11*w1/16; - pt[2].x = x+w1-7*w1/16; - ipt[0].x = x-1+w1-2*(w1-1)/16; - ipt[1].x = x-1+w1-11*(w1-1)/16; - ipt[2].x = x-1+w1-7*(w1-1)/16; + pt[0].x = x + w1 - 2 * w1 / 16; + pt[1].x = x + w1 - 11 * w1 / 16; + pt[2].x = x + w1 - 7 * w1 / 16; + ipt[0].x = x - 1 + w1 - 2 * (w1 - 1) / 16; + ipt[1].x = x - 1 + w1 - 11 * (w1 - 1) / 16; + ipt[2].x = x - 1 + w1 - 7 * (w1 - 1) / 16; /*ipt[0].x = pt[0].x-1; - ipt[1].x = pt[1].x; - ipt[2].x = pt[2].x;*/ + ipt[1].x = pt[1].x; + ipt[2].x = pt[2].x; */ } XFillPolygon(dpy, bitmap, bgc, pt, 3, Convex, CoordModeOrigin); @@ -187,23 +268,28 @@ makePixmap(WScreen *scr, int width, int height, int side, Pixmap *mask) Pixmap pixmap; int x, y; - bitmap = XCreatePixmap(dpy, scr->root_win, width+SPACE, height+SPACE, 1); + bitmap = + XCreatePixmap(dpy, scr->root_win, width + SPACE, height + SPACE, + 1); if (!bal->monoGC) { - bal->monoGC = XCreateGC(dpy, bitmap, 0, NULL); + bal->monoGC = XCreateGC(dpy, bitmap, 0, NULL); } - XSetForeground(dpy, bal->monoGC, 0); - XFillRectangle(dpy, bitmap, bal->monoGC, 0, 0, width+SPACE, height+SPACE); - - pixmap = XCreatePixmap(dpy, scr->root_win, width+SPACE, height+SPACE, - scr->w_depth); + XSetForeground(dpy, bal->monoGC, 0); + XFillRectangle(dpy, bitmap, bal->monoGC, 0, 0, width + SPACE, + height + SPACE); + + pixmap = + XCreatePixmap(dpy, scr->root_win, width + SPACE, height + SPACE, + scr->w_depth); XSetForeground(dpy, scr->draw_gc, scr->black_pixel); - XFillRectangle(dpy, pixmap, scr->draw_gc, 0, 0, width+SPACE, height+SPACE); + XFillRectangle(dpy, pixmap, scr->draw_gc, 0, 0, width + SPACE, + height + SPACE); if (side & BOTTOM) { - y = 0; + y = 0; } else { - y = SPACE; + y = SPACE; } x = 0; @@ -228,50 +314,49 @@ showText(WScreen *scr, int x, int y, int h, int w, char *text) int bx, by; if (scr->balloon->contents) - XFreePixmap(dpy, scr->balloon->contents); + XFreePixmap(dpy, scr->balloon->contents); + + width = getMaxStringWidth(font, text) + 16; + height = countLines(text) * WMFontHeight(font) + 4; - width = WMWidthOfString(font, text, strlen(text))+16; - height = WMFontHeight(font) + 4; - if (height < 16) - height = 16; + height = 16; if (width < height) - width = height; + width = height; if (x + width > scr->scr_width) { - side = RIGHT; - bx = x - width + w/2; - if (bx < 0) - bx = 0; + side = RIGHT; + bx = x - width + w / 2; + if (bx < 0) + bx = 0; } else { - side = LEFT; - bx = x + w/2; + side = LEFT; + bx = x + w / 2; } if (bx + width > scr->scr_width) - bx = scr->scr_width - width; + bx = scr->scr_width - width; if (y - (height + SPACE) < 0) { - side |= TOP; - by = y+h-1; - ty = SPACE; + side |= TOP; + by = y + h - 1; + ty = SPACE; } else { - side |= BOTTOM; - by = y - (height + SPACE); - ty = 0; + side |= BOTTOM; + by = y - (height + SPACE); + ty = 0; } pixmap = makePixmap(scr, width, height, side, &mask); - WMDrawString(scr->wmscreen, pixmap, scr->black, font, 8, - ty + (height - WMFontHeight(font))/2, - text, strlen(text)); + drawMultiLineString(scr->wmscreen, pixmap, scr->black, font, 8, ty + 2, + text, strlen(text)); XSetWindowBackgroundPixmap(dpy, scr->balloon->window, pixmap); scr->balloon->contents = pixmap; - XResizeWindow(dpy, scr->balloon->window, width, height+SPACE); + XResizeWindow(dpy, scr->balloon->window, width, height + SPACE); XShapeCombineMask(dpy, scr->balloon->window, ShapeBounding, 0, 0, mask, - ShapeSet); + ShapeSet); XFreePixmap(dpy, mask); XMoveWindow(dpy, scr->balloon->window, bx, by); XMapRaised(dpy, scr->balloon->window); @@ -279,7 +364,9 @@ showText(WScreen *scr, int x, int y, int h, int w, char *text) scr->balloon->mapped = 1; } -#else /* !SHAPED_BALLOON */ +#else /* !SHAPED_BALLOON */ + + static void showText(WScreen *scr, int x, int y, int h, int w, char *text) { @@ -289,35 +376,37 @@ showText(WScreen *scr, int x, int y, int h, int w, char *text) WMFont *font = scr->info_text_font; if (scr->balloon->contents) - XFreePixmap(dpy, scr->balloon->contents); + XFreePixmap(dpy, scr->balloon->contents); - width = WMWidthOfString(font, text, strlen(text))+8; - height = WMFontHeight(font) + 4; + width = getMaxStringWidth(font, text) + 8; + /*width = WMWidthOfString(font, text, strlen(text))+8;*/ + height = countLines(text) * WMFontHeight(font) + 4; if (x < 0) - x = 0; - else if (x + width > scr->scr_width-1) - x = scr->scr_width - width; - + x = 0; + else if (x + width > scr->scr_width - 1) + x = scr->scr_width - width; + if (y - height - 2 < 0) { - y += h; - if (y < 0) - y = 0; + y += h; + if (y < 0) + y = 0; } else { - y -= height + 2; + y -= height + 2; } - + if (scr->window_title_texture[0]) - XSetForeground(dpy, scr->draw_gc, - scr->window_title_texture[0]->any.color.pixel); + XSetForeground(dpy, scr->draw_gc, + scr->window_title_texture[0]->any.color.pixel); else - XSetForeground(dpy, scr->draw_gc, scr->light_pixel); + XSetForeground(dpy, scr->draw_gc, scr->light_pixel); - pixmap = XCreatePixmap(dpy, scr->root_win, width, height, scr->w_depth); + pixmap = + XCreatePixmap(dpy, scr->root_win, width, height, scr->w_depth); XFillRectangle(dpy, pixmap, scr->draw_gc, 0, 0, width, height); - WMDrawString(scr->wmscreen, pixmap, scr->window_title_color[0], font, 4, 2, - text, strlen(text)); + drawMultiLineString(scr->wmscreen, pixmap, scr->window_title_color[0], + font, 4, 2, text, strlen(text)); XResizeWindow(dpy, scr->balloon->window, width, height); XMoveWindow(dpy, scr->balloon->window, x, y); @@ -327,10 +416,10 @@ showText(WScreen *scr, int x, int y, int h, int w, char *text) XMapRaised(dpy, scr->balloon->window); scr->balloon->contents = pixmap; - + scr->balloon->mapped = 1; } -#endif /* !SHAPED_BALLOON */ +#endif /* !SHAPED_BALLOON */ static void @@ -341,37 +430,37 @@ showBalloon(WScreen *scr) unsigned foo, w; if (scr->balloon) { - scr->balloon->timer = NULL; - scr->balloon->ignoreTimer = 1; + scr->balloon->timer = NULL; + scr->balloon->ignoreTimer = 1; } if (!XGetGeometry(dpy, scr->balloon->objectWindow, &foow, &x, &y, - &w, &foo, &foo, &foo)) { - scr->balloon->prevType = 0; - return; + &w, &foo, &foo, &foo)) { + scr->balloon->prevType = 0; + return; } showText(scr, x, y, scr->balloon->h, w, scr->balloon->text); } - static void frameBalloon(WObjDescriptor *object) { - WFrameWindow *fwin = (WFrameWindow*)object->parent; + WFrameWindow *fwin = (WFrameWindow *) object->parent; WScreen *scr = fwin->core->screen_ptr; if (fwin->titlebar != object->self - || !fwin->flags.is_client_window_frame) { - wBalloonHide(scr); - return; + || !fwin->flags.is_client_window_frame) { + wBalloonHide(scr); + return; } if (fwin->title && fwin->flags.incomplete_title) { - scr->balloon->h = (fwin->titlebar ? fwin->titlebar->height : 0); - scr->balloon->text = wstrdup(fwin->title); - scr->balloon->objectWindow = fwin->core->window; - scr->balloon->timer = WMAddTimerHandler(BALLOON_DELAY, - (WMCallback*)showBalloon, scr); + scr->balloon->h = (fwin->titlebar ? fwin->titlebar->height : 0); + scr->balloon->text = wstrdup(fwin->title); + scr->balloon->objectWindow = fwin->core->window; + scr->balloon->timer = WMAddTimerHandler(BALLOON_DELAY, + (WMCallback *) showBalloon, + scr); } } @@ -379,60 +468,61 @@ frameBalloon(WObjDescriptor *object) static void miniwindowBalloon(WObjDescriptor *object) { - WIcon *icon = (WIcon*)object->parent; + WIcon *icon = (WIcon *) object->parent; WScreen *scr = icon->core->screen_ptr; if (!icon->icon_name) { - wBalloonHide(scr); - return; + wBalloonHide(scr); + return; } scr->balloon->h = icon->core->height; scr->balloon->text = wstrdup(icon->icon_name); scr->balloon->objectWindow = icon->core->window; if ((scr->balloon->prevType == object->parent_type - || scr->balloon->prevType == WCLASS_APPICON) - && scr->balloon->ignoreTimer) { - XUnmapWindow(dpy, scr->balloon->window); - showBalloon(scr); + || scr->balloon->prevType == WCLASS_APPICON) + && scr->balloon->ignoreTimer) { + XUnmapWindow(dpy, scr->balloon->window); + showBalloon(scr); } else { - scr->balloon->timer = WMAddTimerHandler(BALLOON_DELAY, - (WMCallback*)showBalloon, scr); + scr->balloon->timer = WMAddTimerHandler(BALLOON_DELAY, + (WMCallback *) showBalloon, + scr); } } - static void appiconBalloon(WObjDescriptor *object) { - WAppIcon *aicon = (WAppIcon*)object->parent; + WAppIcon *aicon = (WAppIcon *) object->parent; WScreen *scr = aicon->icon->core->screen_ptr; char *tmp; if (aicon->command && aicon->wm_class) { - int len = strlen(aicon->command)+strlen(aicon->wm_class)+8; - tmp = wmalloc(len); - snprintf(tmp, len, "%s (%s)", aicon->wm_class, aicon->command); - scr->balloon->text = tmp; + int len = strlen(aicon->command) + strlen(aicon->wm_class) + 8; + tmp = wmalloc(len); + snprintf(tmp, len, "%s\n(%s)", aicon->wm_class, aicon->command); + scr->balloon->text = tmp; } else if (aicon->command) { - scr->balloon->text = wstrdup(aicon->command); + scr->balloon->text = wstrdup(aicon->command); } else if (aicon->wm_class) { - scr->balloon->text = wstrdup(aicon->wm_class); + scr->balloon->text = wstrdup(aicon->wm_class); } else { - wBalloonHide(scr); - return; + wBalloonHide(scr); + return; } - scr->balloon->h = aicon->icon->core->height-2; + scr->balloon->h = aicon->icon->core->height - 2; scr->balloon->objectWindow = aicon->icon->core->window; if ((scr->balloon->prevType == object->parent_type - || scr->balloon->prevType == WCLASS_MINIWINDOW) - && scr->balloon->ignoreTimer) { - XUnmapWindow(dpy, scr->balloon->window); - showBalloon(scr); + || scr->balloon->prevType == WCLASS_MINIWINDOW) + && scr->balloon->ignoreTimer) { + XUnmapWindow(dpy, scr->balloon->window); + showBalloon(scr); } else { - scr->balloon->timer = WMAddTimerHandler(BALLOON_DELAY, - (WMCallback*)showBalloon, scr); + scr->balloon->timer = WMAddTimerHandler(BALLOON_DELAY, + (WMCallback *) showBalloon, + scr); } } @@ -444,23 +534,23 @@ wBalloonInitialize(WScreen *scr) WBalloon *bal; XSetWindowAttributes attribs; unsigned long vmask; - + bal = wmalloc(sizeof(WBalloon)); memset(bal, 0, sizeof(WBalloon)); - + scr->balloon = bal; - vmask = CWSaveUnder|CWOverrideRedirect|CWColormap|CWBackPixel - |CWBorderPixel; + vmask = CWSaveUnder | CWOverrideRedirect | CWColormap | CWBackPixel + | CWBorderPixel; attribs.save_under = True; attribs.override_redirect = True; attribs.colormap = scr->w_colormap; attribs.background_pixel = scr->icon_back_texture->normal.pixel; - attribs.border_pixel = 0; /* do not care */ + attribs.border_pixel = 0; /* do not care */ bal->window = XCreateWindow(dpy, scr->root_win, 1, 1, 10, 10, 1, - scr->w_depth, CopyFromParent, - scr->w_visual, vmask, &attribs); + scr->w_depth, CopyFromParent, + scr->w_visual, vmask, &attribs); #if 0 /* select EnterNotify to so that the balloon will be unmapped * when the pointer is moved over it */ @@ -469,53 +559,53 @@ wBalloonInitialize(WScreen *scr) } - void wBalloonEnteredObject(WScreen *scr, WObjDescriptor *object) { WBalloon *balloon = scr->balloon; - + if (balloon->timer) { - WMDeleteTimerHandler(balloon->timer); - balloon->timer = NULL; - balloon->ignoreTimer = 0; + WMDeleteTimerHandler(balloon->timer); + balloon->timer = NULL; + balloon->ignoreTimer = 0; } if (scr->balloon->text) - wfree(scr->balloon->text); + wfree(scr->balloon->text); scr->balloon->text = NULL; if (!object) { - wBalloonHide(scr); - balloon->ignoreTimer = 0; - return; + wBalloonHide(scr); + balloon->ignoreTimer = 0; + return; } switch (object->parent_type) { - case WCLASS_FRAME: - if (wPreferences.window_balloon) { - frameBalloon(object); - } - break; - - case WCLASS_DOCK_ICON: - if (object->parent != scr->clip_icon && wPreferences.appicon_balloon) - appiconBalloon(object); + case WCLASS_FRAME: + if (wPreferences.window_balloon) { + frameBalloon(object); + } + break; + + case WCLASS_DOCK_ICON: + if (object->parent != scr->clip_icon + && wPreferences.appicon_balloon) + appiconBalloon(object); else wBalloonHide(scr); - break; - - case WCLASS_MINIWINDOW: - if (wPreferences.miniwin_balloon) { - miniwindowBalloon(object); - } - break; - case WCLASS_APPICON: - if (wPreferences.appicon_balloon) - appiconBalloon(object); - break; - default: - wBalloonHide(scr); - break; + break; + + case WCLASS_MINIWINDOW: + if (wPreferences.miniwin_balloon) { + miniwindowBalloon(object); + } + break; + case WCLASS_APPICON: + if (wPreferences.appicon_balloon) + appiconBalloon(object); + break; + default: + wBalloonHide(scr); + break; } scr->balloon->prevType = object->parent_type; } @@ -526,14 +616,16 @@ void wBalloonHide(WScreen *scr) { if (scr) { - if (scr->balloon->mapped) { - XUnmapWindow(dpy, scr->balloon->window); - scr->balloon->mapped = 0; - } else if (scr->balloon->timer) { - WMDeleteTimerHandler(scr->balloon->timer); - scr->balloon->timer = NULL; - } - scr->balloon->prevType = 0; + if (scr->balloon->mapped) { + XUnmapWindow(dpy, scr->balloon->window); + scr->balloon->mapped = 0; + } else if (scr->balloon->timer) { + WMDeleteTimerHandler(scr->balloon->timer); + scr->balloon->timer = NULL; + } + scr->balloon->prevType = 0; } } + #endif + -- 2.11.4.GIT