]>
Dogcows Code - chaz/tint2/blob - src/tint.c
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 server
.gc
= XCreateGC (server
.dsp
, server
.root_win
, (unsigned long)0, &gcv
) ;
81 XSetErrorHandler ((XErrorHandler
) server_catch_error
);
84 //display = server.dsp;
85 //root = RootWindow(display, DefaultScreen(display));
86 //create_main_window();
91 imlib_context_set_display (server
.dsp
);
92 imlib_context_set_visual (server
.visual
);
93 imlib_context_set_colormap (DefaultColormap (server
.dsp
, server
.screen
));
96 XSelectInput (server
.dsp
, server
.root_win
, PropertyChangeMask
|StructureNotifyMask
);
98 setlocale (LC_ALL
, "");
102 void window_action (Task
*tsk
, int action
)
106 set_close (tsk
->win
);
109 set_active(tsk
->win
);
112 XIconifyWindow (server
.dsp
, tsk
->win
, server
.screen
);
115 if (tsk
== panel
.task_active
) XIconifyWindow (server
.dsp
, tsk
->win
, server
.screen
);
116 else set_active (tsk
->win
);
119 window_toggle_shade (tsk
->win
);
125 void event_button_press (int x
, int y
)
127 if (panel
.mode
== SINGLE_DESKTOP
) {
128 // drag and drop disabled
129 XLowerWindow (server
.dsp
, window
.main_win
);
135 for (l0
= panel
.area
.list
; l0
; l0
= l0
->next
) {
137 if (x
>= tskbar
->area
.posx
&& x
<= (tskbar
->area
.posx
+ tskbar
->area
.width
))
143 for (l0
= tskbar
->area
.list
; l0
; l0
= l0
->next
) {
145 if (x
>= tsk
->area
.posx
&& x
<= (tsk
->area
.posx
+ tsk
->area
.width
)) {
146 panel
.task_drag
= tsk
;
152 XLowerWindow (server
.dsp
, window
.main_win
);
156 void event_button_release (int button
, int x
, int y
)
158 int action
= TOGGLE_ICONIFY
;
159 // TODO: convert event_button_press(int x, int y) to area->event_button_press()
164 action
= panel
.mouse_middle
;
167 action
= panel
.mouse_right
;
170 action
= panel
.mouse_scroll_up
;
173 action
= panel
.mouse_scroll_down
;
180 for (l0
= panel
.area
.list
; l0
; l0
= l0
->next
) {
182 if (x
>= tskbar
->area
.posx
&& x
<= (tskbar
->area
.posx
+ tskbar
->area
.width
))
186 // TODO: check better solution to keep window below
187 XLowerWindow (server
.dsp
, window
.main_win
);
192 // drag and drop task
193 if (panel
.task_drag
) {
194 if (tskbar
!= panel
.task_drag
->area
.parent
&& action
== TOGGLE_ICONIFY
) {
195 if (!panel
.task_drag
->all_desktop
&& panel
.mode
== MULTI_DESKTOP
) {
196 windows_set_desktop(panel
.task_drag
->win
, tskbar
->desktop
);
197 if (tskbar
->desktop
== server
.desktop
)
198 set_active(panel
.task_drag
->win
);
203 else panel
.task_drag
= 0;
207 if (panel
.mode
== MULTI_DESKTOP
)
208 if (tskbar
->desktop
!= server
.desktop
&& action
!= CLOSE
)
209 set_desktop (tskbar
->desktop
);
214 for (l
= tskbar
->area
.list
; l
; l
= l
->next
) {
216 if (x
>= tsk
->area
.posx
&& x
<= (tsk
->area
.posx
+ tsk
->area
.width
)) {
217 window_action (tsk
, action
);
222 // to keep window below
223 XLowerWindow (server
.dsp
, window
.main_win
);
227 void event_property_notify (Window win
, Atom at
)
230 if (win
== server
.root_win
) {
231 if (!server
.got_root_win
) {
232 XSelectInput (server
.dsp
, server
.root_win
, PropertyChangeMask
|StructureNotifyMask
);
233 server
.got_root_win
= 1;
236 /* Change number of desktops */
237 else if (at
== server
.atom
._NET_NUMBER_OF_DESKTOPS
) {
242 else if (at
== server
.atom
._NET_CURRENT_DESKTOP
) {
243 server
.desktop
= server_get_current_desktop ();
244 if (panel
.mode
!= MULTI_DESKTOP
) {
249 else if (at
== server
.atom
._NET_CLIENT_LIST
) {
250 task_refresh_tasklist ();
254 else if (at
== server
.atom
._NET_ACTIVE_WINDOW
) {
255 if (panel
.task_active
) {
256 if (panel
.task_active
->all_desktop
) {
260 nb
= server
.nb_desktop
* server
.nb_monitor
;
261 for (i
=0 ; i
< nb
; i
++) {
262 for (l0
= panel
.taskbar
[i
].area
.list
; l0
; l0
= l0
->next
) {
264 tsk
->area
.is_active
= 0;
269 panel
.task_active
->area
.is_active
= 0;
270 panel
.task_active
= 0;
272 Window w1
= window_get_active ();
273 Task
*t
= task_get_task(w1
);
276 if (XGetTransientForHint(server
.dsp
, w1
, &w2
) != 0)
277 if (w2
) t
= task_get_task(w2
);
280 if (t
->all_desktop
) {
284 nb
= server
.nb_desktop
* server
.nb_monitor
;
285 for (i
=0 ; i
< nb
; i
++) {
286 for (l0
= panel
.taskbar
[i
].area
.list
; l0
; l0
= l0
->next
) {
288 if (tsk
->win
== t
->win
)
289 tsk
->area
.is_active
= 1;
294 t
->area
.is_active
= 1;
295 panel
.task_active
= t
;
299 /* Wallpaper changed */
300 else if (at
== server
.atom
._XROOTPMAP_ID
) {
301 set_panel_background();
307 tsk
= task_get_task (win
);
309 //printf("atom root_win = %s, %s\n", XGetAtomName(server.dsp, at), tsk->title);
311 /* Window title changed */
312 if (at
== server
.atom
._NET_WM_VISIBLE_NAME
|| at
== server
.atom
._NET_WM_NAME
|| at
== server
.atom
.WM_NAME
) {
313 if (tsk
->all_desktop
) {
317 nb
= server
.nb_desktop
* server
.nb_monitor
;
318 for (i
=0 ; i
< nb
; i
++) {
319 for (l0
= panel
.taskbar
[i
].area
.list
; l0
; l0
= l0
->next
) {
321 if (tsk
->win
== tsk2
->win
) {
323 tsk2
->area
.redraw
= 1;
330 tsk
->area
.redraw
= 1;
335 else if (at
== server
.atom
.WM_STATE
) {
336 if (window_is_iconified (win
))
337 if (panel
.task_active
) {
338 if (panel
.task_active
->win
== tsk
->win
) {
339 if (tsk
->all_desktop
) {
343 nb
= server
.nb_desktop
* server
.nb_monitor
;
344 for (i
=0 ; i
< nb
; i
++) {
345 for (l0
= panel
.taskbar
[i
].area
.list
; l0
; l0
= l0
->next
) {
347 tsk2
->area
.is_active
= 0;
352 panel
.task_active
->area
.is_active
= 0;
353 panel
.task_active
= 0;
357 /* Window icon changed */
358 else if (at
== server
.atom
._NET_WM_ICON
) {
359 if (tsk
->icon_data
) {
360 free (tsk
->icon_data
);
363 tsk
->area
.redraw
= 1;
366 /* Window desktop changed */
367 else if (at
== server
.atom
._NET_WM_DESKTOP
) {
373 if (!server
.got_root_win
) server
.root_win
= RootWindow (server
.dsp
, server
.screen
);
378 void event_configure_notify (Window win
)
380 if (panel
.mode
!= MULTI_MONITOR
) return;
382 Task
*tsk
= task_get_task (win
);
385 Taskbar
*tskbar
= tsk
->area
.parent
;
386 if (tskbar
->monitor
!= window_get_monitor (win
)) {
387 // task on another monitor
399 if (!time1_format
) return;
401 if (gettimeofday(&stv
, 0)) return;
403 if (abs(stv
.tv_sec
- time_clock
.tv_sec
) < time_precision
) return;
406 time_clock
.tv_sec
= stv
.tv_sec
;
407 time_clock
.tv_sec
-= time_clock
.tv_sec
% time_precision
;
408 panel
.clock
.area
.redraw
= 1;
413 int main (int argc
, char *argv
[])
420 c
= getopt (argc
, argv
, "c:");
424 // append full transparency background
425 list_back
= g_slist_append(0, calloc(1, sizeof(Area
)));
427 // read tint2rc config
430 i
= config_read_file (optarg
);
434 fprintf(stderr
, "usage: tint2 [-c] <config_file>\n");
440 window_draw_panel ();
442 // BUG: refresh(clock) is needed here, but 'on the paper' it's not necessary.
443 refresh(&panel
.clock
.area
);
445 x11_fd
= ConnectionNumber (server
.dsp
);
446 XSync (server
.dsp
, False
);
449 // thanks to AngryLlama for the timer
450 // Create a File Description Set containing x11_fd
452 FD_SET (x11_fd
, &fd
);
457 // Wait for X Event or a Timer
458 if (select(x11_fd
+1, &fd
, 0, 0, &tv
)) {
459 while (XPending (server
.dsp
)) {
460 XNextEvent(server
.dsp
, &e
);
464 if (e
.xbutton
.button
== 1) event_button_press (e
.xbutton
.x
, e
.xbutton
.y
);
468 event_button_release (e
.xbutton
.button
, e
.xbutton
.x
, e
.xbutton
.y
);
472 //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);
473 //XCopyArea (server.dsp, server.pmap, window.main_win, server.gc, panel.area.paddingxlr, 0, panel.area.width-(2*panel.area.paddingxlr), panel.area.height, 0, 0);
474 XCopyArea (server
.dsp
, server
.pmap
, window
.main_win
, server
.gc
, 0, 0, panel
.area
.width
, panel
.area
.height
, 0, 0);
478 //printf("PropertyNotify\n");
479 event_property_notify (e
.xproperty
.window
, e
.xproperty
.atom
);
482 case ConfigureNotify
:
483 if (e
.xconfigure
.window
== server
.root_win
)
486 event_configure_notify (e
.xconfigure
.window
);
493 switch (panel
.signal_pending
) {
502 if (panel
.refresh
&& !panel
.sleep_mode
) {
504 //printf(" *** visual_refresh\n");
This page took 0.054915 seconds and 4 git commands to generate.