fixed bug in window switching
[wmaker-crm.git] / src / switchpanel.c
blob76ba785c0c58a0f9a9246257caec8028378d990c
1 /*
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,
19 * USA.
22 #include "wconfig.h"
24 #include <stdlib.h>
26 #include "WindowMaker.h"
27 #include "screen.h"
28 #include "wcore.h"
29 #include "framewin.h"
30 #include "window.h"
31 #include "defaults.h"
32 #include "switchpanel.h"
33 #include "funcs.h"
35 struct SwitchPanel {
36 WScreen *scr;
37 WMWindow *win;
38 WMBox *hbox;
39 WMLabel *label;
40 WMArray *icons;
41 WMArray *windows;
42 int current;
44 WMColor *normalColor;
45 WMColor *selectColor;
47 WMPixmap *defIcon;
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);
60 RImage *image = NULL;
61 WMPixmap *pixmap;
62 WMScreen *wscr = WMWidgetScreen(label);
64 if (!WFLAGP(wwin, always_user_icon) && wwin->net_icon_image)
65 image = RRetainImage(wwin->net_icon_image);
66 if (!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)) {
70 RImage *nimage;
71 nimage= RScaleImage(image, iconWidth, (image->height * iconWidth / image->width));
72 RReleaseImage(image);
73 image= nimage;
76 if (image) {
77 pixmap= WMCreatePixmapFromRImage(wscr, image, 100);
78 RReleaseImage(image);
79 } else {
80 if (!panel->defIcon)
82 char *file = wDefaultGetIconFile(panel->scr, NULL, NULL, False);
83 if (file) {
84 char *path = FindImage(wPreferences.icon_path, file);
85 if (path) {
86 image = RLoadImage(panel->scr->rcontext, path, 0);
87 wfree(path);
89 panel->defIcon= WMCreatePixmapFromRImage(wscr, image, 100);
90 RReleaseImage(image);
95 if (panel->defIcon)
96 pixmap= WMRetainPixmap(panel->defIcon);
97 else
98 pixmap= NULL;
101 if (pixmap) {
102 WMSetLabelImage(label, pixmap);
103 WMSetLabelImagePosition(label, WIPImageOnly);
104 WMReleasePixmap(pixmap);
107 WMAddToArray(panel->icons, label);
111 WSwitchPanel *wInitSwitchPanel(WScreen *scr, int workspace)
113 WWindow *wwin;
114 WSwitchPanel *panel= wmalloc(sizeof(WSwitchPanel));
115 int i;
116 int width;
117 int height;
118 int iconWidth = ICON_IDEAL_SIZE;
119 WMBox *vbox;
121 panel->current= 0;
122 panel->defIcon= NULL;
124 panel->normalColor = WMGrayColor(scr->wmscreen);
125 panel->selectColor = WMWhiteColor(scr->wmscreen);
127 panel->scr= scr;
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);
149 wfree(panel);
150 return NULL;
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);
174 else
175 WMSetLabelText(panel->label, "");
177 WMColor *color;
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),
208 panel->selectColor);
210 return panel;
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);
221 if (panel->defIcon)
222 WMReleasePixmap(panel->defIcon);
223 wfree(panel);
227 WWindow *wSwitchPanelSelectNext(WSwitchPanel *panel, int back)
229 WWindow *wwin;
230 int count = WMGetArrayItemCount(panel->windows);
231 WMLabel *label;
233 label= WMGetFromArray(panel->icons, panel->current);
234 WMSetWidgetBackgroundColor(label, panel->normalColor);
235 WMSetLabelRelief(label, WRFlat);
237 if (!back)
238 panel->current = (count + panel->current - 1) % count;
239 else
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);
250 return wwin;
255 WWindow *wSwitchPanelHandleEvent(WSwitchPanel *panel, XEvent *event)
257 WMLabel *label;
258 int i;
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)
264 puts("HOORAY");
267 return NULL;