]>
Dogcows Code - chaz/tint2/blob - src/tint.c
badfa7f80146d4443d508e0066f375106819b4bb
1 /**************************************************************************
5 * Copyright (C) 2007 Pål Staurland (staura@gmail.com)
6 * Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 **************************************************************************/
27 #include <X11/Xutil.h>
28 #include <X11/Xatom.h>
29 #include <X11/Xlocale.h>
44 void signal_handler(int sig
)
46 // signal handler is light as it should be
47 panel
.signal_pending
= sig
;
54 signal(SIGUSR1
, signal_handler
);
55 signal(SIGINT
, signal_handler
);
56 signal(SIGTERM
, signal_handler
);
59 memset(&panel
, 0, sizeof(Panel
));
60 memset(&server
, 0, sizeof(Server_global
));
61 memset(&g_task
, 0, sizeof(Global_task
));
62 memset(&g_taskbar
, 0, sizeof(Area
));
63 panel
.clock
.area
.draw_foreground
= draw_foreground_clock
;
64 g_task
.area
.draw_foreground
= draw_foreground_task
;
67 server
.dsp
= XOpenDisplay (NULL
);
69 fprintf(stderr
, "Could not open display.\n");
73 server
.screen
= DefaultScreen (server
.dsp
);
74 server
.root_win
= RootWindow(server
.dsp
, server
.screen
);
75 server
.depth
= DefaultDepth (server
.dsp
, server
.screen
);
76 server
.visual
= DefaultVisual (server
.dsp
, server
.screen
);
77 server
.desktop
= server_get_current_desktop ();
79 XSetErrorHandler ((XErrorHandler
) server_catch_error
);
83 root
= RootWindow(display
, DefaultScreen(display
));
84 //create_main_window();
89 imlib_context_set_display (server
.dsp
);
90 imlib_context_set_visual (server
.visual
);
91 imlib_context_set_colormap (DefaultColormap (server
.dsp
, server
.screen
));
94 XSelectInput (server
.dsp
, server
.root_win
, PropertyChangeMask
|StructureNotifyMask
);
96 setlocale (LC_ALL
, "");
100 void window_action (Task
*tsk
, int action
)
104 set_close (tsk
->win
);
107 set_active(tsk
->win
);
110 XIconifyWindow (server
.dsp
, tsk
->win
, server
.screen
);
113 if (tsk
== panel
.task_active
) XIconifyWindow (server
.dsp
, tsk
->win
, server
.screen
);
114 else set_active (tsk
->win
);
117 window_toggle_shade (tsk
->win
);
123 void event_button_press (int x
, int y
)
125 if (panel
.mode
== SINGLE_DESKTOP
) {
126 // drag and drop disabled
127 XLowerWindow (server
.dsp
, window
.main_win
);
133 for (l0
= panel
.area
.list
; l0
; l0
= l0
->next
) {
135 if (x
>= tskbar
->area
.posx
&& x
<= (tskbar
->area
.posx
+ tskbar
->area
.width
))
141 for (l0
= tskbar
->area
.list
; l0
; l0
= l0
->next
) {
143 if (x
>= tsk
->area
.posx
&& x
<= (tsk
->area
.posx
+ tsk
->area
.width
)) {
144 panel
.task_drag
= tsk
;
150 XLowerWindow (server
.dsp
, window
.main_win
);
154 void event_button_release (int button
, int x
, int y
)
156 int action
= TOGGLE_ICONIFY
;
157 // TODO: convert event_button_press(int x, int y) to area->event_button_press()
162 action
= panel
.mouse_middle
;
165 action
= panel
.mouse_right
;
168 action
= panel
.mouse_scroll_up
;
171 action
= panel
.mouse_scroll_down
;
178 for (l0
= panel
.area
.list
; l0
; l0
= l0
->next
) {
180 if (x
>= tskbar
->area
.posx
&& x
<= (tskbar
->area
.posx
+ tskbar
->area
.width
))
184 // TODO: check better solution to keep window below
185 XLowerWindow (server
.dsp
, window
.main_win
);
190 // drag and drop task
191 if (panel
.task_drag
) {
192 if (tskbar
!= panel
.task_drag
->area
.parent
&& action
== TOGGLE_ICONIFY
) {
193 windows_set_desktop(panel
.task_drag
->win
, tskbar
->desktop
);
194 if (tskbar
->desktop
== server
.desktop
)
195 set_active(panel
.task_drag
->win
);
199 else panel
.task_drag
= 0;
203 if (panel
.mode
== MULTI_DESKTOP
)
204 if (tskbar
->desktop
!= server
.desktop
&& action
!= CLOSE
)
205 set_desktop (tskbar
->desktop
);
210 for (l
= tskbar
->area
.list
; l
; l
= l
->next
) {
212 if (x
>= tsk
->area
.posx
&& x
<= (tsk
->area
.posx
+ tsk
->area
.width
)) {
213 window_action (tsk
, action
);
218 // to keep window below
219 XLowerWindow (server
.dsp
, window
.main_win
);
223 void event_property_notify (Window win
, Atom at
)
226 if (win
== server
.root_win
) {
227 if (!server
.got_root_win
) {
228 XSelectInput (server
.dsp
, server
.root_win
, PropertyChangeMask
|StructureNotifyMask
);
229 server
.got_root_win
= 1;
232 /* Change number of desktops */
233 else if (at
== server
.atom
._NET_NUMBER_OF_DESKTOPS
) {
238 else if (at
== server
.atom
._NET_CURRENT_DESKTOP
) {
239 server
.desktop
= server_get_current_desktop ();
240 if (panel
.mode
!= MULTI_DESKTOP
) {
245 else if (at
== server
.atom
._NET_CLIENT_LIST
) {
246 task_refresh_tasklist ();
250 else if (at
== server
.atom
._NET_ACTIVE_WINDOW
) {
251 if (panel
.task_active
) {
252 panel
.task_active
->area
.is_active
= 0;
253 panel
.task_active
= 0;
255 Window w1
= window_get_active ();
256 Task
*t
= task_get_task(w1
);
259 if (XGetTransientForHint(server
.dsp
, w1
, &w2
) != 0)
260 if (w2
) t
= task_get_task(w2
);
263 t
->area
.is_active
= 1;
264 panel
.task_active
= t
;
268 /* Wallpaper changed */
269 else if (at
== server
.atom
._XROOTPMAP_ID
) {
270 XFreePixmap (server
.dsp
, panel
.area
.pix
.pmap
);
271 panel
.area
.pix
.pmap
= 0;
277 tsk
= task_get_task (win
);
279 //printf("atom root_win = %s, %s\n", XGetAtomName(server.dsp, at), tsk->title);
281 /* Window title changed */
282 if (at
== server
.atom
._NET_WM_VISIBLE_NAME
|| at
== server
.atom
._NET_WM_NAME
|| at
== server
.atom
.WM_NAME
) {
284 tsk
->area
.redraw
= 1;
288 else if (at
== server
.atom
.WM_STATE
) {
289 if (window_is_iconified (win
))
290 if (panel
.task_active
== tsk
) {
291 tsk
->area
.is_active
= 0;
292 panel
.task_active
= 0;
295 /* Window icon changed */
296 else if (at
== server
.atom
._NET_WM_ICON
) {
297 if (tsk
->icon_data
) {
298 free (tsk
->icon_data
);
301 tsk
->area
.redraw
= 1;
304 /* Window desktop changed */
305 else if (at
== server
.atom
._NET_WM_DESKTOP
) {
311 if (!server
.got_root_win
) server
.root_win
= RootWindow (server
.dsp
, server
.screen
);
316 void event_configure_notify (Window win
)
320 tsk
= task_get_task (win
);
323 Taskbar
*tskbar
= tsk
->area
.parent
;
324 if (tskbar
->monitor
!= window_get_monitor (win
)) {
325 // task on another monitor
337 if (!panel
.clock
.time1_format
) return;
339 if (gettimeofday(&stv
, 0)) return;
341 if (abs(stv
.tv_sec
- panel
.clock
.clock
.tv_sec
) < panel
.clock
.time_precision
) return;
344 panel
.clock
.clock
.tv_sec
= stv
.tv_sec
;
345 panel
.clock
.clock
.tv_sec
-= panel
.clock
.clock
.tv_sec
% panel
.clock
.time_precision
;
346 panel
.clock
.area
.redraw
= 1;
351 int main (int argc
, char *argv
[])
358 c
= getopt (argc
, argv
, "c:");
362 if (panel
.area
.pix
.pmap
) XFreePixmap (server
.dsp
, panel
.area
.pix
.pmap
);
363 panel
.area
.pix
.pmap
= 0;
364 // append full transparency background
365 list_back
= g_slist_append(0, calloc(1, sizeof(Area
)));
367 // read tint2rc config
370 i
= config_read_file (optarg
);
374 fprintf(stderr
, "usage: tint2 [-c] <config_file>\n");
380 window_draw_panel ();
382 // BUG: refresh(clock) is needed here, but 'on the paper' it's not necessary.
383 refresh(&panel
.clock
.area
);
385 x11_fd
= ConnectionNumber (server
.dsp
);
386 XSync (server
.dsp
, False
);
389 // thanks to AngryLlama for the timer
390 // Create a File Description Set containing x11_fd
392 FD_SET (x11_fd
, &fd
);
397 // Wait for X Event or a Timer
398 if (select(x11_fd
+1, &fd
, 0, 0, &tv
)) {
399 while (XPending (server
.dsp
)) {
400 XNextEvent(server
.dsp
, &e
);
404 if (e
.xbutton
.button
== 1) event_button_press (e
.xbutton
.x
, e
.xbutton
.y
);
408 event_button_release (e
.xbutton
.button
, e
.xbutton
.x
, e
.xbutton
.y
);
412 XCopyArea (server
.dsp
, panel
.area
.pix
.pmap
, server
.root_win
, server
.gc_root
, 0, 0, panel
.area
.width
, panel
.area
.height
, server
.posx
, server
.posy
);
413 XCopyArea (server
.dsp
, server
.pmap
, window
.main_win
, server
.gc
, panel
.area
.paddingx
, 0, panel
.area
.width
-(2*panel
.area
.paddingx
), panel
.area
.height
, 0, 0);
417 //printf("PropertyNotify\n");
418 event_property_notify (e
.xproperty
.window
, e
.xproperty
.atom
);
421 case ConfigureNotify
:
422 if (e
.xconfigure
.window
== server
.root_win
)
425 if (panel
.mode
== MULTI_MONITOR
)
426 event_configure_notify (e
.xconfigure
.window
);
433 switch (panel
.signal_pending
) {
442 if (panel
.refresh
&& !panel
.sleep_mode
) {
444 //printf(" *** visual_refresh\n");
This page took 0.052773 seconds and 4 git commands to generate.