1 /* This program is free software; you can redistribute it and/or modify
2 * it under the terms of the GNU General Public License as published by
3 * the Free Software Foundation; either version 2 of the License, or
4 * (at your option) any later version.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 /****************************************************************************
17 * This module is mostly all new
19 * A little of it is borrowed from ctwm.
20 * Copyright 1993 Robert Nation. No restrictions are placed on this code,
21 * as long as the copyright notice is preserved
22 ****************************************************************************/
23 /***********************************************************************
27 ***********************************************************************/
35 #include <X11/Intrinsic.h>
40 #include "libs/fvwmlib.h"
45 #include "functions.h"
54 #include "colormaps.h"
57 #include "decorations.h"
58 #include "module_interface.h"
59 #include "libs/Colorset.h"
64 #include <X11/extensions/shape.h>
67 static int do_all_iconboxes(FvwmWindow
*t
, icon_boxes
**icon_boxes_ptr
);
68 static void GetBitmapFile(FvwmWindow
*tmp_win
);
69 static void GetXPMFile(FvwmWindow
*tmp_win
);
73 /****************************************************************************
75 * Creates an icon window as needed
77 ****************************************************************************/
78 void CreateIconWindow(FvwmWindow
*tmp_win
, int def_x
, int def_y
)
80 /* mask for create windows */
81 unsigned long valuemask
;
82 /* attributes for create windows */
83 XSetWindowAttributes attributes
;
86 SET_ICON_OURS(tmp_win
, 1);
87 SET_PIXMAP_OURS(tmp_win
, 0);
88 SET_ICON_SHAPED(tmp_win
, 0);
89 tmp_win
->icon_pixmap_w
= None
;
90 tmp_win
->iconPixmap
= None
;
91 tmp_win
->iconDepth
= 0;
93 if (IS_ICON_SUPPRESSED(tmp_win
))
96 /* First, see if it was specified in the .fvwmrc */
97 tmp_win
->icon_p_height
= 0;
98 tmp_win
->icon_p_width
= 0;
100 /* First, check for a monochrome bitmap */
101 if (tmp_win
->icon_bitmap_file
!= NULL
)
102 GetBitmapFile(tmp_win
);
105 /* Next, check for a color pixmap */
106 if ((tmp_win
->icon_bitmap_file
!= NULL
) && (tmp_win
->icon_p_height
== 0)
107 && (tmp_win
->icon_p_width
== 0))
111 /* Next, See if the app supplies its own icon window */
112 if ((tmp_win
->icon_p_height
== 0) && (tmp_win
->icon_p_width
== 0)
113 && (tmp_win
->wmhints
) && (tmp_win
->wmhints
->flags
& IconWindowHint
))
114 GetIconWindow(tmp_win
);
116 /* Finally, try to get icon bitmap from the application */
117 if ((tmp_win
->icon_p_height
== 0) && (tmp_win
->icon_p_width
== 0)
118 && (tmp_win
->wmhints
) && (tmp_win
->wmhints
->flags
& IconPixmapHint
))
119 GetIconBitmap(tmp_win
);
121 /* figure out the icon window size */
122 if (!HAS_NO_ICON_TITLE(tmp_win
))
124 tmp_win
->icon_t_width
=
125 XTextWidth(tmp_win
->icon_font
.font
, tmp_win
->icon_name
,
126 strlen(tmp_win
->icon_name
));
127 tmp_win
->icon_g
.height
= ICON_HEIGHT(tmp_win
);
131 tmp_win
->icon_t_width
= 0;
132 tmp_win
->icon_g
.height
= 0;
135 /* make space for relief to be drawn outside the icon */
136 /* this does not happen if fvwm is using a non-default visual (with
137 private colormap) and the client has supplied a pixmap (not a bitmap) */
138 if ((IS_ICON_OURS(tmp_win
)) && (tmp_win
->icon_p_height
> 0)
139 && (Pdefault
|| (tmp_win
->iconDepth
== 1) || IS_PIXMAP_OURS(tmp_win
)))
141 tmp_win
->icon_p_width
+= 4;
142 tmp_win
->icon_p_height
+= 4;
145 if (tmp_win
->icon_p_width
== 0)
146 tmp_win
->icon_p_width
= tmp_win
->icon_t_width
+ 6;
147 tmp_win
->icon_g
.width
= tmp_win
->icon_p_width
;
149 tmp_win
->icon_g
.x
= tmp_win
->icon_xl_loc
= def_x
;
150 tmp_win
->icon_g
.y
= def_y
;
152 /* create the icon title window */
153 valuemask
= CWColormap
| CWBorderPixel
154 | CWBackPixel
| CWCursor
| CWEventMask
;
155 attributes
.colormap
= Pcmap
;
156 attributes
.background_pixel
= Scr
.StdBack
;
157 attributes
.cursor
= Scr
.FvwmCursors
[CRS_DEFAULT
];
158 attributes
.border_pixel
= 0;
159 attributes
.event_mask
= (ButtonPressMask
| ButtonReleaseMask
160 | VisibilityChangeMask
| ExposureMask
| KeyPressMask
161 | EnterWindowMask
| LeaveWindowMask
163 if (!HAS_NO_ICON_TITLE(tmp_win
))
167 dpy
, Scr
.Root
, def_x
, def_y
+ tmp_win
->icon_p_height
,
168 tmp_win
->icon_g
.width
, tmp_win
->icon_g
.height
, 0, Pdepth
,
169 InputOutput
, Pvisual
, valuemask
, &attributes
);
171 if (Scr
.DefaultColorset
>= 0)
172 SetWindowBackground(dpy
, tmp_win
->icon_w
, tmp_win
->icon_g
.width
,
173 tmp_win
->icon_g
.height
, &Colorset
[Scr
.DefaultColorset
],
174 Pdepth
, Scr
.StdGC
, False
);
176 /* create a window to hold the picture */
177 if((IS_ICON_OURS(tmp_win
)) && (tmp_win
->icon_p_width
> 0)
178 && (tmp_win
->icon_p_height
> 0))
180 /* use fvwm's visuals in these cases */
181 if (Pdefault
|| (tmp_win
->iconDepth
== 1) || IS_PIXMAP_OURS(tmp_win
))
183 tmp_win
->icon_pixmap_w
=
185 dpy
, Scr
.Root
, def_x
, def_y
, tmp_win
->icon_p_width
,
186 tmp_win
->icon_p_height
, 0, Pdepth
, InputOutput
, Pvisual
, valuemask
,
188 if (Scr
.DefaultColorset
>= 0)
189 SetWindowBackground(dpy
, tmp_win
->icon_w
, tmp_win
->icon_p_width
,
190 tmp_win
->icon_p_height
,
191 &Colorset
[Scr
.DefaultColorset
], Pdepth
, Scr
.StdGC
,
196 /* client supplied icon pixmap and fvwm is using another visual */
197 /* use it as the background pixmap, don't try to put relief on it
198 * because fvwm will not have the correct colors
199 * the Exceed server has problems maintaining the icon window, it usually
200 * fails to refresh the icon leaving it black so ask for expose events */
201 attributes
.background_pixmap
= tmp_win
->iconPixmap
;
202 attributes
.colormap
= DefaultColormap(dpy
, Scr
.screen
);
203 valuemask
&= ~CWBackPixel
;
204 valuemask
|= CWBackPixmap
;
205 tmp_win
->icon_pixmap_w
=
207 dpy
, Scr
.Root
, def_x
, def_y
, tmp_win
->icon_p_width
,
208 tmp_win
->icon_p_height
, 0, DefaultDepth(dpy
, Scr
.screen
), InputOutput
,
209 DefaultVisual(dpy
, Scr
.screen
), valuemask
, &attributes
);
214 /* client supplied icon window: select events on it */
215 attributes
.event_mask
= ButtonPressMask
| ButtonReleaseMask
| KeyPressMask
216 | VisibilityChangeMask
| FocusChangeMask
217 | EnterWindowMask
| LeaveWindowMask
;
218 valuemask
= CWEventMask
;
219 XChangeWindowAttributes(dpy
, tmp_win
->icon_pixmap_w
, valuemask
,&attributes
);
224 if (ShapesSupported
&& IS_ICON_SHAPED(tmp_win
))
226 /* when fvwm is using the non-default visual client supplied icon pixmaps
227 * are drawn in a window with no relief */
228 int off
= (Pdefault
|| (tmp_win
->iconDepth
== 1) || IS_PIXMAP_OURS(tmp_win
))
230 XShapeCombineMask(dpy
, tmp_win
->icon_pixmap_w
, ShapeBounding
, off
, off
,
231 tmp_win
->icon_maskPixmap
, ShapeSet
);
235 if(tmp_win
->icon_w
!= None
)
237 XSaveContext(dpy
, tmp_win
->icon_w
, FvwmContext
, (caddr_t
)tmp_win
);
238 XDefineCursor(dpy
, tmp_win
->icon_w
, Scr
.FvwmCursors
[CRS_DEFAULT
]);
239 GrabAllWindowKeysAndButtons(dpy
, tmp_win
->icon_w
, Scr
.AllBindings
,
240 C_ICON
, GetUnusedModifiers(),
241 Scr
.FvwmCursors
[CRS_DEFAULT
], True
);
243 xwc
.sibling
= tmp_win
->frame
;
244 xwc
.stack_mode
= Below
;
245 XConfigureWindow(dpy
, tmp_win
->icon_w
, CWSibling
|CWStackMode
, &xwc
);
247 if(tmp_win
->icon_pixmap_w
!= None
)
249 XSaveContext(dpy
, tmp_win
->icon_pixmap_w
, FvwmContext
, (caddr_t
)tmp_win
);
250 XDefineCursor(dpy
, tmp_win
->icon_pixmap_w
, Scr
.FvwmCursors
[CRS_DEFAULT
]);
251 GrabAllWindowKeysAndButtons(dpy
, tmp_win
->icon_pixmap_w
, Scr
.AllBindings
,
252 C_ICON
, GetUnusedModifiers(),
253 Scr
.FvwmCursors
[CRS_DEFAULT
], True
);
255 xwc
.sibling
= tmp_win
->frame
;
256 xwc
.stack_mode
= Below
;
257 XConfigureWindow(dpy
,tmp_win
->icon_pixmap_w
,CWSibling
|CWStackMode
,&xwc
);
262 /****************************************************************************
264 * Draws the icon window
266 ****************************************************************************/
267 void DrawIconWindow(FvwmWindow
*tmp_win
)
274 color_quad
*draw_colors
;
276 if(IS_ICON_SUPPRESSED(tmp_win
))
279 if(tmp_win
->icon_w
!= None
)
280 flush_expose (tmp_win
->icon_w
);
281 if(tmp_win
->icon_pixmap_w
!= None
)
282 flush_expose (tmp_win
->icon_pixmap_w
);
284 if(Scr
.Hilite
== tmp_win
)
285 draw_colors
= &(tmp_win
->hicolors
);
287 draw_colors
= &(tmp_win
->colors
);
288 if (Pdepth
< 2 && Scr
.Hilite
!= tmp_win
)
290 Relief
= Scr
.StdReliefGC
;
291 Shadow
= Scr
.StdShadowGC
;
295 if (Pdepth
< 2 && Scr
.Hilite
== tmp_win
)
296 Relief
= Scr
.ScratchGC2
;
299 Globalgcv
.foreground
= draw_colors
->hilight
;
300 Globalgcm
= GCForeground
;
301 XChangeGC(dpy
,Scr
.ScratchGC1
,Globalgcm
,&Globalgcv
);
302 Relief
= Scr
.ScratchGC1
;
304 Globalgcv
.foreground
= draw_colors
->shadow
;
305 XChangeGC(dpy
,Scr
.ScratchGC2
, Globalgcm
, &Globalgcv
);
306 Shadow
= Scr
.ScratchGC2
;
308 TextColor
= draw_colors
->fore
;
309 BackColor
= draw_colors
->back
;
311 if(tmp_win
->icon_w
!= None
)
313 if (IS_ICON_ENTERED(tmp_win
))
315 /* resize the icon name window */
316 tmp_win
->icon_g
.width
= tmp_win
->icon_t_width
+ 8;
317 if (IS_STICKY(tmp_win
) || IS_ICON_STICKY(tmp_win
))
318 tmp_win
->icon_g
.width
+= 10;
319 if(tmp_win
->icon_g
.width
< tmp_win
->icon_p_width
)
320 tmp_win
->icon_g
.width
= tmp_win
->icon_p_width
;
321 tmp_win
->icon_xl_loc
= tmp_win
->icon_g
.x
-
322 (tmp_win
->icon_g
.width
- tmp_win
->icon_p_width
)/2;
323 /* start keep label on screen. dje 8/7/97 */
324 if (tmp_win
->icon_xl_loc
< 0) { /* if new loc neg (off left edge) */
325 tmp_win
->icon_xl_loc
= 0; /* move to edge */
326 } else { /* if not on left edge */
327 /* if (new loc + width) > screen width (off edge on right) */
328 if ((tmp_win
->icon_xl_loc
+ tmp_win
->icon_g
.width
) >
329 Scr
.MyDisplayWidth
) { /* off right */
330 /* position up against right edge */
331 tmp_win
->icon_xl_loc
= Scr
.MyDisplayWidth
-tmp_win
->icon_g
.width
;
333 /* end keep label on screen. dje 8/7/97 */
338 /* resize the icon name window */
339 tmp_win
->icon_g
.width
= tmp_win
->icon_p_width
;
340 tmp_win
->icon_xl_loc
= tmp_win
->icon_g
.x
;
344 /* set up TitleGC for drawing the icon label */
345 if (tmp_win
->icon_font
.font
!= None
)
346 NewFontAndColor(tmp_win
->icon_font
.font
->fid
, TextColor
, BackColor
);
347 if(tmp_win
->icon_w
!= None
)
349 tmp_win
->icon_g
.height
= ICON_HEIGHT(tmp_win
);
350 XMoveResizeWindow(dpy
, tmp_win
->icon_w
, tmp_win
->icon_xl_loc
,
351 tmp_win
->icon_g
.y
+ tmp_win
->icon_p_height
,
352 tmp_win
->icon_g
.width
,ICON_HEIGHT(tmp_win
));
353 XSetWindowBackground(dpy
, tmp_win
->icon_w
, BackColor
);
354 XClearWindow(dpy
,tmp_win
->icon_w
);
357 x
= (tmp_win
->icon_g
.width
- tmp_win
->icon_t_width
) / 2;
360 if ((IS_STICKY(tmp_win
) || IS_ICON_STICKY(tmp_win
)))
368 r
.width
= tmp_win
->icon_g
.width
- 7;
369 r
.height
= ICON_HEIGHT(tmp_win
);
370 XSetClipRectangles(dpy
, Scr
.TitleGC
, 0, 0, &r
, 1, Unsorted
);
373 XmbDrawString (dpy
, tmp_win
->icon_w
, tmp_win
->icon_font
.fontset
,
375 XDrawString (dpy
, tmp_win
->icon_w
,
378 tmp_win
->icon_g
.height
- tmp_win
->icon_font
.height
+
379 tmp_win
->icon_font
.y
- 3, tmp_win
->icon_name
,
380 strlen(tmp_win
->icon_name
));
381 RelieveRectangle(dpy
, tmp_win
->icon_w
, 0, 0, tmp_win
->icon_g
.width
- 1,
382 ICON_HEIGHT(tmp_win
) - 1, Relief
, Shadow
, 2);
383 if (IS_STICKY(tmp_win
) || IS_ICON_STICKY(tmp_win
))
385 /* an odd number of lines every 4 pixels */
386 int num
= (ICON_HEIGHT(tmp_win
) / 8) * 2 - 1;
387 int min
= ICON_HEIGHT(tmp_win
) / 2 - num
* 2 + 1;
388 int max
= ICON_HEIGHT(tmp_win
) / 2 + num
* 2 - 3;
390 int stipple_w
= x
- 6;
394 for(i
= min
; i
<= max
; i
+= 4)
397 dpy
, tmp_win
->icon_w
, 2, i
, stipple_w
, 1, Shadow
, Relief
, 1);
399 dpy
, tmp_win
->icon_w
, tmp_win
->icon_g
.width
- 3 - stipple_w
, i
,
400 stipple_w
, 1, Shadow
, Relief
, 1);
402 XSetClipMask(dpy
, Scr
.TitleGC
, None
);
406 if(tmp_win
->icon_pixmap_w
!= None
)
408 XMoveWindow(dpy
, tmp_win
->icon_pixmap_w
, tmp_win
->icon_g
.x
,
412 /* only relieve unshaped icons that share fvwm's visual */
413 if ((tmp_win
->iconPixmap
!= None
) && !IS_ICON_SHAPED(tmp_win
)
414 && (Pdefault
|| (tmp_win
->iconDepth
== 1) || IS_PIXMAP_OURS(tmp_win
)))
415 RelieveRectangle(dpy
, tmp_win
->icon_pixmap_w
, 0, 0,
416 tmp_win
->icon_p_width
- 1, tmp_win
->icon_p_height
- 1,
419 /* need to locate the icon pixmap */
420 if (tmp_win
->iconPixmap
!= None
)
422 if (tmp_win
->iconDepth
== 1)
425 XCopyPlane(dpy
, tmp_win
->iconPixmap
, tmp_win
->icon_pixmap_w
,
426 Scr
.TitleGC
, 0, 0, tmp_win
->icon_p_width
- 4,
427 tmp_win
->icon_p_height
- 4, 2, 2, 1);
431 if (Pdefault
|| IS_PIXMAP_OURS(tmp_win
))
433 /* it's a pixmap that need copying */
434 XCopyArea(dpy
, tmp_win
->iconPixmap
, tmp_win
->icon_pixmap_w
,
435 Scr
.TitleGC
, 0, 0, tmp_win
->icon_p_width
- 4,
436 tmp_win
->icon_p_height
- 4, 2, 2);
440 /* it's a client pixmap and fvwm is not using the root visual
441 * The icon window has no 3d border so copy to (0,0)
442 * install the root colormap temporarily to help the Exceed server */
443 if (Scr
.bo
.InstallRootCmap
)
444 InstallRootColormap();
445 XCopyArea(dpy
, tmp_win
->iconPixmap
, tmp_win
->icon_pixmap_w
,
446 DefaultGC(dpy
, Scr
.screen
), 0, 0, tmp_win
->icon_p_width
,
447 tmp_win
->icon_p_height
, 0, 0);
448 if (Scr
.bo
.InstallRootCmap
)
449 UninstallRootColormap();
454 if (IS_ICON_ENTERED(tmp_win
))
456 if (tmp_win
->icon_w
!= None
)
458 XRaiseWindow (dpy
, tmp_win
->icon_w
);
466 xwc
.sibling
= tmp_win
->frame
;
467 xwc
.stack_mode
= Below
;
468 mask
= CWSibling
|CWStackMode
;
469 if (tmp_win
->icon_w
!= None
)
471 XConfigureWindow(dpy
, tmp_win
->icon_w
, mask
, &xwc
);
473 if (tmp_win
->icon_pixmap_w
!= None
)
475 XConfigureWindow(dpy
, tmp_win
->icon_pixmap_w
, mask
, &xwc
);
481 /***********************************************************************
484 * RedoIconName - procedure to re-position the icon window and name
486 ************************************************************************/
487 void RedoIconName(FvwmWindow
*tmp_win
)
489 if(IS_ICON_SUPPRESSED(tmp_win
))
492 if (tmp_win
->icon_w
== (int)NULL
)
495 if (HAS_NO_ICON_TITLE(tmp_win
))
496 tmp_win
->icon_t_width
= 0;
498 tmp_win
->icon_t_width
=
499 XTextWidth(tmp_win
->icon_font
.font
,tmp_win
->icon_name
,
500 strlen(tmp_win
->icon_name
));
501 /* clear the icon window, and trigger a re-draw via an expose event */
502 if (IS_ICONIFIED(tmp_win
))
503 DrawIconWindow(tmp_win
);
504 if (IS_ICONIFIED(tmp_win
))
505 XClearArea(dpy
, tmp_win
->icon_w
, 0, 0, 0, 0, True
);
512 /************************************************************************
515 * AutoPlace - Find a home for an icon
517 ************************************************************************/
518 void AutoPlaceIcon(FvwmWindow
*t
)
523 FvwmWindow
*test_window
;
525 int real_x
=10, real_y
=10;
527 Bool do_move_pixmap
= False
;
528 Bool do_move_title
= False
;
530 /* New! Put icon in same page as the center of the window */
531 /* Not a good idea for StickyIcons. Neither for icons of windows that are
532 * visible on the current page. */
533 if(IS_ICON_STICKY(t
)||IS_STICKY(t
))
537 /*Also, if its a stickyWindow, put it on the current page! */
538 new_x
= t
->frame_g
.x
% Scr
.MyDisplayWidth
;
539 new_y
= t
->frame_g
.y
% Scr
.MyDisplayHeight
;
540 if(new_x
+ t
->frame_g
.width
<= 0)
541 new_x
+= Scr
.MyDisplayWidth
;
542 if(new_y
+ t
->frame_g
.height
<= 0)
543 new_y
+= Scr
.MyDisplayHeight
;
544 SetupFrame(t
, new_x
, new_y
, t
->frame_g
.width
, t
->frame_g
.height
, False
);
545 t
->Desk
= Scr
.CurrentDesk
;
547 else if (IsRectangleOnThisPage(&(t
->frame_g
), t
->Desk
))
554 base_x
=((t
->frame_g
.x
+Scr
.Vx
+(t
->frame_g
.width
>>1))/Scr
.MyDisplayWidth
)*
556 base_y
=((t
->frame_g
.y
+Scr
.Vy
+(t
->frame_g
.height
>>1))/
557 Scr
.MyDisplayHeight
)*Scr
.MyDisplayHeight
;
558 /* limit icon position to desktop */
559 if (base_x
> Scr
.VxMax
)
563 if (base_y
> Scr
.VyMax
)
572 /* just make sure the icon is on this screen */
573 t
->icon_g
.x
= t
->icon_g
.x
% Scr
.MyDisplayWidth
+ base_x
;
574 t
->icon_g
.y
= t
->icon_g
.y
% Scr
.MyDisplayHeight
+ base_y
;
576 t
->icon_g
.x
+= Scr
.MyDisplayWidth
;
578 t
->icon_g
.y
+= Scr
.MyDisplayHeight
;
579 t
->icon_xl_loc
= t
->icon_g
.x
;
580 do_move_pixmap
= True
;
581 do_move_title
= True
;
583 else if (USE_ICON_POSITION_HINT(t
) && t
->wmhints
&&
584 t
->wmhints
->flags
& IconPositionHint
)
586 t
->icon_g
.x
= t
->wmhints
->icon_x
;
587 t
->icon_g
.y
= t
->wmhints
->icon_y
;
588 t
->icon_xl_loc
= t
->icon_g
.x
;
591 Look thru chain of icon boxes assigned to window.
592 Add logic for grids and fill direction.
596 /* A place to hold inner and outer loop variables. */
597 typedef struct dimension_struct
599 int step
; /* grid size (may be negative) */
600 int start_at
; /* starting edge */
601 int real_start
; /* on screen starting edge */
602 int end_at
; /* ending edge */
603 int base
; /* base for screen */
604 int icon_dimension
; /* height or width */
605 int nom_dimension
; /* nonminal height or width */
606 int screen_dimension
; /* screen height or width */
608 dimension dim
[3]; /* space for work, 1st, 2nd dimen */
609 icon_boxes
*icon_boxes_ptr
; /* current icon box */
610 int i
; /* index for inner/outer loop data */
612 /* Hopefully this makes the following more readable. */
613 #define ICONBOX_LFT icon_boxes_ptr->IconBox[0]
614 #define ICONBOX_TOP icon_boxes_ptr->IconBox[1]
615 #define ICONBOX_RGT icon_boxes_ptr->IconBox[2]
616 #define ICONBOX_BOT icon_boxes_ptr->IconBox[3]
617 #define BOT_FILL icon_boxes_ptr->IconFlags & ICONFILLBOT
618 #define RGT_FILL icon_boxes_ptr->IconFlags & ICONFILLRGT
619 #define HRZ_FILL icon_boxes_ptr->IconFlags & ICONFILLHRZ
621 /* unnecessary copy of width */
622 width
= t
->icon_p_width
;
624 height
= t
->icon_g
.height
+ t
->icon_p_height
;
625 /* no slot found yet */
628 /* check all boxes in order */
629 icon_boxes_ptr
= NULL
; /* init */
630 while(do_all_iconboxes(t
, &icon_boxes_ptr
))
638 dim
[1].step
= icon_boxes_ptr
->IconGrid
[1];
639 /* init start from */
640 dim
[1].start_at
= ICONBOX_TOP
;
642 dim
[1].end_at
= ICONBOX_BOT
;
644 dim
[1].base
= base_y
;
646 dim
[1].icon_dimension
= height
;
647 dim
[1].screen_dimension
= Scr
.MyDisplayHeight
;
650 /* fill from bottom */
652 dim
[1].step
= 0 - dim
[1].step
;
653 } /* end fill from bottom */
656 dim
[2].step
= icon_boxes_ptr
->IconGrid
[0];
657 /* init start from */
658 dim
[2].start_at
= ICONBOX_LFT
;
660 dim
[2].end_at
= ICONBOX_RGT
;
662 dim
[2].base
= base_x
;
664 dim
[2].icon_dimension
= width
;
665 dim
[2].screen_dimension
= Scr
.MyDisplayWidth
;
668 /* fill from right */
670 dim
[2].step
= 0 - dim
[2].step
;
671 } /* end fill from right */
674 /* for dimensions 1 and 2 */
675 /* If the window is taller than the icon box, ignore the icon height
676 * when figuring where to put it. Same goes for the width
677 * This should permit reasonably graceful handling of big icons. */
678 dim
[i
].nom_dimension
= dim
[i
].icon_dimension
;
679 if (dim
[i
].icon_dimension
>= dim
[i
].end_at
- dim
[i
].start_at
)
681 dim
[i
].nom_dimension
= dim
[i
].end_at
- dim
[i
].start_at
- 1;
685 /* if moving backwards */
687 dim
[0].start_at
= dim
[i
].start_at
;
689 dim
[i
].start_at
= dim
[i
].end_at
;
691 dim
[i
].end_at
= dim
[0].start_at
;
692 dim
[i
].start_at
-= dim
[i
].icon_dimension
;
693 } /* end moving backwards */
694 /* adjust both to base */
695 dim
[i
].start_at
+= dim
[i
].base
;
696 dim
[i
].end_at
+= dim
[i
].base
;
697 } /* end 2 dimensions */
702 memcpy(&dim
[0],&dim
[1],sizeof(dimension
));
704 memcpy(&dim
[1],&dim
[2],sizeof(dimension
));
705 /* switch the other */
706 memcpy(&dim
[2],&dim
[0],sizeof(dimension
));
707 } /* end horizontal dimension first */
708 /* save for reseting inner loop */
709 dim
[0].start_at
= dim
[2].start_at
;
710 while((dim
[1].step
< 0 /* filling reversed */
711 ? (dim
[1].start_at
+ dim
[1].icon_dimension
- dim
[1].nom_dimension
712 > dim
[1].end_at
) /* check back edge */
713 : (dim
[1].start_at
+ dim
[1].nom_dimension
714 < dim
[1].end_at
)) /* check front edge */
715 && (!loc_ok
)) { /* nothing found yet */
716 dim
[1].real_start
= dim
[1].start_at
; /* init */
717 if (dim
[1].start_at
+ dim
[1].icon_dimension
>
718 dim
[1].screen_dimension
- 2 + dim
[1].base
)
720 /* off screen, move on screen */
721 dim
[1].real_start
= dim
[1].screen_dimension
722 - dim
[1].icon_dimension
+ dim
[1].base
;
723 } /* end off screen */
724 if (dim
[1].start_at
< dim
[1].base
)
726 /* if off other edge, move on screen */
727 dim
[1].real_start
= dim
[1].base
;
728 } /* end off other edge */
729 /* reset inner loop */
730 dim
[2].start_at
= dim
[0].start_at
;
731 while((dim
[2].step
< 0 /* filling reversed */
732 ? (dim
[2].start_at
+ dim
[2].icon_dimension
-dim
[2].nom_dimension
733 > dim
[2].end_at
) /* check back edge */
734 : (dim
[2].start_at
+ dim
[2].nom_dimension
735 < dim
[2].end_at
)) /* check front edge */
736 && (!loc_ok
)) { /* nothing found yet */
737 dim
[2].real_start
= dim
[2].start_at
; /* init */
738 if (dim
[2].start_at
+ dim
[2].icon_dimension
>
739 dim
[2].screen_dimension
- 2 + dim
[2].base
)
741 /* if off screen, move on screen */
742 dim
[2].real_start
= dim
[2].screen_dimension
743 - dim
[2].icon_dimension
+ dim
[2].base
;
744 } /* end off screen */
745 if (dim
[2].start_at
< dim
[2].base
)
747 /* if off other edge, move on screen */
748 dim
[2].real_start
= dim
[2].base
;
749 } /* end off other edge */
755 real_x
= dim
[1].real_start
;
756 real_y
= dim
[2].real_start
;
761 real_x
= dim
[2].real_start
;
762 real_y
= dim
[1].real_start
;
765 /* this may be a good location */
767 test_window
= Scr
.FvwmRoot
.next
;
768 while((test_window
!= (FvwmWindow
*)0)
772 if(test_window
->Desk
== t
->Desk
)
774 if((IS_ICONIFIED(test_window
)) &&
775 (!IS_TRANSIENT(test_window
) ||
776 !IS_ICONIFIED_BY_PARENT(test_window
)) &&
777 (test_window
->icon_w
||test_window
->icon_pixmap_w
) &&
778 (test_window
!= t
)) {
779 tw
=test_window
->icon_p_width
;
780 th
=test_window
->icon_p_height
+
781 test_window
->icon_g
.height
;
782 tx
= test_window
->icon_g
.x
;
783 ty
= test_window
->icon_g
.y
;
785 if((tx
<(real_x
+width
+3))&&((tx
+tw
+3) > real_x
)&&
786 (ty
<(real_y
+height
+3))&&((ty
+th
+ 3)>real_y
))
788 /* don't accept this location */
790 } /* end if icons overlap */
791 } /* end if its an icon */
792 } /* end if same desk */
793 test_window
= test_window
->next
;
794 } /* end while icons that may overlap */
795 /* Grid inner value & direction */
796 dim
[2].start_at
+= dim
[2].step
;
797 } /* end while room inner dimension */
798 /* Grid outer value & direction */
799 dim
[1].start_at
+= dim
[1].step
;
800 } /* end while room outer dimension */
801 } /* end for all icon boxes, or found space */
803 /* If icon never found a home just leave it */
805 t
->icon_g
.x
= real_x
;
806 t
->icon_g
.y
= real_y
;
809 XMoveWindow(dpy
,t
->icon_pixmap_w
,t
->icon_g
.x
, t
->icon_g
.y
);
811 t
->icon_g
.width
= t
->icon_p_width
;
812 t
->icon_xl_loc
= t
->icon_g
.x
;
814 do_move_title
= True
;
815 BroadcastPacket(M_ICON_LOCATION
, 7,
818 t
->icon_g
.x
, t
->icon_g
.y
,
819 t
->icon_p_width
, t
->icon_g
.height
+t
->icon_p_height
);
821 if (do_move_pixmap
&& t
->icon_pixmap_w
!= None
)
823 XMoveWindow(dpy
, t
->icon_pixmap_w
, t
->icon_g
.x
, t
->icon_g
.y
);
825 if (do_move_title
&& t
->icon_w
!= None
)
828 dpy
, t
->icon_w
, t
->icon_xl_loc
, t
->icon_g
.y
+t
->icon_p_height
,
829 t
->icon_g
.width
, ICON_HEIGHT(t
));
833 static icon_boxes
*global_icon_box_ptr
;
834 /* Find next icon box to try to place icon in.
835 Goes thru chain that the window got thru style matching,
836 then the global icon box.
837 Create the global icon box on first call.
838 Return code indicates when the boxes are used up.
839 The boxes could only get completely used up when you fill the screen
843 do_all_iconboxes(FvwmWindow
*t
, icon_boxes
**icon_boxes_ptr
)
845 if (global_icon_box_ptr
== 0) { /* if first time */
846 /* Right now, the global box is hard-coded, fills the screen,
847 uses an 80x80 grid, and fills top-bottom, left-right */
848 global_icon_box_ptr
= calloc(1, sizeof(icon_boxes
));
849 global_icon_box_ptr
->IconBox
[2] = Scr
.MyDisplayHeight
;
850 global_icon_box_ptr
->IconBox
[3] = Scr
.MyDisplayWidth
;
851 global_icon_box_ptr
->IconGrid
[0] = 80;
852 global_icon_box_ptr
->IconGrid
[1] = 80;
853 global_icon_box_ptr
->IconFlags
= ICONFILLHRZ
;
855 if (*icon_boxes_ptr
== NULL
) { /* first time? */
856 *icon_boxes_ptr
= t
->IconBoxes
; /* start at windows box */
857 if (!*icon_boxes_ptr
) { /* if window has no box */
858 *icon_boxes_ptr
= global_icon_box_ptr
; /* use global box */
860 return (1); /* use box */
863 /* Here its not the first call, we are either on the chain or at
865 if (*icon_boxes_ptr
== global_icon_box_ptr
) { /* if the global box */
866 return (0); /* completely out of boxes (unlikely) */
868 *icon_boxes_ptr
= (*icon_boxes_ptr
)->next
; /* move to next one on chain */
869 if (*icon_boxes_ptr
) { /* if there is a next one */
870 return (1); /* return it */
872 *icon_boxes_ptr
= global_icon_box_ptr
; /* global box */
873 return (1); /* use it */
876 /****************************************************************************
878 * Looks for a monochrome icon bitmap file
880 ****************************************************************************/
881 static void GetBitmapFile(FvwmWindow
*tmp_win
)
886 path
= findImageFile(tmp_win
->icon_bitmap_file
, NULL
, R_OK
);
890 if (XReadBitmapFile(dpy
, Scr
.Root
, path
,
891 (unsigned int *)&tmp_win
->icon_p_width
,
892 (unsigned int *)&tmp_win
->icon_p_height
,
893 &tmp_win
->iconPixmap
, &HotX
, &HotY
) == BitmapSuccess
)
895 tmp_win
->iconDepth
= 1;
896 SET_PIXMAP_OURS(tmp_win
, 1);
900 tmp_win
->icon_p_width
= 0;
901 tmp_win
->icon_p_height
= 0;
907 /****************************************************************************
909 * Looks for a color XPM icon file
911 ****************************************************************************/
912 static void GetXPMFile(FvwmWindow
*tmp_win
)
915 XpmAttributes xpm_attributes
;
920 path
= findImageFile(tmp_win
->icon_bitmap_file
, NULL
, R_OK
);
921 if(path
== NULL
)return;
923 xpm_attributes
.visual
= Pvisual
;
924 xpm_attributes
.colormap
= Pcmap
;
925 xpm_attributes
.depth
= Pdepth
;
926 xpm_attributes
.closeness
= 40000; /* Allow for "similar" colors */
927 xpm_attributes
.valuemask
= XpmSize
| XpmReturnPixels
| XpmCloseness
928 | XpmVisual
| XpmColormap
| XpmDepth
;
930 rc
= XpmReadFileToXpmImage(path
, &my_image
, NULL
);
931 if (rc
!= XpmSuccess
)
933 fvwm_msg(ERR
,"GetXPMFile","XpmReadFileToXpmImage failed, pixmap %s, rc %d",
939 color_reduce_pixmap(&my_image
,Scr
.ColorLimit
);
940 rc
= XpmCreatePixmapFromXpmImage(dpy
,Scr
.NoFocusWin
, &my_image
,
941 &tmp_win
->iconPixmap
,
942 &tmp_win
->icon_maskPixmap
,
944 if (rc
!= XpmSuccess
)
946 fvwm_msg(ERR
,"GetXPMFile",
947 "XpmCreatePixmapFromXpmImage failed, rc %d\n", rc
);
948 XpmFreeXpmImage(&my_image
);
951 tmp_win
->icon_p_width
= my_image
.width
;
952 tmp_win
->icon_p_height
= my_image
.height
;
953 SET_PIXMAP_OURS(tmp_win
, 1);
954 tmp_win
->iconDepth
= Pdepth
;
957 if (ShapesSupported
&& tmp_win
->icon_maskPixmap
)
958 SET_ICON_SHAPED(tmp_win
, 1);
961 XpmFreeXpmImage(&my_image
);
966 /****************************************************************************
968 * Looks for an application supplied icon window
970 ****************************************************************************/
971 void GetIconWindow(FvwmWindow
*tmp_win
)
973 /* We are guaranteed that wmhints is non-null when calling this
975 if(XGetGeometry(dpy
, tmp_win
->wmhints
->icon_window
, &JunkRoot
,
976 &JunkX
, &JunkY
,(unsigned int *)&tmp_win
->icon_p_width
,
977 (unsigned int *)&tmp_win
->icon_p_height
,
978 &JunkBW
, &JunkDepth
)==0)
980 fvwm_msg(ERR
,"GetIconWindow","Help! Bad Icon Window!");
982 tmp_win
->icon_p_width
+= JunkBW
<<1;
983 tmp_win
->icon_p_height
+= JunkBW
<<1;
985 * Now make the new window the icon window for this window,
986 * and set it up to work as such (select for key presses
987 * and button presses/releases, set up the contexts for it,
988 * and define the cursor for it).
990 tmp_win
->icon_pixmap_w
= tmp_win
->wmhints
->icon_window
;
994 if (tmp_win
->wmhints
->flags
& IconMaskHint
)
996 SET_ICON_SHAPED(tmp_win
, 1);
997 tmp_win
->icon_maskPixmap
= tmp_win
->wmhints
->icon_mask
;
1001 /* Make sure that the window is a child of the root window ! */
1002 /* Olwais screws this up, maybe others do too! */
1003 XReparentWindow(dpy
, tmp_win
->icon_pixmap_w
, Scr
.Root
, 0,0);
1004 SET_ICON_OURS(tmp_win
, 0);
1008 /****************************************************************************
1010 * Looks for an application supplied bitmap or pixmap
1012 ****************************************************************************/
1013 void GetIconBitmap(FvwmWindow
*tmp_win
)
1015 unsigned int width
, height
, depth
;
1017 /* We are guaranteed that wmhints is non-null when calling this routine */
1018 if (!XGetGeometry(dpy
, tmp_win
->wmhints
->icon_pixmap
, &JunkRoot
,
1019 &JunkX
, &JunkY
, &width
, &height
, &JunkBW
, &depth
))
1024 /* sanity check the pixmap depth, it must be the same as the root or 1 */
1025 if ((depth
!= 1) && (depth
!= DefaultDepth(dpy
,Scr
.screen
)))
1027 fvwm_msg(ERR
, "GetIconBitmap", "Bad client icon pixmap depth %d", depth
);
1031 tmp_win
->iconPixmap
= tmp_win
->wmhints
->icon_pixmap
;
1032 tmp_win
->icon_p_width
= width
;
1033 tmp_win
->icon_p_height
= height
;
1034 tmp_win
->iconDepth
= depth
;
1037 if (ShapesSupported
)
1039 if (tmp_win
->wmhints
->flags
& IconMaskHint
)
1041 SET_ICON_SHAPED(tmp_win
, 1);
1042 tmp_win
->icon_maskPixmap
= tmp_win
->wmhints
->icon_mask
;
1047 SET_PIXMAP_OURS(tmp_win
, 0);
1052 /***********************************************************************
1055 * DeIconify a window
1057 ***********************************************************************/
1058 void DeIconify(FvwmWindow
*tmp_win
)
1065 if (IS_MAP_PENDING(tmp_win
))
1067 /* final state: de-iconified */
1068 SET_ICONIFY_AFTER_MAP(tmp_win
, 0);
1072 while (IS_ICONIFIED_BY_PARENT(tmp_win
))
1074 for (t
= Scr
.FvwmRoot
.next
; t
!= NULL
; t
= t
->next
)
1076 if (t
!= tmp_win
&& tmp_win
->transientfor
== t
->w
)
1081 /* AS dje RaiseWindow(tmp_win); */
1082 /* now de-iconify transients */
1083 for (t
= Scr
.FvwmRoot
.next
; t
!= NULL
; t
= t
->next
)
1085 if ((t
== tmp_win
)||
1086 ((IS_TRANSIENT(t
)) && (t
->transientfor
== tmp_win
->w
)))
1089 SET_ICONIFIED_BY_PARENT(t
, 0);
1091 DrawDecorations(t
, DRAW_ALL
, False
, True
, None
);
1093 /* AS stuff starts here dje */
1094 if (t
->icon_pixmap_w
)
1095 XUnmapWindow(dpy
, t
->icon_pixmap_w
);
1097 XUnmapWindow(dpy
, t
->icon_w
);
1100 XMapWindow(dpy
, t
->w
);
1101 if(t
->Desk
== Scr
.CurrentDesk
)
1107 r
.width
= t
->icon_g
.width
;
1108 r
.height
= t
->icon_p_height
+t
->icon_g
.height
;
1109 /* update frame geometry in case the icon was moved over a page
1111 update_relative_geometry(t
);
1112 if (IsRectangleOnThisPage(&r
, t
->Desk
) &&
1113 !IsRectangleOnThisPage(&(t
->frame_g
), t
->Desk
))
1115 /* Make sure we keep it on screen when de-iconifying. */
1117 truncate_to_multiple(t
->frame_g
.x
,Scr
.MyDisplayWidth
);
1119 truncate_to_multiple(t
->frame_g
.y
,Scr
.MyDisplayHeight
);
1120 XMoveWindow(dpy
, t
->frame
, t
->frame_g
.x
, t
->frame_g
.y
);
1121 update_absolute_geometry(t
);
1122 maximize_adjust_offset(t
);
1125 /* domivogt (1-Mar-2000): The next block is a hack to prevent animation
1126 * if the window has an icon, but neither a pixmap nor a title. */
1127 if (HAS_NO_ICON_TITLE(t
) && t
->icon_pixmap_w
== None
)
1129 t
->icon_g
.width
= 0;
1130 t
->icon_g
.height
= 0;
1131 t
->icon_p_width
= 0;
1132 t
->icon_p_height
= 0;
1136 BroadcastPacket(M_DEICONIFY
, 11,
1139 t
->icon_g
.x
, t
->icon_g
.y
,
1140 t
->icon_p_width
, t
->icon_p_height
+t
->icon_g
.height
,
1141 t
->frame_g
.x
, t
->frame_g
.y
,
1142 t
->frame_g
.width
, t
->frame_g
.height
);
1146 BroadcastPacket(M_DEICONIFY
, 7,
1149 t
->icon_g
.x
, t
->icon_g
.y
,
1151 t
->icon_p_height
+t
->icon_g
.height
);
1153 if(t
->Desk
== Scr
.CurrentDesk
)
1155 XMapWindow(dpy
, t
->frame
);
1156 SET_MAP_PENDING(t
, 1);
1158 XMapWindow(dpy
, t
->Parent
);
1159 SetMapStateProp(t
, NormalState
);
1160 SET_ICONIFIED(t
, 0);
1161 SET_ICON_UNMAPPED(t
, 0);
1162 SET_ICON_ENTERED(t
, 0);
1163 /* Need to make sure the border is colored correctly,
1164 * in case it was stuck or unstuck while iconified. */
1167 DrawDecorations(t
, DRAW_ALL
, False
, True
, None
);
1173 RaiseWindow(tmp_win
); /* moved dje */
1176 if(HAS_CLICK_FOCUS(tmp_win
))
1177 FocusOn(tmp_win
, TRUE
, "");
1178 GNOME_SetWinArea(tmp_win
);
1184 /****************************************************************************
1186 * Iconifies the selected window
1188 ****************************************************************************/
1189 void Iconify(FvwmWindow
*tmp_win
, int def_x
, int def_y
)
1192 XWindowAttributes winattrs
= {0};
1193 unsigned long eventMask
;
1198 if (IS_MAP_PENDING(tmp_win
))
1200 /* final state: iconified */
1201 SET_ICONIFY_AFTER_MAP(tmp_win
, 1);
1205 if (!XGetWindowAttributes(dpy
, tmp_win
->w
, &winattrs
))
1209 eventMask
= winattrs
.your_event_mask
;
1211 if((tmp_win
== Scr
.Hilite
)&&(HAS_CLICK_FOCUS(tmp_win
))&&(tmp_win
->next
))
1213 SetFocus(tmp_win
->next
->w
,tmp_win
->next
,1);
1216 /* iconify transients first */
1217 for (t
= Scr
.FvwmRoot
.next
; t
!= NULL
; t
= t
->next
)
1219 if ((t
==tmp_win
)||((IS_TRANSIENT(t
)) && (t
->transientfor
== tmp_win
->w
)))
1221 SET_ICON_ENTERED(t
, 0);
1223 * Prevent the receipt of an UnmapNotify, since that would
1224 * cause a transition to the Withdrawn state.
1227 XSelectInput(dpy
, t
->w
, eventMask
& ~StructureNotifyMask
);
1228 XUnmapWindow(dpy
, t
->w
);
1229 XSelectInput(dpy
, t
->w
, eventMask
);
1230 XUnmapWindow(dpy
, t
->frame
);
1231 t
->DeIconifyDesk
= t
->Desk
;
1233 XUnmapWindow(dpy
, t
->icon_w
);
1234 if (t
->icon_pixmap_w
)
1235 XUnmapWindow(dpy
, t
->icon_pixmap_w
);
1237 SetMapStateProp(t
, IconicState
);
1238 DrawDecorations(t
, DRAW_ALL
, False
, False
, None
);
1241 SET_DEICONIFY_PENDING(t
, 1);
1245 SET_ICONIFIED(t
, 1);
1246 SET_ICON_UNMAPPED(t
, 1);
1247 SET_ICONIFIED_BY_PARENT(t
, 1);
1249 BroadcastPacket(M_ICONIFY
, 7,
1254 t
->icon_g
.height
+t
->icon_p_height
);
1255 BroadcastConfig(M_CONFIGURE_WINDOW
,t
);
1260 /* necessary during a recapture */
1261 if (IS_ICONIFIED_BY_PARENT(tmp_win
))
1264 if (tmp_win
->icon_w
== None
)
1266 if(IS_ICON_MOVED(tmp_win
))
1267 CreateIconWindow(tmp_win
,tmp_win
->icon_g
.x
,tmp_win
->icon_g
.y
);
1269 CreateIconWindow(tmp_win
, def_x
, def_y
);
1272 /* if no pixmap we want icon width to change to text width every iconify */
1273 if( (tmp_win
->icon_w
!= None
) && (tmp_win
->icon_pixmap_w
== None
) )
1275 if (HAS_NO_ICON_TITLE(tmp_win
))
1277 tmp_win
->icon_t_width
= 0;
1278 tmp_win
->icon_p_width
= 0;
1279 tmp_win
->icon_g
.width
= 0;
1283 tmp_win
->icon_t_width
=
1284 XTextWidth(tmp_win
->icon_font
.font
,tmp_win
->icon_name
,
1285 strlen(tmp_win
->icon_name
));
1286 tmp_win
->icon_p_width
= tmp_win
->icon_t_width
+ 6 + 4;
1287 tmp_win
->icon_g
.width
= tmp_win
->icon_p_width
;
1291 /* this condition will be true unless we restore a window to
1292 iconified state from a saved session. */
1293 if (!(DO_START_ICONIC(tmp_win
) && IS_ICON_MOVED(tmp_win
)))
1295 AutoPlaceIcon(tmp_win
);
1297 /* domivogt (1-Mar-2000): The next block is a hack to prevent animation if the
1298 * window has an icon, but neither a pixmap nor a title. */
1299 if (HAS_NO_ICON_TITLE(tmp_win
) && tmp_win
->icon_pixmap_w
== None
)
1301 tmp_win
->icon_g
.width
= 0;
1302 tmp_win
->icon_g
.height
= 0;
1303 tmp_win
->icon_p_width
= 0;
1304 tmp_win
->icon_p_height
= 0;
1306 SET_ICONIFIED(tmp_win
, 1);
1307 SET_ICON_UNMAPPED(tmp_win
, 0);
1308 BroadcastPacket(M_ICONIFY
, 11,
1309 tmp_win
->w
, tmp_win
->frame
,
1310 (unsigned long)tmp_win
,
1313 tmp_win
->icon_g
.width
,
1314 tmp_win
->icon_g
.height
+tmp_win
->icon_p_height
,
1315 tmp_win
->frame_g
.x
, /* next 4 added for Animate module */
1317 tmp_win
->frame_g
.width
,
1318 tmp_win
->frame_g
.height
);
1319 BroadcastConfig(M_CONFIGURE_WINDOW
,tmp_win
);
1321 if (!(DO_START_ICONIC(tmp_win
) && IS_ICON_MOVED(tmp_win
)))
1323 LowerWindow(tmp_win
);
1326 if(tmp_win
->Desk
== Scr
.CurrentDesk
)
1328 if (tmp_win
->icon_w
!= None
)
1329 XMapWindow(dpy
, tmp_win
->icon_w
);
1331 if(tmp_win
->icon_pixmap_w
!= None
)
1332 XMapWindow(dpy
, tmp_win
->icon_pixmap_w
);
1334 if(HAS_CLICK_FOCUS(tmp_win
) || HAS_SLOPPY_FOCUS(tmp_win
))
1336 if (tmp_win
== Scr
.Focus
)
1338 if(Scr
.PreviousFocus
== Scr
.Focus
)
1339 Scr
.PreviousFocus
= NULL
;
1340 if(HAS_CLICK_FOCUS(tmp_win
) && tmp_win
->next
)
1341 SetFocus(tmp_win
->next
->w
, tmp_win
->next
,1);
1343 SetFocus(Scr
.NoFocusWin
, NULL
,1);
1350 /****************************************************************************
1352 * This is used to tell applications which windows on the screen are
1353 * top level appication windows, and which windows are the icon windows
1354 * that go with them.
1356 ****************************************************************************/
1357 void SetMapStateProp(FvwmWindow
*tmp_win
, int state
)
1359 unsigned long data
[2]; /* "suggested" by ICCCM version 1 */
1361 data
[0] = (unsigned long) state
;
1362 data
[1] = (unsigned long) tmp_win
->icon_w
;
1363 /* data[2] = (unsigned long) tmp_win->icon_pixmap_w;*/
1365 XChangeProperty(dpy
, tmp_win
->w
, _XA_WM_STATE
, _XA_WM_STATE
, 32,
1366 PropModeReplace
, (unsigned char *) data
, 2);
1371 void iconify_function(F_CMD_ARGS
)
1375 if (DeferExecution(eventp
,&w
,&tmp_win
,&context
, CRS_SELECT
, ButtonRelease
))
1378 toggle
= ParseToggleArgument(action
, NULL
, -1, 0);
1381 if (GetIntegerArguments(action
, NULL
, &toggle
, 1) > 0)
1385 else if (toggle
< 0)
1392 toggle
= (IS_ICONIFIED(tmp_win
)) ? 0 : 1;
1394 if (IS_ICONIFIED(tmp_win
))
1403 if(check_if_function_allowed(F_ICONIFY
,tmp_win
,True
,0) == 0)
1408 Iconify(tmp_win
,eventp
->xbutton
.x_root
-5,eventp
->xbutton
.y_root
-5);