💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Menkar › files › 74f0e4c66917cbb0fcf008443ad… captured on 2023-05-24 at 18:31:37. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-03-20)

➡️ Next capture (2023-09-08)

-=-=-=-=-=-=-

0 /*

1 * title.c - window titles

2 */

3

4 /*

5 * Copyright 2006-2007 Johan Veenhuizen

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

15 * in 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

26 #include <assert.h>

27 #include <string.h>

28

29 #include <X11/Xlib.h>

30 #include <X11/Xutil.h>

31

32 #include "global.h"

33 #include "menu.h"

34 #include "lib.h"

35 #include "monitor.h"

36 #include "title.h"

37 #include "window.h"

38

39 static void prepare_repaint(struct widget *widget)

40 {

41 struct title *title = (struct title *)widget;

42

43 if (window_family_is_active(title->window)) {

44 title->fg = &color_title_active_fg;

45 title->bg = &color_title_active_bg;

46 } else {

47 title->fg = &color_title_inactive_fg;

48 title->bg = &color_title_inactive_bg;

49 }

50

51 XSetWindowBackground(display, WIDGET_XWINDOW(title),

52 title->bg->normal);

53 }

54

55 static void repaint(struct widget *widget)

56 {

57 struct title *title = (struct title *)widget;

58 struct window *win = title->window;

59 struct color *fg = title->fg;

60 struct color *bg = title->bg;

61 char *buf = NULL;

62 int xpad = title_pad + 2 * font->descent; /* this looks reasonable */

63 int ypad = MAX(3, 2 * title_pad);

64 int maxwidth = window_is_active(win) ?

65 WIDGET_WIDTH(title) - 2 * xpad - ypad - WIDGET_WIDTH(title) / 5 :

66 WIDGET_WIDTH(title) - 2 * xpad;

67 int off;

68

69 /* clear */

70 XSetForeground(display, title->gc, bg->normal);

71 XFillRectangle(display, title->pixmap, title->gc,

72 0, 0, WIDGET_WIDTH(title), WIDGET_HEIGHT(title));

73

74 /* repaint */

75 if (window_is_ontop(title->window)) {

76 drawdepressed(title->pixmap, title->gc, bg,

77 0, 0, WIDGET_WIDTH(title), WIDGET_HEIGHT(title));

78 off = 1;

79 } else {

80 drawraised(title->pixmap, title->gc, bg,

81 0, 0, WIDGET_WIDTH(title), WIDGET_HEIGHT(title));

82 off = 0;

83 }

84

85 XSetForeground(display, title->gc, fg->normal);

86 if (win->name != NULL && strlen(win->name) > 0) {

87 buf = STRDUP(win->name);

88 stringfit(buf, maxwidth);

89 XDrawString(display, title->pixmap, title->gc,

90 xpad + off,

91 title_pad + font->ascent + off,

92 buf, strlen(buf));

93 }

94

95 if (window_is_active(win)) {

96 int x, y;

97 int m = 0;

98

99 x = (buf == NULL || strlen(buf) == 0) ?

100 ypad : stringwidth(buf) + 2 * xpad;

101 x += off;

102 if (x < WIDGET_WIDTH(title) - 1 - ypad) {

103 for (y = ypad + off;

104 y < WIDGET_HEIGHT(title) - 1 - ypad + off;

105 y++) {

106 XSetForeground(display, title->gc,

107 m ? bg->shadow2 : bg->bright2);

108 XDrawLine(display, title->pixmap, title->gc,

109 m + x, y,

110 m + WIDGET_WIDTH(title)-2 - ypad + off, y);

111 m = !m;

112 }

113 }

114 }

115

116 /* display */

117 if (WIDGET_MAPPED(title))

118 XCopyArea(display,

119 title->pixmap, WIDGET_XWINDOW(title), title->gc,

120 0, 0, WIDGET_WIDTH(title), WIDGET_HEIGHT(title), 0, 0);

121

122 FREE(buf);

123 }

124

125 static void titleevent(struct widget *widget, XEvent *ep)

