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
, int workspace
)
214 WSwitchPanel
*panel
= wmalloc(sizeof(WSwitchPanel
));
218 int iconWidth
= ICON_IDEAL_SIZE
;
222 panel
->defIcon
= NULL
;
224 panel
->normalColor
= WMGrayColor(scr
->wmscreen
);
225 panel
->selectColor
= WMWhiteColor(scr
->wmscreen
);
228 panel
->windows
= WMCreateArray(10);
230 for (wwin
= scr
->focused_window
; wwin
; wwin
= wwin
->prev
) {
231 if (wwin
->frame
->workspace
== workspace
&& wWindowCanReceiveFocus(wwin
) &&
232 (!WFLAGP(wwin
, skip_window_list
) || wwin
->flags
.internal_window
)) {
233 WMInsertInArray(panel
->windows
, 0, wwin
);
237 width
= (iconWidth
+ ICON_EXTRASPACE
)*WMGetArrayItemCount(panel
->windows
);
239 if (width
> WMScreenWidth(scr
->wmscreen
))
241 width
= WMScreenWidth(scr
->wmscreen
) - 100;
242 iconWidth
= width
/ WMGetArrayItemCount(panel
->windows
) - ICON_EXTRASPACE
;
245 if (iconWidth
< 16 || WMGetArrayItemCount(panel
->windows
) == 0)
247 /* if there are too many windows, don't bother trying to show the panel */
248 WMFreeArray(panel
->windows
);
253 height
= iconWidth
+ 20 + 10 + ICON_EXTRASPACE
;
255 panel
->icons
= WMCreateArray(WMGetArrayItemCount(panel
->windows
));
256 panel
->images
= WMCreateArray(WMGetArrayItemCount(panel
->windows
));
258 panel
->win
= WMCreateWindow(scr
->wmscreen
, "");
259 WMResizeWidget(panel
->win
, width
+ 10, height
);
262 WMFrame
*frame
= WMCreateFrame(panel
->win
);
263 WMSetFrameRelief(frame
, WRSimple
);
264 WMSetViewExpandsToParent(WMWidgetView(frame
), 0, 0, 0, 0);
266 vbox
= WMCreateBox(panel
->win
);
268 WMSetViewExpandsToParent(WMWidgetView(vbox
), 5, 5, 5, 5);
269 WMSetBoxHorizontal(vbox
, False
);
271 panel
->label
= WMCreateLabel(vbox
);
272 WMAddBoxSubviewAtEnd(vbox
, WMWidgetView(panel
->label
), False
, True
, 20, 0, 0);
273 if (scr
->focused_window
&& scr
->focused_window
->frame
->title
)
274 WMSetLabelText(panel
->label
, scr
->focused_window
->frame
->title
);
276 WMSetLabelText(panel
->label
, "");
279 WMFont
*boldFont
= WMBoldSystemFontOfSize(scr
->wmscreen
, 12);
281 WMSetLabelRelief(panel
->label
, WRSimple
);
282 WMSetLabelFont(panel
->label
, boldFont
);
283 color
= WMDarkGrayColor(scr
->wmscreen
);
284 WMSetWidgetBackgroundColor(panel
->label
, color
);
285 WMReleaseColor(color
);
286 color
= WMWhiteColor(scr
->wmscreen
);
287 WMSetLabelTextColor(panel
->label
, color
);
288 WMReleaseColor(color
);
290 WMReleaseFont(boldFont
);
296 char *path
= FindImage(wPreferences
.pixmap_path
, "swtile.png");
298 tmp
= RLoadImage(panel
->scr
->rcontext
, path
, 0);
303 tmp
= RGetImageFromXPMData(scr
->rcontext
, tile_xpm
);
305 panel
->tile
= RScaleImage(tmp
, iconWidth
+ICON_EXTRASPACE
, iconWidth
+ICON_EXTRASPACE
);
308 bgColor
.red
= WMRedComponentOfColor(WMGrayColor(scr
->wmscreen
))>>8;
309 bgColor
.green
= WMGreenComponentOfColor(WMGrayColor(scr
->wmscreen
))>>8;
310 bgColor
.blue
= WMBlueComponentOfColor(WMGrayColor(scr
->wmscreen
))>>8;
312 RCombineImageWithColor(panel
->tile
, &bgColor
);
317 panel
->hbox
= WMCreateBox(vbox
);
318 WMSetBoxHorizontal(panel
->hbox
, True
);
319 WMAddBoxSubviewAtEnd(vbox
, WMWidgetView(panel
->hbox
), True
, True
, 20, 0, 2);
321 WM_ITERATE_ARRAY(panel
->windows
, wwin
, i
) {
322 addIconForWindow(panel
, wwin
, iconWidth
);
323 changeImage(panel
, i
, 0);
326 WMMapSubwidgets(panel
->win
);
327 WMRealizeWidget(panel
->win
);
328 WMMapWidget(panel
->win
);
332 center
= wGetPointToCenterRectInHead(scr
, wGetHeadForPointerLocation(scr
),
334 WMMoveWidget(panel
->win
, center
.x
, center
.y
);
337 changeImage(panel
, 0, 1);
343 void wSwitchPanelDestroy(WSwitchPanel
*panel
)
347 WM_ITERATE_ARRAY(panel
->images
, image
, i
) {
349 RReleaseImage(image
);
351 WMDestroyWidget(panel
->win
);
352 WMFreeArray(panel
->icons
);
353 WMFreeArray(panel
->windows
);
354 WMFreeArray(panel
->images
);
355 WMReleaseColor(panel
->selectColor
);
356 WMReleaseColor(panel
->normalColor
);
358 RReleaseImage(panel
->defIcon
);
359 RReleaseImage(panel
->tile
);
364 WWindow
*wSwitchPanelSelectNext(WSwitchPanel
*panel
, int back
)
367 int count
= WMGetArrayItemCount(panel
->windows
);
369 changeImage(panel
, panel
->current
, 0);
372 panel
->current
= (count
+ panel
->current
- 1) % count
;
374 panel
->current
= (panel
->current
+ 1) % count
;
376 wwin
= WMGetFromArray(panel
->windows
, panel
->current
);
378 WMSetLabelText(panel
->label
, wwin
->frame
->title
);
380 changeImage(panel
, panel
->current
, 1);
387 WWindow
*wSwitchPanelHandleEvent(WSwitchPanel
*panel
, XEvent
*event
)
392 printf("%i %i\n", event
->xmotion
.x
, event
->xmotion
.y
);
394 WM_ITERATE_ARRAY(panel
->icons
, label
, i
) {
395 if (WMWidgetXID(label
) == event
->xmotion
.subwindow
)