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,
26 #include "WindowMaker.h"
32 #include "switchpanel.h"
37 static char * tile_xpm
[] = {
41 " ................................................. ",
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 " ................................................ "};
117 WMColor
*normalColor
;
118 WMColor
*selectColor
;
129 extern WPreferences wPreferences
;
131 #define ICON_IDEAL_SIZE 48
132 #define ICON_EXTRASPACE 16
134 static void changeImage(WSwitchPanel
*panel
, int index
, int selected
)
136 WMPixmap
*pixmap
= NULL
;
137 WMLabel
*label
= WMGetFromArray(panel
->icons
, index
);
138 RImage
*image
= WMGetFromArray(panel
->images
, index
);
139 WMScreen
*wscr
= WMWidgetScreen(label
);
146 back
= RCloneImage(panel
->tile
);
147 RCombineArea(back
, image
, 0, 0, image
->width
, image
->height
,
148 (back
->width
- image
->width
)/2, (back
->height
- image
->height
)/2);
150 pixmap
= WMCreatePixmapFromRImage(wscr
, back
, -1);
154 bgColor
.red
= WMRedComponentOfColor(WMGrayColor(wscr
))>>8;
155 bgColor
.green
= WMGreenComponentOfColor(WMGrayColor(wscr
))>>8;
156 bgColor
.blue
= WMBlueComponentOfColor(WMGrayColor(wscr
))>>8;
158 image
= RCloneImage(image
);
159 RCombineImageWithColor(image
, &bgColor
);
161 pixmap
= WMCreatePixmapFromRImage(wscr
, image
, -1);
162 RReleaseImage(image
);
167 WMSetLabelImage(label
, pixmap
);
168 WMSetLabelImagePosition(label
, WIPImageOnly
);
169 WMReleasePixmap(pixmap
);
174 static void addIconForWindow(WSwitchPanel
*panel
, WWindow
*wwin
, int iconWidth
)
176 WMLabel
*label
= WMCreateLabel(panel
->hbox
);
177 WMAddBoxSubviewAtEnd(panel
->hbox
, WMWidgetView(label
), False
, True
, iconWidth
+ ICON_EXTRASPACE
, 0, 0);
178 RImage
*image
= NULL
;
180 if (!WFLAGP(wwin
, always_user_icon
) && wwin
->net_icon_image
)
181 image
= RRetainImage(wwin
->net_icon_image
);
183 image
= wDefaultGetImage(panel
->scr
, wwin
->wm_instance
, wwin
->wm_class
);
185 if (!image
&& !panel
->defIcon
)
187 char *file
= wDefaultGetIconFile(panel
->scr
, NULL
, NULL
, False
);
189 char *path
= FindImage(wPreferences
.icon_path
, file
);
191 image
= RLoadImage(panel
->scr
->rcontext
, path
, 0);
196 if (!image
&& panel
->defIcon
)
197 image
= RRetainImage(panel
->defIcon
);
199 if (image
&& (abs(image
->width
- iconWidth
) > 2 || abs(image
->height
- iconWidth
) > 2)) {
201 nimage
= RScaleImage(image
, iconWidth
, (image
->height
* iconWidth
/ image
->width
));
202 RReleaseImage(image
);
206 WMAddToArray(panel
->images
, image
);
207 WMAddToArray(panel
->icons
, label
);
211 WSwitchPanel
*wInitSwitchPanel(WScreen
*scr
, WWindow
*curwin
, int workspace
)
214 WSwitchPanel
*panel
= wmalloc(sizeof(WSwitchPanel
));
218 int iconWidth
= ICON_IDEAL_SIZE
;
221 panel
->defIcon
= NULL
;
223 panel
->normalColor
= WMGrayColor(scr
->wmscreen
);
224 panel
->selectColor
= WMWhiteColor(scr
->wmscreen
);
227 panel
->windows
= WMCreateArray(10);
229 for (wwin
= curwin
; wwin
; wwin
= wwin
->prev
) {
230 if (wwin
->frame
->workspace
== workspace
&& wWindowCanReceiveFocus(wwin
) &&
231 (!WFLAGP(wwin
, skip_window_list
) || wwin
->flags
.internal_window
)) {
232 WMInsertInArray(panel
->windows
, 0, wwin
);
236 /* start over from the beginning of the list */
240 for (wwin
= curwin
; wwin
&& wwin
!= curwin
; wwin
= wwin
->prev
) {
241 if (wwin
->frame
->workspace
== workspace
&& wWindowCanReceiveFocus(wwin
) &&
242 (!WFLAGP(wwin
, skip_window_list
) || wwin
->flags
.internal_window
)) {
243 WMInsertInArray(panel
->windows
, 0, wwin
);
247 width
= (iconWidth
+ ICON_EXTRASPACE
)*WMGetArrayItemCount(panel
->windows
);
249 if (width
> WMScreenWidth(scr
->wmscreen
))
251 width
= WMScreenWidth(scr
->wmscreen
) - 100;
252 iconWidth
= width
/ WMGetArrayItemCount(panel
->windows
) - ICON_EXTRASPACE
;
255 if (iconWidth
< 16 || WMGetArrayItemCount(panel
->windows
) == 0)
257 /* if there are too many windows, don't bother trying to show the panel */
258 WMFreeArray(panel
->windows
);
263 height
= iconWidth
+ 20 + 10 + ICON_EXTRASPACE
;
265 panel
->icons
= WMCreateArray(WMGetArrayItemCount(panel
->windows
));
266 panel
->images
= WMCreateArray(WMGetArrayItemCount(panel
->windows
));
268 panel
->win
= WMCreateWindow(scr
->wmscreen
, "");
269 WMResizeWidget(panel
->win
, width
+ 10, height
);
272 WMFrame
*frame
= WMCreateFrame(panel
->win
);
273 WMSetFrameRelief(frame
, WRSimple
);
274 WMSetViewExpandsToParent(WMWidgetView(frame
), 0, 0, 0, 0);
276 vbox
= WMCreateBox(panel
->win
);
278 WMSetViewExpandsToParent(WMWidgetView(vbox
), 5, 5, 5, 5);
279 WMSetBoxHorizontal(vbox
, False
);
281 panel
->label
= WMCreateLabel(vbox
);
282 WMAddBoxSubviewAtEnd(vbox
, WMWidgetView(panel
->label
), False
, True
, 20, 0, 0);
283 if (scr
->focused_window
&& scr
->focused_window
->frame
->title
)
284 WMSetLabelText(panel
->label
, scr
->focused_window
->frame
->title
);
286 WMSetLabelText(panel
->label
, "");
290 WMFont
*boldFont
= WMBoldSystemFontOfSize(scr
->wmscreen
, 12);
292 WMSetLabelRelief(panel
->label
, WRSimple
);
293 WMSetLabelFont(panel
->label
, boldFont
);
294 color
= WMDarkGrayColor(scr
->wmscreen
);
295 WMSetWidgetBackgroundColor(panel
->label
, color
);
296 WMReleaseColor(color
);
297 color
= WMWhiteColor(scr
->wmscreen
);
298 WMSetLabelTextColor(panel
->label
, color
);
299 WMReleaseColor(color
);
301 WMReleaseFont(boldFont
);
307 char *path
= FindImage(wPreferences
.pixmap_path
, "swtile.png");
309 tmp
= RLoadImage(panel
->scr
->rcontext
, path
, 0);
314 tmp
= RGetImageFromXPMData(scr
->rcontext
, tile_xpm
);
316 panel
->tile
= RScaleImage(tmp
, iconWidth
+ICON_EXTRASPACE
, iconWidth
+ICON_EXTRASPACE
);
319 bgColor
.red
= WMRedComponentOfColor(WMGrayColor(scr
->wmscreen
))>>8;
320 bgColor
.green
= WMGreenComponentOfColor(WMGrayColor(scr
->wmscreen
))>>8;
321 bgColor
.blue
= WMBlueComponentOfColor(WMGrayColor(scr
->wmscreen
))>>8;
323 RCombineImageWithColor(panel
->tile
, &bgColor
);
328 panel
->hbox
= WMCreateBox(vbox
);
329 WMSetBoxHorizontal(panel
->hbox
, True
);
330 WMAddBoxSubviewAtEnd(vbox
, WMWidgetView(panel
->hbox
), True
, True
, 20, 0, 4);
332 WM_ITERATE_ARRAY(panel
->windows
, wwin
, i
) {
333 addIconForWindow(panel
, wwin
, iconWidth
);
334 changeImage(panel
, i
, 0);
337 WMMapSubwidgets(panel
->win
);
338 WMRealizeWidget(panel
->win
);
339 WMMapWidget(panel
->win
);
343 center
= wGetPointToCenterRectInHead(scr
, wGetHeadForPointerLocation(scr
),
345 WMMoveWidget(panel
->win
, center
.x
, center
.y
);
348 panel
->current
= WMGetFirstInArray(panel
->windows
, curwin
);
349 changeImage(panel
, panel
->current
, 1);
355 void wSwitchPanelDestroy(WSwitchPanel
*panel
)
359 WM_ITERATE_ARRAY(panel
->images
, image
, i
) {
361 RReleaseImage(image
);
363 WMDestroyWidget(panel
->win
);
364 WMFreeArray(panel
->icons
);
365 WMFreeArray(panel
->windows
);
366 WMFreeArray(panel
->images
);
367 WMReleaseColor(panel
->selectColor
);
368 WMReleaseColor(panel
->normalColor
);
370 RReleaseImage(panel
->defIcon
);
371 RReleaseImage(panel
->tile
);
376 WWindow
*wSwitchPanelSelectNext(WSwitchPanel
*panel
, int back
)
379 int count
= WMGetArrayItemCount(panel
->windows
);
381 changeImage(panel
, panel
->current
, 0);
384 panel
->current
= (count
+ panel
->current
- 1) % count
;
386 panel
->current
= (panel
->current
+ 1) % count
;
388 wwin
= WMGetFromArray(panel
->windows
, panel
->current
);
390 WMSetLabelText(panel
->label
, wwin
->frame
->title
);
392 changeImage(panel
, panel
->current
, 1);
399 WWindow
*wSwitchPanelHandleEvent(WSwitchPanel
*panel
, XEvent
*event
)
404 printf("%i %i\n", event
->xmotion
.x
, event
->xmotion
.y
);
406 WM_ITERATE_ARRAY(panel
->icons
, label
, i
) {
407 if (WMWidgetXID(label
) == event
->xmotion
.subwindow
)