version bump
[blackbox.git] / src / Windowmenu.cc
blob53f7b1d85eef0d3af07ed0ed8b8bebaae5e05123
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Windowmenu.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:
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
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.
25 #include "Windowmenu.hh"
26 #include "Screen.hh"
27 #include "Window.hh"
28 #include "Workspace.hh"
30 #include <Unicode.hh>
32 #include <assert.h>
34 // #define WITH_FULLSCREEN
37 class SendToWorkspacemenu : public bt::Menu {
38 public:
39 SendToWorkspacemenu(bt::Application &app, unsigned int screen);
41 inline void setWindow(BlackboxWindow *win)
42 { _window = win; }
44 void refresh(void);
46 protected:
47 virtual void itemClicked(unsigned int id, unsigned int button);
49 private:
50 BlackboxWindow *_window;
54 enum {
55 SendToWorkspace,
56 OccupyAllWorkspaces,
57 Shade,
58 Iconify,
59 Maximize,
60 #if defined(WITH_FULLSCREEN)
61 FullScreen,
62 #endif
63 AlwaysOnTop,
64 AlwaysOnBottom,
65 KillClient,
66 Close
69 Windowmenu::Windowmenu(bt::Application &app, unsigned int screen)
70 : bt::Menu(app, screen), _window(0)
72 _sendto = new SendToWorkspacemenu(app, screen);
73 insertItem(bt::toUnicode("Send to Workspace"), _sendto, SendToWorkspace);
74 insertItem(bt::toUnicode("Occupy all Workspaces"), OccupyAllWorkspaces);
75 insertSeparator();
76 insertItem(bt::toUnicode("Shade"), Shade);
77 insertItem(bt::toUnicode("Iconify"), Iconify);
78 insertItem(bt::toUnicode("Maximize"), Maximize);
79 #if defined(WITH_FULLSCREEN)
80 insertItem(bt::toUnicode("Full Screen"), FullScreen);
81 #endif
82 insertItem(bt::toUnicode("Always on top"), AlwaysOnTop);
83 insertItem(bt::toUnicode("Always on bottom"), AlwaysOnBottom);
84 insertSeparator();
85 insertItem(bt::toUnicode("Kill Client"), KillClient);
86 insertItem(bt::toUnicode("Close"), Close);
90 void Windowmenu::setWindow(BlackboxWindow *win) {
91 _window = win;
92 _sendto->setWindow(win);
96 void Windowmenu::hide(void) {
97 bt::Menu::hide();
98 setWindow(0);
102 void Windowmenu::refresh(void) {
103 assert(_window != 0);
105 setItemEnabled(SendToWorkspace,
106 _window->hasWindowFunction(WindowFunctionChangeWorkspace)
107 && _window->workspace() != bt::BSENTINEL);
109 setItemEnabled(OccupyAllWorkspaces,
110 _window->hasWindowFunction(WindowFunctionChangeWorkspace));
111 setItemChecked(OccupyAllWorkspaces,
112 _window->workspace() == bt::BSENTINEL);
114 setItemEnabled(Shade, _window->hasWindowFunction(WindowFunctionShade));
115 setItemChecked(Shade, _window->isShaded());
117 setItemEnabled(Iconify, _window->hasWindowFunction(WindowFunctionIconify));
118 setItemChecked(Iconify, _window->isIconic());
120 setItemEnabled(Maximize, _window->hasWindowFunction(WindowFunctionMaximize));
121 setItemChecked(Maximize, _window->isMaximized());
123 #if defined(WITH_FULLSCREEN)
124 setItemEnabled(FullScreen, _window->windowType() == WindowTypeNormal);
125 setItemChecked(FullScreen, _window->isFullScreen());
126 #endif
128 setItemEnabled(AlwaysOnTop,
129 _window->hasWindowFunction(WindowFunctionChangeLayer));
130 setItemChecked(AlwaysOnTop,
131 _window->layer() == StackingList::LayerAbove);
133 setItemEnabled(AlwaysOnBottom,
134 _window->hasWindowFunction(WindowFunctionChangeLayer));
135 setItemChecked(AlwaysOnBottom,
136 _window->layer() == StackingList::LayerBelow);
138 setItemEnabled(KillClient, !_window->isTransient());
140 setItemEnabled(Close, _window->hasWindowFunction(WindowFunctionClose));
144 void Windowmenu::itemClicked(unsigned int id, unsigned int) {
145 switch (id) {
146 case OccupyAllWorkspaces:
148 BScreen *screen = _window->screen();
149 unsigned int workspace = (_window->workspace() == bt::BSENTINEL
150 ? screen->currentWorkspace()
151 : bt::BSENTINEL);
152 _window->changeWorkspace(workspace);
153 break;
156 case Shade:
157 _window->setShaded(!_window->isShaded());
158 break;
160 case Iconify:
161 _window->iconify();
162 break;
164 case Maximize:
165 _window->maximize(1);
166 break;
168 #if defined(WITH_FULLSCREEN)
169 case FullScreen:
170 _window->setFullScreen(!_window->isFullScreen());
171 break;
172 #endif
174 case AlwaysOnTop:
176 StackingList::Layer new_layer =
177 (_window->layer() == StackingList::LayerAbove
178 ? StackingList::LayerNormal
179 : StackingList::LayerAbove);
180 _window->changeLayer(new_layer);
181 break;
184 case AlwaysOnBottom:
186 StackingList::Layer new_layer =
187 (_window->layer() == StackingList::LayerBelow
188 ? StackingList::LayerNormal
189 : StackingList::LayerBelow);
190 _window->changeLayer(new_layer);
191 break;
194 case KillClient:
195 XKillClient(_window->screen()->screenInfo().display().XDisplay(),
196 _window->clientWindow());
197 break;
199 case Close:
200 _window->close();
201 break;
202 } // switch
206 SendToWorkspacemenu::SendToWorkspacemenu(bt::Application &app,
207 unsigned int screen)
208 : bt::Menu(app, screen), _window(0)
212 void SendToWorkspacemenu::refresh(void) {
213 assert(_window != 0);
215 clear();
216 BScreen *screen = _window->screen();
217 const unsigned num = screen->workspaceCount();
218 for (unsigned int i = 0; i < num; ++i)
219 insertItem(screen->resource().workspaceName(i), i);
222 give a little visual indication to the user about which workspace
223 the window is on. you obviously can't send a window to the workspace
224 the window is already on, which is why it is checked and disabled
226 setItemEnabled(_window->workspace(), false);
227 setItemChecked(_window->workspace(), true);
231 void SendToWorkspacemenu::itemClicked(unsigned int id, unsigned int button) {
232 assert(_window != 0);
233 _window->changeWorkspace(id,
234 (button == 2
235 ? BlackboxWindow::SwitchToNewWorkspace
236 : BlackboxWindow::StayOnCurrentWorkspace));
238 if (button == 2) {
239 BScreen *screen = _window->screen();
240 screen->setCurrentWorkspace(_window->workspace());