1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Configmenu.cc for Blackbox - An X11 Window Manager
3 // Copyright (c) 2001 - 2005 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000, 2002 - 2005
5 // Bradley T Hughes <bhughes at trolltech.com>
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a
8 // copy of this software and associated documentation files (the "Software"),
9 // to deal in the Software without restriction, including without limitation
10 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 // and/or sell copies of the Software, and to permit persons to whom the
12 // Software is furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 // DEALINGS IN THE SOFTWARE.
24
25 #include "Configmenu.hh"
26 #include "Screen.hh"
27 #include "Slitmenu.hh"
28 #include "Toolbarmenu.hh"
29
30 #include <Image.hh>
31 #include <Unicode.hh>
32
33
34 class ConfigFocusmenu : public bt::Menu {
35 public:
36 ConfigFocusmenu(bt::Application &app, unsigned int screen,
37 BScreen *bscreen);
38
39 void refresh(void);
40
41 protected:
42 void itemClicked(unsigned int id, unsigned int);
43
44 private:
45 BScreen *_bscreen;
46 };
47
48
49 class ConfigPlacementmenu : public bt::Menu {
50 public:
51 ConfigPlacementmenu(bt::Application &app, unsigned int screen,
52 BScreen *bscreen);
53
54 void refresh(void);
55
56 protected:
57 void itemClicked(unsigned int id, unsigned int);
58
59 private:
60 BScreen *_bscreen;
61 };
62
63
64 class ConfigDithermenu : public bt::Menu {
65 public:
66 ConfigDithermenu(bt::Application &app, unsigned int screen,
67 BScreen *bscreen);
68
69 void refresh(void);
70
71 protected:
72 void itemClicked(unsigned int id, unsigned int);
73
74 private:
75 BScreen *_bscreen;
76 };
77
78
79 enum {
80 FocusModel,
81 WindowPlacement,
82 ImageDithering,
83 OpaqueWindowMoving,
84 OpaqueWindowResizing,
85 FullMaximization,
86 FocusNewWindows,
87 FocusLastWindowOnWorkspace,
88 ChangeWorkspaceWithMouseWheel,
89 ShadeWindowWithMouseWheel,
90 ToolbarActionsWithMouseWheel,
91 DisableBindings,
92 ToolbarOptions,
93 SlitOptions,
94 ClickToFocus,
95 SloppyFocus,
96 AutoRaise,
97 ClickRaise,
98 IgnoreShadedWindows
99 };
100
Configmenu(bt::Application & app,unsigned int screen,BScreen * bscreen)101 Configmenu::Configmenu(bt::Application &app, unsigned int screen,
102 BScreen *bscreen)
103 : bt::Menu(app, screen), _bscreen(bscreen)
104 {
105 setAutoDelete(false);
106 setTitle(bt::toUnicode("Configuration Options"));
107 showTitle();
108
109 ConfigFocusmenu *focusmenu =
110 new ConfigFocusmenu(app, screen, bscreen);
111 ConfigPlacementmenu *placementmenu =
112 new ConfigPlacementmenu(app, screen, bscreen);
113 ConfigDithermenu *dithermenu =
114 new ConfigDithermenu(app, screen, bscreen);
115
116 insertItem(bt::toUnicode("Focus Model"), focusmenu, FocusModel);
117 insertItem(bt::toUnicode("Window Placement"),
118 placementmenu, WindowPlacement);
119 insertItem(bt::toUnicode("Image Dithering"), dithermenu, ImageDithering);
120 insertSeparator();
121 insertItem(bt::toUnicode("Opaque Window Moving"), OpaqueWindowMoving);
122 insertItem(bt::toUnicode("Opaque Window Resizing"), OpaqueWindowResizing);
123 insertItem(bt::toUnicode("Full Maximization"), FullMaximization);
124 insertItem(bt::toUnicode("Focus New Windows"), FocusNewWindows);
125 insertItem(bt::toUnicode("Focus Last Window on Workspace"),
126 FocusLastWindowOnWorkspace);
127 insertItem(bt::toUnicode("Change Workspace with Mouse Wheel"),
128 ChangeWorkspaceWithMouseWheel);
129 insertItem(bt::toUnicode("Shade Windows with Mouse Wheel"),
130 ShadeWindowWithMouseWheel);
131 insertItem(bt::toUnicode("Toolbar Actions with Mouse Wheel"),
132 ToolbarActionsWithMouseWheel);
133 insertItem(bt::toUnicode("Disable Bindings with Scroll Lock"),
134 DisableBindings);
135 insertSeparator();
136 insertItem(bt::toUnicode("Toolbar Options"),
137 bscreen->toolbarmenu(), ToolbarOptions);
138 insertItem(bt::toUnicode("Slit Options"), bscreen->slitmenu(), SlitOptions);
139 }
140
141
refresh(void)142 void Configmenu::refresh(void) {
143 const BlackboxResource &res = _bscreen->blackbox()->resource();
144 setItemChecked(OpaqueWindowMoving, res.opaqueMove());
145 setItemChecked(OpaqueWindowResizing, res.opaqueResize());
146 setItemChecked(FullMaximization, res.fullMaximization());
147 setItemChecked(FocusNewWindows, res.focusNewWindows());
148 setItemChecked(FocusLastWindowOnWorkspace, res.focusLastWindowOnWorkspace());
149 setItemChecked(ChangeWorkspaceWithMouseWheel,
150 res.changeWorkspaceWithMouseWheel());
151 setItemChecked(ShadeWindowWithMouseWheel,
152 res.shadeWindowWithMouseWheel());
153 setItemChecked(ToolbarActionsWithMouseWheel,
154 res.toolbarActionsWithMouseWheel());
155 setItemChecked(DisableBindings, res.allowScrollLock());
156 }
157
158
itemClicked(unsigned int id,unsigned int)159 void Configmenu::itemClicked(unsigned int id, unsigned int) {
160 BlackboxResource &res = _bscreen->blackbox()->resource();
161 switch (id) {
162 case OpaqueWindowMoving: // opaque move
163 res.setOpaqueMove(!res.opaqueMove());
164 break;
165
166 case OpaqueWindowResizing:
167 res.setOpaqueResize(!res.opaqueResize());
168 break;
169
170 case FullMaximization: // full maximization
171 res.setFullMaximization(!res.fullMaximization());
172 break;
173
174 case FocusNewWindows: // focus new windows
175 res.setFocusNewWindows(!res.focusNewWindows());
176 break;
177
178 case FocusLastWindowOnWorkspace: // focus last window on workspace
179 res.setFocusLastWindowOnWorkspace(!res.focusLastWindowOnWorkspace());
180 break;
181
182 case ChangeWorkspaceWithMouseWheel:
183 res.setChangeWorkspaceWithMouseWheel(!res.changeWorkspaceWithMouseWheel());
184 break;
185
186 case ShadeWindowWithMouseWheel:
187 res.setShadeWindowWithMouseWheel(!res.shadeWindowWithMouseWheel());
188 break;
189
190 case ToolbarActionsWithMouseWheel:
191 res.setToolbarActionsWithMouseWheel(!res.toolbarActionsWithMouseWheel());
192 break;
193
194 case DisableBindings: // disable keybindings with Scroll Lock
195 res.setAllowScrollLock(!res.allowScrollLock());
196 _bscreen->blackbox()->reconfigure();
197 break;
198
199 default:
200 return;
201 } // switch
202
203 res.save(*_bscreen->blackbox());
204 }
205
206
ConfigFocusmenu(bt::Application & app,unsigned int screen,BScreen * bscreen)207 ConfigFocusmenu::ConfigFocusmenu(bt::Application &app, unsigned int screen,
208 BScreen *bscreen)
209 : bt::Menu(app, screen), _bscreen(bscreen)
210 {
211 setTitle(bt::toUnicode("Focus Model"));
212 showTitle();
213
214 insertItem(bt::toUnicode("Click to Focus"), ClickToFocus);
215 insertItem(bt::toUnicode("Sloppy Focus"), SloppyFocus);
216 insertItem(bt::toUnicode("Auto Raise"), AutoRaise);
217 insertItem(bt::toUnicode("Click Raise"), ClickRaise);
218 }
219
220
refresh(void)221 void ConfigFocusmenu::refresh(void) {
222 const BlackboxResource &res = _bscreen->blackbox()->resource();
223
224 setItemChecked(ClickToFocus, res.focusModel() == ClickToFocusModel);
225 setItemChecked(SloppyFocus, res.focusModel() == SloppyFocusModel);
226
227 setItemEnabled(AutoRaise, res.focusModel() == SloppyFocusModel);
228 setItemChecked(AutoRaise, res.autoRaise());
229
230 setItemEnabled(ClickRaise, res.focusModel() == SloppyFocusModel);
231 setItemChecked(ClickRaise, res.clickRaise());
232 }
233
234
itemClicked(unsigned int id,unsigned int)235 void ConfigFocusmenu::itemClicked(unsigned int id, unsigned int) {
236 BlackboxResource &res = _bscreen->blackbox()->resource();
237 switch (id) {
238 case ClickToFocus:
239 _bscreen->toggleFocusModel(ClickToFocusModel);
240 break;
241
242 case SloppyFocus:
243 _bscreen->toggleFocusModel(SloppyFocusModel);
244 break;
245
246 case AutoRaise: // auto raise with sloppy focus
247 res.setAutoRaise(!res.autoRaise());
248 break;
249
250 case ClickRaise: // click raise with sloppy focus
251 res.setClickRaise(!res.clickRaise());
252 // make sure the appropriate mouse buttons are grabbed on the windows
253 _bscreen->toggleFocusModel(SloppyFocusModel);
254 break;
255
256 default: return;
257 } // switch
258 res.save(*_bscreen->blackbox());
259 }
260
261
ConfigPlacementmenu(bt::Application & app,unsigned int screen,BScreen * bscreen)262 ConfigPlacementmenu::ConfigPlacementmenu(bt::Application &app,
263 unsigned int screen,
264 BScreen *bscreen)
265 : bt::Menu(app, screen), _bscreen(bscreen)
266 {
267 setTitle(bt::toUnicode("Window Placement"));
268 showTitle();
269
270 insertItem(bt::toUnicode("Smart Placement (Rows)"), RowSmartPlacement);
271 insertItem(bt::toUnicode("Smart Placement (Columns)"), ColSmartPlacement);
272 insertItem(bt::toUnicode("Center Placement"), CenterPlacement);
273 insertItem(bt::toUnicode("Cascade Placement"), CascadePlacement);
274
275 insertSeparator();
276
277 insertItem(bt::toUnicode("Left to Right"), LeftRight);
278 insertItem(bt::toUnicode("Right to Left"), RightLeft);
279 insertItem(bt::toUnicode("Top to Bottom"), TopBottom);
280 insertItem(bt::toUnicode("Bottom to Top"), BottomTop);
281
282 insertSeparator();
283
284 insertItem(bt::toUnicode("Ignore Shaded Windows"), IgnoreShadedWindows);
285 }
286
287
refresh(void)288 void ConfigPlacementmenu::refresh(void) {
289 const BlackboxResource &res = _bscreen->blackbox()->resource();
290 bool rowsmart = res.windowPlacementPolicy() == RowSmartPlacement,
291 colsmart = res.windowPlacementPolicy() == ColSmartPlacement,
292 center = res.windowPlacementPolicy() == CenterPlacement,
293 cascade = res.windowPlacementPolicy() == CascadePlacement,
294 rl = res.rowPlacementDirection() == LeftRight,
295 tb = res.colPlacementDirection() == TopBottom;
296
297 setItemChecked(RowSmartPlacement, rowsmart);
298 setItemChecked(ColSmartPlacement, colsmart);
299 setItemChecked(CenterPlacement, center);
300 setItemChecked(CascadePlacement, cascade);
301
302 setItemEnabled(LeftRight, !center && !cascade);
303 setItemChecked(LeftRight, !center && (cascade || rl));
304
305 setItemEnabled(RightLeft, !center && !cascade);
306 setItemChecked(RightLeft, !center && (!cascade && !rl));
307
308 setItemEnabled(TopBottom, !center && !cascade);
309 setItemChecked(TopBottom, !center && (cascade || tb));
310
311 setItemEnabled(BottomTop, !center && !cascade);
312 setItemChecked(BottomTop, !center && (!cascade && !tb));
313
314 setItemEnabled(IgnoreShadedWindows, !center);
315 setItemChecked(IgnoreShadedWindows, !center && res.placementIgnoresShaded());
316 }
317
318
itemClicked(unsigned int id,unsigned int)319 void ConfigPlacementmenu::itemClicked(unsigned int id, unsigned int) {
320 BlackboxResource &res = _bscreen->blackbox()->resource();
321 switch (id) {
322 case RowSmartPlacement:
323 case ColSmartPlacement:
324 case CenterPlacement:
325 case CascadePlacement:
326 res.setWindowPlacementPolicy(id);
327 break;
328
329 case LeftRight:
330 case RightLeft:
331 res.setRowPlacementDirection(id);
332 break;
333
334 case TopBottom:
335 case BottomTop:
336 res.setColPlacementDirection(id);
337 break;
338
339 case IgnoreShadedWindows:
340 res.setPlacementIgnoresShaded(! res.placementIgnoresShaded());
341 break;
342
343 default:
344 return;
345 } // switch
346 res.save(*_bscreen->blackbox());
347 }
348
349
ConfigDithermenu(bt::Application & app,unsigned int screen,BScreen * bscreen)350 ConfigDithermenu::ConfigDithermenu(bt::Application &app, unsigned int screen,
351 BScreen *bscreen)
352 : bt::Menu(app, screen), _bscreen(bscreen)
353 {
354 setTitle(bt::toUnicode("Image Dithering"));
355 showTitle();
356
357 insertItem(bt::toUnicode("Do not dither images"), bt::NoDither);
358 insertItem(bt::toUnicode("Use fast dither"), bt::OrderedDither);
359 insertItem(bt::toUnicode("Use high-quality dither"), bt::FloydSteinbergDither);
360 }
361
362
refresh(void)363 void ConfigDithermenu::refresh(void) {
364 setItemChecked(bt::NoDither,
365 bt::Image::ditherMode() == bt::NoDither);
366 setItemChecked(bt::OrderedDither,
367 bt::Image::ditherMode() == bt::OrderedDither);
368 setItemChecked(bt::FloydSteinbergDither,
369 bt::Image::ditherMode() == bt::FloydSteinbergDither);
370 }
371
372
itemClicked(unsigned int id,unsigned int)373 void ConfigDithermenu::itemClicked(unsigned int id, unsigned int) {
374 bt::Image::setDitherMode((bt::DitherMode) id);
375 _bscreen->blackbox()->resource().save(*_bscreen->blackbox());
376 }
377