fvwm1/fvwm/icons.c
2019-08-26 23:33:33 +01:00

918 lines
26 KiB
C

/****************************************************************************
* This module is mostly all new
* by Rob Nation
* A little of it is borrowed from ctwm.
* Copyright 1993 Robert Nation. No restrictions are placed on this code,
* as long as the copyright notice is preserved
****************************************************************************/
/***********************************************************************
*
* fvwm icon code
*
***********************************************************************/
#include "../configure.h"
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#ifdef NeXT
#include <fcntl.h>
#endif
#include <X11/Intrinsic.h>
#ifdef XPM
#include <X11/xpm.h>
#endif /* XPM */
#include "fvwm.h"
#include "menus.h"
#include "misc.h"
#include "parse.h"
#include "screen.h"
#include "module.h"
#ifdef SHAPE
#include <X11/extensions/shape.h>
#endif /* SHAPE */
void GrabIconButtons(FvwmWindow *, Window);
void GrabIconKeys(FvwmWindow *, Window);
MyFont *IconFont;
/****************************************************************************
*
* Creates an icon window as needed
*
****************************************************************************/
void CreateIconWindow(FvwmWindow *tmp_win, int def_x, int def_y)
{
int final_x, final_y;
unsigned long valuemask; /* mask for create windows */
XSetWindowAttributes attributes; /* attributes for create windows */
tmp_win->flags |= ICON_OURS;
tmp_win->flags &= ~XPM_FLAG;
tmp_win->flags &= ~PIXMAP_OURS;
tmp_win->flags &= ~SHAPED_ICON;
tmp_win->icon_pixmap_w = None;
tmp_win->iconPixmap = None;
tmp_win->iconDepth = 0;
if(tmp_win->flags & SUPPRESSICON)
return;
/* First, see if it was specified in the .fvwmrc */
tmp_win->icon_p_height = 0;
tmp_win->icon_p_width = 0;
/* First, check for a monochrome bitmap */
if(tmp_win->icon_bitmap_file != NULL)
GetBitmapFile(tmp_win);
/* Next, check for a color pixmap */
if((tmp_win->icon_bitmap_file != NULL)&&
(tmp_win->icon_p_height == 0)&&(tmp_win->icon_p_width == 0))
GetXPMFile(tmp_win);
/* Next, See if the app supplies its own icon window */
if((tmp_win->icon_p_height == 0)&&(tmp_win->icon_p_width == 0)&&
(tmp_win->wmhints) && (tmp_win->wmhints->flags & IconWindowHint))
GetIconWindow(tmp_win);
/* Finally, try to get icon bitmap from the application */
if((tmp_win->icon_p_height == 0)&&(tmp_win->icon_p_width == 0)&&
(tmp_win->wmhints)&&(tmp_win->wmhints->flags & IconPixmapHint))
GetIconBitmap(tmp_win);
/* figure out the icon window size */
if (!(tmp_win->flags & NOICON_TITLE)||(tmp_win->icon_p_height == 0))
{
tmp_win->icon_t_width = XTextWidth(IconFont->font,tmp_win->icon_name,
strlen(tmp_win->icon_name));
tmp_win->icon_w_height = ICON_HEIGHT;
}
else
{
tmp_win->icon_t_width = 0;
tmp_win->icon_w_height = 0;
}
if((tmp_win->flags & ICON_OURS)&&(tmp_win->icon_p_height >0))
{
tmp_win->icon_p_width += 4;
tmp_win->icon_p_height +=4;
}
if(tmp_win->icon_p_width == 0)
tmp_win->icon_p_width = tmp_win->icon_t_width+6;
tmp_win->icon_w_width = tmp_win->icon_p_width;
final_x = def_x;
final_y = def_y;
if(final_x <0)
final_x = 0;
if(final_y <0)
final_y = 0;
if(final_x + tmp_win->icon_w_width >=Scr.MyDisplayWidth)
final_x = Scr.MyDisplayWidth - tmp_win->icon_w_width-1;
if(final_y + tmp_win->icon_w_height >=Scr.MyDisplayHeight)
final_y = Scr.MyDisplayHeight - tmp_win->icon_w_height-1;
tmp_win->icon_x_loc = final_x;
tmp_win->icon_xl_loc = final_x;
tmp_win->icon_y_loc = final_y;
/* clip to fit on screen */
attributes.background_pixel = Scr.StdColors.back;
valuemask = CWBorderPixel | CWCursor | CWEventMask | CWBackPixel;
attributes.border_pixel = Scr.StdColors.fore;
attributes.cursor = Scr.FvwmCursors[DEFAULT];
attributes.event_mask = (ButtonPressMask | ButtonReleaseMask |
VisibilityChangeMask |
ExposureMask | KeyPressMask|EnterWindowMask |
FocusChangeMask );
if (!(tmp_win->flags & NOICON_TITLE)||(tmp_win->icon_p_height == 0))
tmp_win->icon_w =
XCreateWindow(dpy, Scr.Root, final_x, final_y+tmp_win->icon_p_height,
tmp_win->icon_w_width, tmp_win->icon_w_height,0,
CopyFromParent,
CopyFromParent,CopyFromParent,valuemask,&attributes);
if((tmp_win->flags & ICON_OURS)&&(tmp_win->icon_p_width>0)&&
(tmp_win->icon_p_height>0))
{
tmp_win->icon_pixmap_w =
XCreateWindow(dpy, Scr.Root, final_x, final_y, tmp_win->icon_p_width,
tmp_win->icon_p_height, 0, CopyFromParent,
CopyFromParent,CopyFromParent,valuemask,&attributes);
}
else
{
attributes.event_mask = (ButtonPressMask | ButtonReleaseMask |
VisibilityChangeMask |
KeyPressMask|EnterWindowMask |
FocusChangeMask | LeaveWindowMask );
valuemask = CWEventMask;
XChangeWindowAttributes(dpy,tmp_win->icon_pixmap_w,
valuemask,&attributes);
}
#ifdef XPM
#ifdef SHAPE
if (tmp_win->flags & SHAPED_ICON)
{
XShapeCombineMask(dpy, tmp_win->icon_pixmap_w, ShapeBounding,2, 2,
tmp_win->icon_maskPixmap, ShapeSet);
}
#endif
#endif
if(tmp_win->icon_w != None)
{
XSaveContext(dpy, tmp_win->icon_w, FvwmContext, (caddr_t)tmp_win);
XDefineCursor(dpy, tmp_win->icon_w, Scr.FvwmCursors[DEFAULT]);
GrabIconButtons(tmp_win,tmp_win->icon_w);
GrabIconKeys(tmp_win,tmp_win->icon_w);
}
if(tmp_win->icon_pixmap_w != None)
{
XSaveContext(dpy, tmp_win->icon_pixmap_w, FvwmContext, (caddr_t)tmp_win);
XDefineCursor(dpy, tmp_win->icon_pixmap_w, Scr.FvwmCursors[DEFAULT]);
GrabIconButtons(tmp_win,tmp_win->icon_pixmap_w);
GrabIconKeys(tmp_win,tmp_win->icon_pixmap_w);
}
return;
}
/****************************************************************************
*
* Draws the icon window
*
****************************************************************************/
void DrawIconWindow(FvwmWindow *Tmp_win)
{
GC Shadow, Relief;
Pixel TextColor,BackColor;
int x ;
if(Tmp_win->flags & SUPPRESSICON)
return;
if(Tmp_win->icon_w != None)
flush_expose (Tmp_win->icon_w);
if(Tmp_win->icon_pixmap_w != None)
flush_expose (Tmp_win->icon_pixmap_w);
if(Scr.Hilite == Tmp_win)
{
if(Scr.d_depth < 2)
Relief = Scr.HiShadowGC;
else
Relief = Scr.HiReliefGC;
Shadow = Scr.HiShadowGC;
/* resize the icon name window */
if(Tmp_win->icon_w != None)
{
Tmp_win->icon_w_width = Tmp_win->icon_t_width+6;
if(Tmp_win->icon_w_width < Tmp_win->icon_p_width)
Tmp_win->icon_w_width = Tmp_win->icon_p_width;
Tmp_win->icon_xl_loc = Tmp_win->icon_x_loc -
(Tmp_win->icon_w_width - Tmp_win->icon_p_width)/2;
}
TextColor = Scr.HiColors.fore;
BackColor = Scr.HiColors.back;
}
else
{
if((Tmp_win->flags & STICKY)&&(Scr.d_depth < 2))
{
Relief = Scr.StickyShadowGC;
Shadow = Scr.StickyShadowGC;
}
else if(Scr.d_depth < 2)
{
Relief = Scr.StdShadowGC;
Shadow = Scr.StdShadowGC;
}
else
{
if(Tmp_win->BackPixel != Scr.StdColors.back)
{
Globalgcv.foreground = Tmp_win->ReliefPixel;
Globalgcm = GCForeground;
XChangeGC(dpy,Scr.ScratchGC1,Globalgcm,&Globalgcv);
Relief = Scr.ScratchGC1;
Globalgcv.foreground = Tmp_win->ShadowPixel;
XChangeGC(dpy,Scr.ScratchGC2,Globalgcm,&Globalgcv);
Shadow = Scr.ScratchGC2;
}
else
{
Relief = Scr.StdReliefGC;
Shadow = Scr.StdShadowGC;
}
}
/* resize the icon name window */
if(Tmp_win->icon_w != None)
{
Tmp_win->icon_w_width = Tmp_win->icon_p_width;
Tmp_win->icon_xl_loc = Tmp_win->icon_x_loc;
}
TextColor = Tmp_win->TextPixel;
BackColor = Tmp_win->BackPixel;
}
if((Tmp_win->flags & ICON_OURS)&&(Tmp_win->icon_pixmap_w != None))
XSetWindowBackground(dpy,Tmp_win->icon_pixmap_w,
BackColor);
if(Tmp_win->icon_w != None)
XSetWindowBackground(dpy,Tmp_win->icon_w,BackColor);
/* write the icon label */
NewFontAndColor(IconFont->font->fid,TextColor,BackColor);
if(Tmp_win->icon_pixmap_w != None)
XMoveWindow(dpy,Tmp_win->icon_pixmap_w,Tmp_win->icon_x_loc,
Tmp_win->icon_y_loc);
if(Tmp_win->icon_w != None)
{
XMoveResizeWindow(dpy, Tmp_win->icon_w, Tmp_win->icon_xl_loc,
Tmp_win->icon_y_loc+Tmp_win->icon_p_height,
Tmp_win->icon_w_width,ICON_HEIGHT);
XClearWindow(dpy,Tmp_win->icon_w);
}
if((Tmp_win->iconPixmap != None)&&(!(Tmp_win->flags & SHAPED_ICON)))
RelieveWindow(Tmp_win,Tmp_win->icon_pixmap_w,0,0,
Tmp_win->icon_p_width, Tmp_win->icon_p_height,
Relief,Shadow, FULL_HILITE);
/* need to locate the icon pixmap */
if(Tmp_win->iconPixmap != None)
{
if(Tmp_win->iconDepth == Scr.d_depth)
{
XCopyArea(dpy,Tmp_win->iconPixmap,Tmp_win->icon_pixmap_w,Scr.FontGC,
0,0,Tmp_win->icon_p_width-4, Tmp_win->icon_p_height-4,2,2);
}
else
XCopyPlane(dpy,Tmp_win->iconPixmap,Tmp_win->icon_pixmap_w,Scr.FontGC,0,
0,Tmp_win->icon_p_width-4, Tmp_win->icon_p_height-4,2,2,1);
}
if(Tmp_win->icon_w != None)
{
/* text position */
x = (Tmp_win->icon_w_width - Tmp_win->icon_t_width)/2;
if(x<3)x=3;
XDrawString (dpy, Tmp_win->icon_w, Scr.FontGC, x,
Tmp_win->icon_w_height-IconFont->height+IconFont->y-3,
Tmp_win->icon_name, strlen(Tmp_win->icon_name));
RelieveWindow(Tmp_win,Tmp_win->icon_w,0,0,Tmp_win->icon_w_width,
ICON_HEIGHT,Relief,Shadow, FULL_HILITE);
}
}
/***********************************************************************
*
* Procedure:
* RedoIconName - procedure to re-position the icon window and name
*
************************************************************************/
void RedoIconName(FvwmWindow *Tmp_win)
{
#ifndef NO_PAGER
if(Scr.PagerFont.height > 0)
{
XClearWindow(dpy,Tmp_win->pager_view);
RedrawPager();
}
#endif
if(Tmp_win->flags & SUPPRESSICON)
return;
if (Tmp_win->icon_w == (int)NULL)
return;
Tmp_win->icon_t_width = XTextWidth(IconFont->font,Tmp_win->icon_name,
strlen(Tmp_win->icon_name));
/* clear the icon window, and trigger a re-draw via an expose event */
if (Tmp_win->flags & ICONIFIED)
XClearArea(dpy, Tmp_win->icon_w, 0, 0, 0, 0, True);
return;
}
/***********************************************************************
*
* Procedure:
* AutoPlace - Find a home for an icon
*
************************************************************************/
void AutoPlace(FvwmWindow *t)
{
int test_x=0, test_y=0,tw,th,tx,ty,i,temp_h,temp_w;
int base_x, base_y;
int width,height;
FvwmWindow *test_window;
Bool loc_ok;
int real_x=10, real_y=10;
/* New! Put icon in same page as the center of the window */
/* Not a good idea for StickyIcons */
if((Scr.flags & StickyIcons)||(t->flags & STICKY))
{
base_x = 0;
base_y = 0;
}
else
{
base_x=((t->frame_x+Scr.Vx+(t->frame_width>>1))/Scr.MyDisplayWidth)*
Scr.MyDisplayWidth - Scr.Vx;
base_y=((t->frame_y+Scr.Vy+(t->frame_height>>1))/Scr.MyDisplayHeight)*
Scr.MyDisplayHeight - Scr.Vy;
}
if(t->flags & ICON_MOVED)
{
/* just make sure the icon is on this screen */
t->icon_x_loc = t->icon_x_loc % Scr.MyDisplayWidth + base_x;
t->icon_y_loc = t->icon_y_loc % Scr.MyDisplayHeight + base_y;
if(t->icon_x_loc < 0)
t->icon_x_loc += Scr.MyDisplayWidth;
if(t->icon_y_loc < 0)
t->icon_y_loc += Scr.MyDisplayHeight;
}
else if (t->wmhints && t->wmhints->flags & IconPositionHint)
{
t->icon_x_loc = t->wmhints->icon_x;
t->icon_y_loc = t->wmhints->icon_y;
}
else
{
width = t->icon_p_width;
height = t->icon_w_height + t->icon_p_height;
loc_ok = False;
/* check all boxes in order */
i=0;
while((i<Scr.NumBoxes)&&(!loc_ok))
{
/* In each IconBox, start at the upper left, travel right, then
* down */
test_y = Scr.IconBoxes[i][1]+base_y;
temp_h = height;
temp_w = width;
/* OK second try at this.
* If the window is taller than the icon box, ignore the icon height
* when figuring where to put it. Same goes for the width */
/* This should permit reasonably graceful handling of big icons. */
if(width >= (Scr.IconBoxes[i][2] - Scr.IconBoxes[i][0]))
temp_w = 0;
if(height >= (Scr.IconBoxes[i][3] - Scr.IconBoxes[i][1]))
temp_h = 0;
while(((test_y + temp_h) < (Scr.IconBoxes[i][3]+base_y))&&(!loc_ok))
{
test_x = Scr.IconBoxes[i][0]+base_x;
while(((test_x + temp_w) < (Scr.IconBoxes[i][2]+base_x))&&
(!loc_ok))
{
real_x = test_x;
real_y = test_y;
if(test_x + width > (Scr.MyDisplayWidth-2+base_x))
real_x = Scr.MyDisplayWidth - width -2 + base_x;
if(test_y + height > (Scr.MyDisplayHeight-2+base_y))
real_y = Scr.MyDisplayHeight - height -2+base_y;
if(test_x <base_x)
real_x = base_x;
if(test_y < base_y)
real_y = base_y;
loc_ok = True;
test_window = Scr.FvwmRoot.next;
while((test_window != (FvwmWindow *)0)&&(loc_ok == True))
{
if(test_window->Desk == t->Desk)
{
if((test_window->flags&ICONIFIED)&&
(test_window->icon_w||test_window->icon_pixmap_w)&&
(test_window != t))
{
tw=test_window->icon_p_width;
th=test_window->icon_p_height+
test_window->icon_w_height;
tx = test_window->icon_x_loc;
ty = test_window->icon_y_loc;
if((tx<(real_x+width+3))&&((tx+tw+3) > real_x)&&
(ty<(real_y+height+3))&&((ty+th + 3)>real_y))
{
loc_ok = False;
}
}
if(Scr.flags & StubbornIconPlacement)
{
if(!(test_window->flags&ICONIFIED)&&
(test_window!=t))
{
tw=test_window->frame_width;
th=test_window->frame_height;
tx = test_window->frame_x;
ty = test_window->frame_y;
if((tx < (real_x+width+3))&&
((tx+tw+3)>real_x)&&
(ty < (real_y+height+3))&&
((ty+th+3)>real_y))
{
loc_ok = False;
}
}
}
}
test_window = test_window->next;
}
test_x +=3;
}
test_y +=3;
}
i++;
}
if(loc_ok == False)
return;
t->icon_x_loc = real_x;
t->icon_y_loc = real_y;
}
if(t->icon_pixmap_w)
XMoveWindow(dpy,t->icon_pixmap_w,t->icon_x_loc, t->icon_y_loc);
t->icon_w_width = t->icon_p_width;
t->icon_xl_loc = t->icon_x_loc;
if (t->icon_w != None)
XMoveResizeWindow(dpy, t->icon_w, t->icon_xl_loc,
t->icon_y_loc+t->icon_p_height,
t->icon_w_width,ICON_HEIGHT);
Broadcast(M_ICON_LOCATION,7,t->w,t->frame,
(unsigned long)t,
t->icon_x_loc,t->icon_y_loc,
t->icon_w_width, t->icon_w_height+ t->icon_p_height);
}
/***********************************************************************
*
* Procedure:
* GrabIconButtons - grab needed buttons for the icon window
*
* Inputs:
* tmp_win - the fvwm window structure to use
*
***********************************************************************/
void GrabIconButtons(FvwmWindow *tmp_win, Window w)
{
MouseButton *MouseEntry;
MouseEntry = Scr.MouseButtonRoot;
while(MouseEntry != (MouseButton *)0)
{
if((MouseEntry->func != (int)0)&&(MouseEntry->Context & C_ICON))
{
if(MouseEntry->Button >0)
XGrabButton(dpy, MouseEntry->Button, MouseEntry->Modifier, w,
True, ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
Scr.FvwmCursors[DEFAULT]);
else
{
XGrabButton(dpy, 1, MouseEntry->Modifier, w,
True, ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
Scr.FvwmCursors[DEFAULT]);
XGrabButton(dpy, 2, MouseEntry->Modifier, w,
True, ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
Scr.FvwmCursors[DEFAULT]);
XGrabButton(dpy, 3, MouseEntry->Modifier, w,
True, ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
Scr.FvwmCursors[DEFAULT]);
}
}
MouseEntry = MouseEntry->NextButton;
}
return;
}
/***********************************************************************
*
* Procedure:
* GrabIconKeys - grab needed keys for the icon window
*
* Inputs:
* tmp_win - the fvwm window structure to use
*
***********************************************************************/
void GrabIconKeys(FvwmWindow *tmp_win,Window w)
{
FuncKey *tmp;
for (tmp = Scr.FuncKeyRoot.next; tmp != NULL; tmp = tmp->next)
{
if (tmp->cont & C_ICON)
XGrabKey(dpy, tmp->keycode, tmp->mods, w, True,
GrabModeAsync, GrabModeAsync);
}
return;
}
/****************************************************************************
*
* Looks for a monochrome icon bitmap file
*
****************************************************************************/
void GetBitmapFile(FvwmWindow *tmp_win)
{
char *path = NULL;
int HotX,HotY;
extern char *IconPath;
path = findIconFile(tmp_win->icon_bitmap_file, IconPath,R_OK);
if(path == NULL)return;
if(XReadBitmapFile (dpy, Scr.Root,path,
(unsigned int *)&tmp_win->icon_p_width,
(unsigned int *)&tmp_win->icon_p_height,
&tmp_win->iconPixmap,
&HotX, &HotY) != BitmapSuccess)
{
tmp_win->icon_p_width = 0;
tmp_win->icon_p_height = 0;
}
free(path);
}
/****************************************************************************
*
* Looks for a color XPM icon file
*
****************************************************************************/
void GetXPMFile(FvwmWindow *tmp_win)
{
#ifdef XPM
XWindowAttributes root_attr;
XpmAttributes xpm_attributes;
extern char *PixmapPath;
char *path = NULL;
path = findIconFile(tmp_win->icon_bitmap_file, PixmapPath,R_OK);
if(path == NULL)return;
XGetWindowAttributes(dpy,Scr.Root,&root_attr);
xpm_attributes.colormap = root_attr.colormap;
xpm_attributes.closeness = 40000; /* Allow for "similar" colors */
xpm_attributes.valuemask = XpmSize | XpmReturnPixels | XpmColormap | XpmCloseness;
if(XpmReadFileToPixmap(dpy, Scr.Root, path,
&tmp_win->iconPixmap,
&tmp_win->icon_maskPixmap,
&xpm_attributes) == XpmSuccess)
{
tmp_win->icon_p_width = xpm_attributes.width;
tmp_win->icon_p_height = xpm_attributes.height;
tmp_win->flags |= XPM_FLAG;
tmp_win->flags |= PIXMAP_OURS;
tmp_win->iconDepth = Scr.d_depth;
#ifdef SHAPE
if (tmp_win->icon_maskPixmap)
tmp_win->flags |= SHAPED_ICON;
#endif
}
free(path);
#endif /* XPM */
}
/****************************************************************************
*
* Looks for an application supplied icon window
*
****************************************************************************/
void GetIconWindow(FvwmWindow *tmp_win)
{
/* We are guaranteed that wmhints is non-null when calling this
* routine */
if(XGetGeometry(dpy, tmp_win->wmhints->icon_window, &JunkRoot,
&JunkX, &JunkY,(unsigned int *)&tmp_win->icon_p_width,
(unsigned int *)&tmp_win->icon_p_height,
&JunkBW, &JunkDepth)==0)
{
fprintf(stderr,"Help! Bad Icon Window!\n");
}
tmp_win->icon_p_width += JunkBW<<1;
tmp_win->icon_p_height += JunkBW<<1;
/*
* Now make the new window the icon window for this window,
* and set it up to work as such (select for key presses
* and button presses/releases, set up the contexts for it,
* and define the cursor for it).
*/
tmp_win->icon_pixmap_w = tmp_win->wmhints->icon_window;
#ifdef SHAPE
if (tmp_win->wmhints->flags & IconMaskHint)
{
tmp_win->flags |= SHAPED_ICON;
tmp_win->icon_maskPixmap = tmp_win->wmhints->icon_mask;
}
#endif
/* Make sure that the window is a child of the root window ! */
/* Olwais screws this up, maybe others do too! */
XReparentWindow(dpy, tmp_win->icon_pixmap_w, Scr.Root, 0,0);
tmp_win->flags &= ~ICON_OURS;
}
/****************************************************************************
*
* Looks for an application supplied bitmap or pixmap
*
****************************************************************************/
void GetIconBitmap(FvwmWindow *tmp_win)
{
/* We are guaranteed that wmhints is non-null when calling this
* routine */
XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap, &JunkRoot, &JunkX, &JunkY,
(unsigned int *)&tmp_win->icon_p_width,
(unsigned int *)&tmp_win->icon_p_height, &JunkBW, &JunkDepth);
tmp_win->iconPixmap = tmp_win->wmhints->icon_pixmap;
tmp_win->iconDepth = JunkDepth;
#ifdef SHAPE
if (tmp_win->wmhints->flags & IconMaskHint)
{
tmp_win->flags |= SHAPED_ICON;
tmp_win->icon_maskPixmap = tmp_win->wmhints->icon_mask;
}
#endif
}
/***********************************************************************
*
* Procedure:
* DeIconify a window
*
***********************************************************************/
void DeIconify(FvwmWindow *tmp_win)
{
FvwmWindow *t,*tmp;
int new_x,new_y,w2,h2;
/* now de-iconify transients */
for (t = Scr.FvwmRoot.next; t != NULL; t = t->next)
{
if ((t == tmp_win)||
((t->flags & TRANSIENT) &&(t->transientfor == tmp_win->w)))
{
t->flags |= MAPPED;
if(Scr.Hilite == t)
SetBorder (t, False,True,True,None);
/* make sure that the window is on this screen */
if((t->frame_x < 0)||(t->frame_y<0)||
(t->frame_x >= Scr.MyDisplayWidth)||
(t->frame_y >= Scr.MyDisplayHeight))
{
/* try to put at least half the window
* in the current screen, if the current desktop
* is the windows desktop */
if(Scr.flags & StubbornIcons)
t->Desk = t->DeIconifyDesk;
else
t->Desk = Scr.CurrentDesk;
if(t->Desk == Scr.CurrentDesk)
{
new_x = t->frame_x;
new_y = t->frame_y;
w2 = (t->frame_width>>1);
h2 = (t->frame_height>>1);
if(!(Scr.flags & StubbornIcons))
{
if (( new_x < -w2) || (new_x > (Scr.MyDisplayWidth-w2 )))
{
new_x = new_x % Scr.MyDisplayWidth;
if ( new_x < -w2 )
new_x += Scr.MyDisplayWidth;
}
if ((new_y < -h2) || (new_y > (Scr.MyDisplayHeight-h2 )))
{
new_y = new_y % Scr.MyDisplayHeight;
if ( new_y < -h2 )
new_y += Scr.MyDisplayHeight;
}
}
SetupFrame(t,new_x,new_y,
t->frame_width,t->frame_height,False);
}
}
XMapWindow(dpy, t->w);
if(t->Desk == Scr.CurrentDesk)
{
XMapWindow(dpy, t->frame);
t->flags |= MAP_PENDING;
}
XMapWindow(dpy, t->Parent);
SetMapStateProp(t, NormalState);
t->flags &= ~ICONIFIED;
t->flags &= ~ICON_UNMAPPED;
/* Need to make sure the border is colored correctly,
* in case it was stuck or unstuck while iconified. */
tmp = Scr.Hilite;
Scr.Hilite = t;
SetBorder(t,False,True,True,None);
Scr.Hilite = tmp;
XRaiseWindow(dpy,t->w);
if (t->icon_w)
XUnmapWindow(dpy, t->icon_w);
if (t->icon_pixmap_w)
XUnmapWindow(dpy, t->icon_pixmap_w);
Broadcast(M_DEICONIFY,3,t->w,t->frame,(unsigned long)t,0,0,0,0);
}
}
RaiseWindow(tmp_win);
if((Scr.flags & StubbornIcons)||(Scr.flags & ClickToFocus))
FocusOn(tmp_win,1);
KeepOnTop();
MoveResizePagerView(tmp_win);
return;
}
/****************************************************************************
*
* Iconifies the selected window
*
****************************************************************************/
void Iconify(FvwmWindow *tmp_win, int def_x, int def_y)
{
FvwmWindow *t;
XWindowAttributes winattrs;
unsigned long eventMask;
XGetWindowAttributes(dpy, tmp_win->w, &winattrs);
eventMask = winattrs.your_event_mask;
if((tmp_win)&&(tmp_win == Scr.Hilite)&&
(Scr.flags & ClickToFocus)&&(tmp_win->next))
{
SetFocus(tmp_win->next->w,tmp_win->next);
ClearCirculatedFlag();
}
/* iconify transients first */
for (t = Scr.FvwmRoot.next; t != NULL; t = t->next)
{
if ((t==tmp_win)||
((t->flags & TRANSIENT) && (t->transientfor == tmp_win->w)))
{
/*
* Prevent the receipt of an UnmapNotify, since that would
* cause a transition to the Withdrawn state.
*/
t->flags &= ~MAPPED;
XSelectInput(dpy, t->w, eventMask & ~StructureNotifyMask);
XUnmapWindow(dpy, t->w);
XSelectInput(dpy, t->w, eventMask);
XUnmapWindow(dpy, t->frame);
t->DeIconifyDesk = t->Desk;
if (t->icon_w)
XUnmapWindow(dpy, t->icon_w);
if (t->icon_pixmap_w)
XUnmapWindow(dpy, t->icon_pixmap_w);
SetMapStateProp(t, IconicState);
SetBorder (t, False,False,False,None);
if(t != tmp_win)
{
t->flags |= ICONIFIED|ICON_UNMAPPED;
Broadcast(M_ICONIFY,7,t->w,t->frame,
(unsigned long)t,
-10000, -10000,
t->icon_w_width,
t->icon_w_height+t->icon_p_height);
BroadcastConfig(M_CONFIGURE_WINDOW,t);
}
if(t!= tmp_win)
MoveResizePagerView(t);
}
}
if (tmp_win->icon_w == None)
if(tmp_win->flags & ICON_MOVED)
CreateIconWindow(tmp_win,tmp_win->icon_x_loc,tmp_win->icon_y_loc);
else
CreateIconWindow(tmp_win, def_x, def_y);
AutoPlace(tmp_win);
tmp_win->flags |= ICONIFIED;
tmp_win->flags &= ~ICON_UNMAPPED;
Broadcast(M_ICONIFY,7,tmp_win->w,tmp_win->frame,
(unsigned long)tmp_win,
tmp_win->icon_x_loc,tmp_win->icon_y_loc,
tmp_win->icon_w_width,
tmp_win->icon_w_height+tmp_win->icon_p_height);
BroadcastConfig(M_CONFIGURE_WINDOW,tmp_win);
LowerWindow(tmp_win);
if(tmp_win->Desk == Scr.CurrentDesk)
{
if (tmp_win->icon_w != None)
XMapWindow(dpy, tmp_win->icon_w);
if(tmp_win->icon_pixmap_w != None)
XMapWindow(dpy, tmp_win->icon_pixmap_w);
KeepOnTop();
MoveResizePagerView(tmp_win);
}
if((Scr.flags & ClickToFocus)||(Scr.flags & SloppyFocus))
{
if ((tmp_win)&&(tmp_win == Scr.Focus))
{
if(Scr.PreviousFocus == Scr.Focus)
Scr.PreviousFocus = NULL;
if((Scr.flags & ClickToFocus)&&(tmp_win->next))
SetFocus(tmp_win->next->w, tmp_win->next);
else
{
SetFocus(Scr.NoFocusWin, NULL);
}
ClearCirculatedFlag();
}
}
return;
}