1 /*
2 * IceWM
3 *
4 * Copyright (C) 1997-2002 Marko Macek
5 *
6 * Status display for resize/move
7 */
8 #include "config.h"
9
10 #include "yfull.h"
11 #include "wmstatus.h"
12 #include "wpixmaps.h"
13 #include "wmframe.h"
14 #include "wmclient.h"
15 #include "wmmgr.h"
16 #include "prefs.h"
17 #include "yprefs.h"
18 #include "yrect.h"
19 #include "workspaces.h"
20 #include "intl.h"
21
22 #include <stdio.h>
23 #include <string.h>
24
25 YColorName YWindowManagerStatus::statusFg(&clrMoveSizeStatusText);
26 YColorName YWindowManagerStatus::statusBg(&clrMoveSizeStatus);
27
28 YFont YWindowManagerStatus::statusFont;
29
30 lazy<MoveSizeStatus> statusMoveSize;
31 lazy<WorkspaceStatus> statusWorkspace;
32
33 /******************************************************************************/
34 /******************************************************************************/
35
YWindowManagerStatus()36 YWindowManagerStatus::YWindowManagerStatus()
37 : YWindow()
38 , fScreen(-1)
39 , fConfigured(false)
40 {
41 setStyle(wsOverrideRedirect | wsSaveUnder | wsNoExpose);
42 setTitle("IceStatus");
43 setClassHint("status", "IceWM");
44 setNetWindowType(_XA_NET_WM_WINDOW_TYPE_NOTIFICATION);
45 }
46
~YWindowManagerStatus()47 YWindowManagerStatus::~YWindowManagerStatus() {
48 if (statusMoveSize == nullptr || statusWorkspace == nullptr)
49 statusFont = null;
50 }
51
configure(const YRect2 & r)52 void YWindowManagerStatus::configure(const YRect2& r) {
53 if (fConfigured == false || r.resized()) {
54 configureStatus();
55 }
56 }
57
configureStatus()58 void YWindowManagerStatus::configureStatus() {
59 fConfigured = true;
60
61 if (statusFont == null)
62 statusFont = statusFontName;
63
64 int sW = statusFont->textWidth(longestStatus());
65 int sH = statusFont->height();
66
67 YRect geo(desktop->getScreenGeometry(fScreen));
68 setGeometry(YRect(geo.x() + (geo.width() - sW) / 2,
69 geo.y() + (geo.height() - sH) - 8, // / 2,
70 sW + 2, sH + 4));
71 }
72
repaintSync()73 void YWindowManagerStatus::repaintSync() {
74 if (fConfigured == false) {
75 configureStatus();
76 }
77 GraphicsBuffer(this).paint();
78 }
79
paint(Graphics & g,const YRect &)80 void YWindowManagerStatus::paint(Graphics &g, const YRect &/*r*/) {
81 g.setColor(statusBg);
82 g.drawBorderW(0, 0, width() - 1, height() - 1, true);
83 int x = 1, y = 1, w = int(width()) - 3, h = int(height()) - 3;
84 if (0 < w && 0 < h) {
85 if (switchbackPixbuf != null)
86 g.drawGradient(switchbackPixbuf, x, y, w, h, 0, 0, w, h);
87 else if (switchbackPixmap != null)
88 g.fillPixmap(switchbackPixmap, x, y, w, h);
89 else
90 g.fillRect(x, y, w, h);
91 }
92 if (statusFont) {
93 mstring status(getStatus());
94 g.setFont(statusFont);
95 g.setColor(statusFg);
96 g.drawChars(status,
97 width() / 2 - statusFont->textWidth(status) / 2,
98 height() - statusFont->descent() - 2);
99 }
100 }
101
begin()102 void YWindowManagerStatus::begin() {
103 YRect geo(desktop->getScreenGeometry(fScreen));
104 setPosition(x(),
105 taskBarAtTop ? 4 : int(geo.height() - height()) - 4);
106 raise();
107 show();
108 }
109
110 /******************************************************************************/
111 /******************************************************************************/
112
MoveSizeStatus()113 MoveSizeStatus::MoveSizeStatus()
114 : YWindowManagerStatus(),
115 fX(0), fY(0), fW(0), fH(0) {
116 }
117
~MoveSizeStatus()118 MoveSizeStatus::~MoveSizeStatus() {
119 }
120
end()121 void MoveSizeStatus::end() {
122 super::end();
123 statusMoveSize = null;
124 }
125
longestStatus()126 mstring MoveSizeStatus::longestStatus() {
127 return "9999x9999+9999+9999";
128 }
129
getStatus()130 mstring MoveSizeStatus::getStatus() {
131 char status[50];
132 snprintf(status, 50, "%dx%d%+d%+d", fW, fH, fX, fY);
133 return status;
134 }
135
begin(YFrameWindow * frame)136 void MoveSizeStatus::begin(YFrameWindow *frame) {
137 if (showMoveSizeStatus) {
138 setStatus(frame);
139 YWindowManagerStatus::begin();
140 }
141 }
142
setStatus(YFrameWindow * frame,const YRect & r)143 void MoveSizeStatus::setStatus(YFrameWindow *frame, const YRect &r) {
144 XSizeHints *sh = frame->client()->sizeHints();
145
146 int width = r.width() - frame->borderX() * 2;
147 int height = r.height() - frame->borderY() * 2 - frame->titleY();
148
149 fX = r.x();
150 fY = r.y();
151 if (sh && (sh->flags & PResizeInc)) {
152 fW = (width - sh->base_width) / max(1, sh->width_inc);
153 fH = (height - sh->base_height) / max(1, sh->height_inc);
154 } else {
155 fW = width;
156 fH = height;
157 }
158 setScreen(desktop->getScreenForRect(r.x(), r.y(), r.width(), r.height()));
159 repaintSync();
160 }
161
setStatus(YFrameWindow * frame)162 void MoveSizeStatus::setStatus(YFrameWindow *frame) {
163 XSizeHints *sh = frame->client()->sizeHints();
164
165 fX = frame->x ();//// + frame->borderX ();
166 fY = frame->y ();//// + frame->borderY () + frame->titleY ();
167 if (sh && (sh->flags & PResizeInc)) {
168 fW = (frame->client()->width() - sh->base_width) / max(1, sh->width_inc);
169 fH = (frame->client()->height() - sh->base_height) / max(1, sh->height_inc);
170 } else {
171 fW = frame->client()->width();
172 fH = frame->client()->height();
173 }
174 setScreen(frame->getScreen());
175 repaintSync();
176 }
177
178 /******************************************************************************/
179 /******************************************************************************/
180
handleTimer(YTimer * t)181 bool WorkspaceStatus::handleTimer(YTimer *t) {
182 if (t == &timer) {
183 end();
184 }
185 return false;
186 };
187
WorkspaceStatus()188 WorkspaceStatus::WorkspaceStatus() :
189 YWindowManagerStatus(),
190 workspace(0),
191 timer(workspaceStatusTime, this, false)
192 {
193 }
194
~WorkspaceStatus()195 WorkspaceStatus::~WorkspaceStatus() {
196 }
197
end()198 void WorkspaceStatus::end() {
199 super::end();
200 statusWorkspace = null;
201 }
202
getStatus()203 mstring WorkspaceStatus::getStatus() {
204 return getStatus(workspaceNames[workspace]);
205 }
206
getStatus(const char * name)207 mstring WorkspaceStatus::getStatus(const char* name) {
208 return mstring(_("Workspace: ")).append(name);
209 }
210
begin(long workspace)211 void WorkspaceStatus::begin(long workspace) {
212 setStatus(workspace);
213 YWindowManagerStatus::begin();
214 }
215
setStatus(long workspace)216 void WorkspaceStatus::setStatus(long workspace) {
217 this->workspace = workspace;
218 repaintSync();
219
220 timer.stopTimer();
221 timer.startTimer();
222 }
223
longestStatus()224 mstring WorkspaceStatus::longestStatus() {
225 const char* longestWorkspaceName = nullptr;
226 int maxWorkspaceNameLength = 0;
227
228 for (int w = 0; w < workspaceCount; ++w) {
229 const char* name = workspaceNames[w];
230 int length = statusFont->textWidth(name);
231
232 if (length > maxWorkspaceNameLength) {
233 maxWorkspaceNameLength = length;
234 longestWorkspaceName = name;
235 }
236 }
237
238 return getStatus(longestWorkspaceName);
239 }
240
241 // vim: set sw=4 ts=4 et:
242