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"
51 extern WPreferences wPreferences
;
53 #define ICON_IDEAL_SIZE 64
54 #define ICON_EXTRASPACE 4
56 static void addIconForWindow(WSwitchPanel
*panel
, WWindow
*wwin
, int iconWidth
)
58 WMLabel
*label
= WMCreateLabel(panel
->hbox
);
59 WMAddBoxSubviewAtEnd(panel
->hbox
, WMWidgetView(label
), False
, True
, iconWidth
+ ICON_EXTRASPACE
, 0, 0);
62 WMScreen
*wscr
= WMWidgetScreen(label
);
64 if (!WFLAGP(wwin
, always_user_icon
) && wwin
->net_icon_image
)
65 image
= RRetainImage(wwin
->net_icon_image
);
67 image
= wDefaultGetImage(panel
->scr
, wwin
->wm_instance
, wwin
->wm_class
);
69 if (image
&& (abs(image
->width
- iconWidth
) > 2 || abs(image
->height
- iconWidth
) > 2)) {
71 nimage
= RScaleImage(image
, iconWidth
, (image
->height
* iconWidth
/ image
->width
));
77 pixmap
= WMCreatePixmapFromRImage(wscr
, image
, 100);
82 char *file
= wDefaultGetIconFile(panel
->scr
, NULL
, NULL
, False
);
84 char *path
= FindImage(wPreferences
.icon_path
, file
);
86 image
= RLoadImage(panel
->scr
->rcontext
, path
, 0);
89 panel
->defIcon
= WMCreatePixmapFromRImage(wscr
, image
, 100);
96 pixmap
= WMRetainPixmap(panel
->defIcon
);
102 WMSetLabelImage(label
, pixmap
);
103 WMSetLabelImagePosition(label
, WIPImageOnly
);
104 WMReleasePixmap(pixmap
);
107 WMAddToArray(panel
->icons
, label
);
111 WSwitchPanel
*wInitSwitchPanel(WScreen
*scr
, int workspace
)
114 WSwitchPanel
*panel
= wmalloc(sizeof(WSwitchPanel
));
118 int iconWidth
= ICON_IDEAL_SIZE
;
122 panel
->defIcon
= NULL
;
124 panel
->normalColor
= WMGrayColor(scr
->wmscreen
);
125 panel
->selectColor
= WMWhiteColor(scr
->wmscreen
);
128 panel
->windows
= WMCreateArray(10);
130 for (wwin
= scr
->focused_window
; wwin
; wwin
= wwin
->prev
) {
131 if (wwin
->frame
->workspace
== workspace
&& wWindowCanReceiveFocus(wwin
) &&
132 (!WFLAGP(wwin
, skip_window_list
) || wwin
->flags
.internal_window
)) {
133 WMInsertInArray(panel
->windows
, 0, wwin
);
137 width
= (iconWidth
+ ICON_EXTRASPACE
)*WMGetArrayItemCount(panel
->windows
);
139 if (width
> WMScreenWidth(scr
->wmscreen
))
141 width
= WMScreenWidth(scr
->wmscreen
) - 100;
142 iconWidth
= width
/ WMGetArrayItemCount(panel
->windows
) - ICON_EXTRASPACE
;
145 if (iconWidth
< 16 || WMGetArrayItemCount(panel
->windows
) == 0)
147 /* if there are too many windows, don't bother trying to show the panel */
148 WMFreeArray(panel
->windows
);
153 height
= iconWidth
+ 20 + 10 + ICON_EXTRASPACE
;
155 panel
->icons
= WMCreateArray(WMGetArrayItemCount(panel
->windows
));
157 panel
->win
= WMCreateWindow(scr
->wmscreen
, "");
158 WMResizeWidget(panel
->win
, width
+ 10, height
);
161 WMFrame
*frame
= WMCreateFrame(panel
->win
);
162 WMSetFrameRelief(frame
, WRSimple
);
163 WMSetViewExpandsToParent(WMWidgetView(frame
), 0, 0, 0, 0);
165 vbox
= WMCreateBox(panel
->win
);
167 WMSetViewExpandsToParent(WMWidgetView(vbox
), 5, 5, 5, 5);
168 WMSetBoxHorizontal(vbox
, False
);
170 panel
->label
= WMCreateLabel(vbox
);
171 WMAddBoxSubviewAtEnd(vbox
, WMWidgetView(panel
->label
), False
, True
, 20, 0, 0);
172 if (scr
->focused_window
&& scr
->focused_window
->frame
->title
)
173 WMSetLabelText(panel
->label
, scr
->focused_window
->frame
->title
);
175 WMSetLabelText(panel
->label
, "");
178 WMFont
*boldFont
= WMBoldSystemFontOfSize(scr
->wmscreen
, 12);
180 WMSetLabelRelief(panel
->label
, WRSimple
);
181 WMSetLabelFont(panel
->label
, boldFont
);
182 color
= WMDarkGrayColor(scr
->wmscreen
);
183 WMSetWidgetBackgroundColor(panel
->label
, color
);
184 WMReleaseColor(color
);
185 color
= WMWhiteColor(scr
->wmscreen
);
186 WMSetLabelTextColor(panel
->label
, color
);
187 WMReleaseColor(color
);
189 WMReleaseFont(boldFont
);
192 panel
->hbox
= WMCreateBox(vbox
);
193 WMSetBoxHorizontal(panel
->hbox
, True
);
194 WMAddBoxSubviewAtEnd(vbox
, WMWidgetView(panel
->hbox
), True
, True
, 20, 0, 2);
196 WM_ITERATE_ARRAY(panel
->windows
, wwin
, i
) {
197 addIconForWindow(panel
, wwin
, iconWidth
);
200 WMMapSubwidgets(panel
->win
);
201 WMRealizeWidget(panel
->win
);
202 WMMapWidget(panel
->win
);
203 WMMoveWidget(panel
->win
,
204 (WMScreenWidth(scr
->wmscreen
) - (width
+10))/2,
205 (WMScreenHeight(scr
->wmscreen
) - height
)/2);
207 WMSetWidgetBackgroundColor(WMGetFromArray(panel
->icons
, 0),
214 void wSwitchPanelDestroy(WSwitchPanel
*panel
)
216 WMDestroyWidget(panel
->win
);
217 WMFreeArray(panel
->icons
);
218 WMFreeArray(panel
->windows
);
219 WMReleaseColor(panel
->selectColor
);
220 WMReleaseColor(panel
->normalColor
);
222 WMReleasePixmap(panel
->defIcon
);
227 WWindow
*wSwitchPanelSelectNext(WSwitchPanel
*panel
, int back
)
230 int count
= WMGetArrayItemCount(panel
->windows
);
233 label
= WMGetFromArray(panel
->icons
, panel
->current
);
234 WMSetWidgetBackgroundColor(label
, panel
->normalColor
);
235 WMSetLabelRelief(label
, WRFlat
);
238 panel
->current
= (count
+ panel
->current
- 1) % count
;
240 panel
->current
= (panel
->current
+ 1) % count
;
242 wwin
= WMGetFromArray(panel
->windows
, panel
->current
);
244 WMSetLabelText(panel
->label
, wwin
->frame
->title
);
246 label
= WMGetFromArray(panel
->icons
, panel
->current
);
247 WMSetWidgetBackgroundColor(label
, panel
->selectColor
);
248 WMSetLabelRelief(label
, WRSimple
);
255 WWindow
*wSwitchPanelHandleEvent(WSwitchPanel
*panel
, XEvent
*event
)
260 printf("%i %i\n", event
->xmotion
.x
, event
->xmotion
.y
);
262 WM_ITERATE_ARRAY(panel
->icons
, label
, i
) {
263 if (WMWidgetXID(label
) == event
->xmotion
.subwindow
)