2 * Window Maker window manager
4 * Copyright (c) 1997-2004 Alfredo K. Kojima
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 #include "WindowMaker.h"
33 #include "switchpanel.h"
38 static char * tile_xpm
[] = {
42 " ................................................. ",
43 " ...................................................... ",
44 " ......................................................... ",
45 " ........................................................... ",
46 " ............................................................ ",
47 " .............................................................. ",
48 " .............................................................. ",
49 "............................................................... ",
50 "................................................................",
51 "................................................................",
52 "................................................................",
53 "................................................................",
54 "................................................................",
55 "................................................................",
56 "................................................................",
57 "................................................................",
58 "................................................................",
59 "................................................................",
60 "................................................................",
61 "................................................................",
62 "................................................................",
63 "................................................................",
64 "................................................................",
65 "................................................................",
66 "................................................................",
67 "................................................................",
68 "................................................................",
69 "................................................................",
70 "................................................................",
71 "................................................................",
72 "................................................................",
73 "................................................................",
74 "................................................................",
75 "................................................................",
76 "................................................................",
77 "................................................................",
78 "................................................................",
79 "................................................................",
80 "................................................................",
81 "................................................................",
82 "................................................................",
83 "................................................................",
84 "................................................................",
85 "................................................................",
86 "................................................................",
87 "................................................................",
88 "................................................................",
89 "................................................................",
90 "................................................................",
91 "................................................................",
92 "................................................................",
93 "................................................................",
94 "................................................................",
95 "................................................................",
96 "................................................................",
97 "................................................................",
98 " .............................................................. ",
99 " .............................................................. ",
100 " .............................................................. ",
101 " ............................................................ ",
102 " .......................................................... ",
103 " ........................................................ ",
104 " ...................................................... ",
105 " ................................................ "};
127 extern WPreferences wPreferences
;
129 #define ICON_IDEAL_SIZE 48
130 #define ICON_EXTRASPACE 16
132 static void changeImage(WSwitchPanel
*panel
, int index
, int selected
)
134 WMPixmap
*pixmap
= NULL
;
135 WMLabel
*label
= WMGetFromArray(panel
->icons
, index
);
136 RImage
*image
= WMGetFromArray(panel
->images
, index
);
137 WMScreen
*wscr
= WMWidgetScreen(label
);
144 back
= RCloneImage(panel
->tile
);
145 RCombineArea(back
, image
, 0, 0, image
->width
, image
->height
,
146 (back
->width
- image
->width
)/2, (back
->height
- image
->height
)/2);
148 pixmap
= WMCreatePixmapFromRImage(wscr
, back
, -1);
152 bgColor
.red
= WMRedComponentOfColor(WMGrayColor(wscr
))>>8;
153 bgColor
.green
= WMGreenComponentOfColor(WMGrayColor(wscr
))>>8;
154 bgColor
.blue
= WMBlueComponentOfColor(WMGrayColor(wscr
))>>8;
156 image
= RCloneImage(image
);
157 RCombineImageWithColor(image
, &bgColor
);
159 pixmap
= WMCreatePixmapFromRImage(wscr
, image
, -1);
160 RReleaseImage(image
);
165 WMSetLabelImage(label
, pixmap
);
166 WMSetLabelImagePosition(label
, WIPImageOnly
);
167 WMReleasePixmap(pixmap
);
172 static void addIconForWindow(WSwitchPanel
*panel
, WWindow
*wwin
, int iconWidth
)
174 WMLabel
*label
= WMCreateLabel(panel
->hbox
);
175 WMAddBoxSubviewAtEnd(panel
->hbox
, WMWidgetView(label
), False
, True
, iconWidth
+ ICON_EXTRASPACE
, 0, 0);
176 RImage
*image
= NULL
;
178 if (!WFLAGP(wwin
, always_user_icon
) && wwin
->net_icon_image
)
179 image
= RRetainImage(wwin
->net_icon_image
);
181 image
= wDefaultGetImage(panel
->scr
, wwin
->wm_instance
, wwin
->wm_class
);
183 if (!image
&& !panel
->defIcon
)
185 char *file
= wDefaultGetIconFile(panel
->scr
, NULL
, NULL
, False
);
187 char *path
= FindImage(wPreferences
.icon_path
, file
);
189 image
= RLoadImage(panel
->scr
->rcontext
, path
, 0);
194 if (!image
&& panel
->defIcon
)
195 image
= RRetainImage(panel
->defIcon
);
197 if (image
&& ((image
->width
- iconWidth
) > 2 || (image
->height
- iconWidth
) > 2)) {
199 nimage
= RScaleImage(image
, iconWidth
, (image
->height
* iconWidth
/ image
->width
));
200 RReleaseImage(image
);
204 WMAddToArray(panel
->images
, image
);
205 WMAddToArray(panel
->icons
, label
);
209 WSwitchPanel
*wInitSwitchPanel(WScreen
*scr
, WWindow
*curwin
, int workspace
)
212 WSwitchPanel
*panel
= wmalloc(sizeof(WSwitchPanel
));
216 int iconWidth
= ICON_IDEAL_SIZE
;
219 memset(panel
, 0, sizeof(WSwitchPanel
));
222 panel
->windows
= WMCreateArray(10);
224 for (wwin
= curwin
; wwin
; wwin
= wwin
->prev
) {
225 if (wwin
->frame
->workspace
== workspace
&& wWindowCanReceiveFocus(wwin
) &&
226 (!WFLAGP(wwin
, skip_window_list
) || wwin
->flags
.internal_window
)) {
227 WMInsertInArray(panel
->windows
, 0, wwin
);
231 /* start over from the beginning of the list */
235 for (wwin
= curwin
; wwin
&& wwin
!= curwin
; wwin
= wwin
->prev
) {
236 if (wwin
->frame
->workspace
== workspace
&& wWindowCanReceiveFocus(wwin
) &&
237 (!WFLAGP(wwin
, skip_window_list
) || wwin
->flags
.internal_window
)) {
238 WMInsertInArray(panel
->windows
, 0, wwin
);
242 width
= (iconWidth
+ ICON_EXTRASPACE
)*WMGetArrayItemCount(panel
->windows
);
244 if (width
> WMScreenWidth(scr
->wmscreen
))
246 width
= WMScreenWidth(scr
->wmscreen
) - 100;
247 iconWidth
= width
/ WMGetArrayItemCount(panel
->windows
) - ICON_EXTRASPACE
;
250 if (WMGetArrayItemCount(panel
->windows
) == 0) {
251 WMFreeArray(panel
->windows
);
256 if (iconWidth
< 16) {
257 /* if there are too many windows, don't bother trying to show the panel */
262 height
= iconWidth
+ 20 + 10 + ICON_EXTRASPACE
;
264 panel
->icons
= WMCreateArray(WMGetArrayItemCount(panel
->windows
));
265 panel
->images
= WMCreateArray(WMGetArrayItemCount(panel
->windows
));
267 panel
->win
= WMCreateWindow(scr
->wmscreen
, "");
268 WMResizeWidget(panel
->win
, width
+ 10, height
);
271 WMFrame
*frame
= WMCreateFrame(panel
->win
);
272 WMSetFrameRelief(frame
, WRSimple
);
273 WMSetViewExpandsToParent(WMWidgetView(frame
), 0, 0, 0, 0);
275 vbox
= WMCreateBox(panel
->win
);
277 WMSetViewExpandsToParent(WMWidgetView(vbox
), 5, 5, 5, 5);
278 WMSetBoxHorizontal(vbox
, False
);
280 panel
->label
= WMCreateLabel(vbox
);
281 WMAddBoxSubviewAtEnd(vbox
, WMWidgetView(panel
->label
), False
, True
, 20, 0, 0);
282 if (scr
->focused_window
&& scr
->focused_window
->frame
->title
)
283 WMSetLabelText(panel
->label
, scr
->focused_window
->frame
->title
);
285 WMSetLabelText(panel
->label
, "");
289 WMFont
*boldFont
= WMBoldSystemFontOfSize(scr
->wmscreen
, 12);
291 WMSetLabelRelief(panel
->label
, WRSimple
);
292 WMSetLabelFont(panel
->label
, boldFont
);
293 color
= WMDarkGrayColor(scr
->wmscreen
);
294 WMSetWidgetBackgroundColor(panel
->label
, color
);
295 WMReleaseColor(color
);
296 color
= WMWhiteColor(scr
->wmscreen
);
297 WMSetLabelTextColor(panel
->label
, color
);
298 WMReleaseColor(color
);
300 WMReleaseFont(boldFont
);
306 char *path
= FindImage(wPreferences
.pixmap_path
, "swtile.png");
308 tmp
= RLoadImage(panel
->scr
->rcontext
, path
, 0);
313 tmp
= RGetImageFromXPMData(scr
->rcontext
, tile_xpm
);
315 panel
->tile
= RScaleImage(tmp
, iconWidth
+ICON_EXTRASPACE
, iconWidth
+ICON_EXTRASPACE
);
318 bgColor
.red
= WMRedComponentOfColor(WMGrayColor(scr
->wmscreen
))>>8;
319 bgColor
.green
= WMGreenComponentOfColor(WMGrayColor(scr
->wmscreen
))>>8;
320 bgColor
.blue
= WMBlueComponentOfColor(WMGrayColor(scr
->wmscreen
))>>8;
322 RCombineImageWithColor(panel
->tile
, &bgColor
);
327 panel
->hbox
= WMCreateBox(vbox
);
328 WMSetBoxHorizontal(panel
->hbox
, True
);
329 WMAddBoxSubviewAtEnd(vbox
, WMWidgetView(panel
->hbox
), True
, True
, 20, 0, 4);
331 WM_ITERATE_ARRAY(panel
->windows
, wwin
, i
) {
332 addIconForWindow(panel
, wwin
, iconWidth
);
333 changeImage(panel
, i
, 0);
336 WMMapSubwidgets(panel
->win
);
337 WMRealizeWidget(panel
->win
);
338 WMMapWidget(panel
->win
);
342 center
= wGetPointToCenterRectInHead(scr
, wGetHeadForPointerLocation(scr
),
344 WMMoveWidget(panel
->win
, center
.x
, center
.y
);
347 panel
->current
= WMGetFirstInArray(panel
->windows
, curwin
);
348 if (panel
->current
>= 0)
349 changeImage(panel
, panel
->current
, 1);
355 void wSwitchPanelDestroy(WSwitchPanel
*panel
)
361 WM_ITERATE_ARRAY(panel
->images
, image
, i
) {
363 RReleaseImage(image
);
365 WMFreeArray(panel
->images
);
368 WMDestroyWidget(panel
->win
);
370 WMFreeArray(panel
->icons
);
371 WMFreeArray(panel
->windows
);
373 RReleaseImage(panel
->defIcon
);
375 RReleaseImage(panel
->tile
);
380 WWindow
*wSwitchPanelSelectNext(WSwitchPanel
*panel
, int back
)
383 int count
= WMGetArrayItemCount(panel
->windows
);
389 changeImage(panel
, panel
->current
, 0);
392 panel
->current
= (count
+ panel
->current
- 1) % count
;
394 panel
->current
= (panel
->current
+ 1) % count
;
396 wwin
= WMGetFromArray(panel
->windows
, panel
->current
);
399 WMSetLabelText(panel
->label
, wwin
->frame
->title
);
401 changeImage(panel
, panel
->current
, 1);
408 WWindow
*wSwitchPanelHandleEvent(WSwitchPanel
*panel
, XEvent
*event
)
413 printf("%i %i\n", event
->xmotion
.x
, event
->xmotion
.y
);
415 WM_ITERATE_ARRAY(panel
->icons
, label
, i
) {
416 if (WMWidgetXID(label
) == event
->xmotion
.subwindow
)