126 {

127 struct title *title = (struct title *)widget;

128 Window dummy;

129

130 switch (ep->type) {

131 case ButtonPress:

132 if (ep->xbutton.button == Button1) {

133 if (title->lastclick > ep->xbutton.time - 250) {

134 maximize_window(title->window, ep->xbutton.x_root, ep->xbutton.y_root);

135 } else {

136 XTranslateCoordinates(display,

137 WIDGET_XWINDOW(title),

138 WIDGET_XWINDOW(title->window),

139 ep->xbutton.x,

140 ep->xbutton.y,

141 &title->xoff,

142 &title->yoff,

143 &dummy);

144 if (ep->xbutton.state & ShiftMask)

145 toggle_window_ontop(title->window);

146 set_active_window(title->window);

147

148 beginfastmove(WIDGET_XWINDOW(title));

149 title->moving = 1;

150 }

151 title->lastclick = ep->xbutton.time;

152 } else if (ep->xbutton.button == Button3)

153 show_menu(winmenu,

154 ep->xbutton.x_root, ep->xbutton.y_root,

155 ep->xbutton.button);

156 break;

157 case ButtonRelease:

158 if (ep->xbutton.button == Button1 && title->moving) {

159 title->moving = 0;

160 endfastmove();

161 for(int i=0; i<monitors_len; i++) {

162 if(ep->xbutton.x_root>monitors[i].x&&ep->xbutton.x_root<monitors[i].x+monitors[i].w&&ep->xbutton.y_root < monitors[i].y+1) {

163 maximize_window(title->window, ep->xbutton.x_root, ep->xbutton.y_root);

164 }

165 }

166

167 }

168 break;

169 case MotionNotify:

170 if (title->moving) {

171 if (ep->xmotion.state & ControlMask)

172 move_window_family(title->window,

173 ep->xmotion.x_root - title->xoff,

174 ep->xmotion.y_root - title->yoff);

175 else

176 move_window(title->window,

177 ep->xmotion.x_root - title->xoff,

178 ep->xmotion.y_root - title->yoff);

179 }

180 break;

181 case Expose:

182 XCopyArea(display, title->pixmap, WIDGET_XWINDOW(title),

183 title->gc, ep->xexpose.x, ep->xexpose.y,

184 ep->xexpose.width, ep->xexpose.height,

185 ep->xexpose.x, ep->xexpose.y);

186 break;

187 }

188 }

189

190 struct title *create_title(struct window *window, int x, int y,

191 int width, int height)

192 {

193 XGCValues gcval;

194 struct title *tp;

195

196 tp = MALLOC(sizeof (struct title));

197 create_widget(&tp->widget, WIDGET_TITLE, WIDGET_XWINDOW(window),

198 InputOutput, x, y, width, height);

199 tp->pixmap = XCreatePixmap(display, WIDGET_XWINDOW(tp),

200 tp->pixmapwidth = width, tp->pixmapheight = height,

201 DefaultDepth(display, screen));

202 gcval.graphics_exposures = False;

203 tp->gc = XCreateGC(display, WIDGET_XWINDOW(tp),

204 GCGraphicsExposures, &gcval);

205 XSetFont(display, tp->gc, font->fid);

206 tp->window = window;

207 tp->widget.event = titleevent;

208 tp->widget.prepare_repaint = prepare_repaint;

209 tp->widget.repaint = repaint;

210 XSelectInput(display, WIDGET_XWINDOW(tp),

211 ButtonPressMask | ButtonMotionMask | ButtonReleaseMask |

212 ExposureMask);

213 tp->moving = 0;

214 tp->lastclick = 0;

215 REPAINT(tp);

216 map_widget(&tp->widget);

217 return tp;

218 }

219

220 void resize_title(struct title *tp, int width, int height)

221 {

222 if (!tp) return;

223 if (width > tp->pixmapwidth || height > tp->pixmapheight) {

224 XFreePixmap(display, tp->pixmap);

225 if (width > tp->pixmapwidth)

226 tp->pixmapwidth = MAX(LARGER(tp->pixmapwidth),

227 width);

228 if (height > tp->pixmapheight)

229 tp->pixmapheight = MAX(LARGER(tp->pixmapheight),

230 height);

231 debug("increasing title pixmap size (%dx%d)",

232 tp->pixmapwidth, tp->pixmapheight);

233 tp->pixmap = XCreatePixmap(display, WIDGET_XWINDOW(tp),

234 tp->pixmapwidth, tp->pixmapheight,

235 DefaultDepth(display, screen));

236 }

237

238 resize_widget(&tp->widget, width, height);

239 REPAINT(tp);

240 }

241

242 void destroy_title(struct title *title)

243 {

244 destroy_widget(&title->widget);

245 XFreePixmap(display, title->pixmap);

246 XFreeGC(display, title->gc);

247 FREE(title);

248 }

249