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