*add* autohide
*fix* issue 182 by using select instead of pselect git-svn-id: http://tint2.googlecode.com/svn/trunk@321 121b4492-b84c-0410-8b4c-0d4edfb3f3cc
This commit is contained in:
parent
755d6672fe
commit
adb784a859
18 changed files with 367 additions and 97 deletions
|
@ -100,4 +100,13 @@ mouse_right = close
|
|||
mouse_scroll_up = toggle
|
||||
mouse_scroll_down = iconify
|
||||
|
||||
#---------------------------------------------
|
||||
# AUTOHIDE OPTIONS
|
||||
#---------------------------------------------
|
||||
autohide = 0
|
||||
autohide_show_timeout = 0.3
|
||||
autohide_hide_timeout = 2
|
||||
autohide_height = 4
|
||||
strut_policy = minimum
|
||||
|
||||
|
||||
|
|
|
@ -127,3 +127,12 @@ mouse_right = close
|
|||
mouse_scroll_up = toggle
|
||||
mouse_scroll_down = iconify
|
||||
|
||||
#---------------------------------------------
|
||||
# AUTOHIDE OPTIONS
|
||||
#---------------------------------------------
|
||||
autohide = 0
|
||||
autohide_show_timeout = 0.3
|
||||
autohide_hide_timeout = 2
|
||||
autohide_height = 4
|
||||
strut_policy = minimum
|
||||
|
||||
|
|
|
@ -125,3 +125,12 @@ mouse_right = close
|
|||
mouse_scroll_up = toggle
|
||||
mouse_scroll_down = iconify
|
||||
|
||||
#---------------------------------------------
|
||||
# AUTOHIDE OPTIONS
|
||||
#---------------------------------------------
|
||||
autohide = 0
|
||||
autohide_show_timeout = 0.3
|
||||
autohide_hide_timeout = 2
|
||||
autohide_height = 4
|
||||
strut_policy = minimum
|
||||
|
||||
|
|
|
@ -105,3 +105,12 @@ mouse_right = close
|
|||
mouse_scroll_up = toggle
|
||||
mouse_scroll_down = iconify
|
||||
|
||||
#---------------------------------------------
|
||||
# AUTOHIDE OPTIONS
|
||||
#---------------------------------------------
|
||||
autohide = 0
|
||||
autohide_show_timeout = 0.3
|
||||
autohide_hide_timeout = 2
|
||||
autohide_height = 4
|
||||
strut_policy = minimum
|
||||
|
||||
|
|
|
@ -115,3 +115,12 @@ mouse_right = close
|
|||
mouse_scroll_up = toggle
|
||||
mouse_scroll_down = iconify
|
||||
|
||||
#---------------------------------------------
|
||||
# AUTOHIDE OPTIONS
|
||||
#---------------------------------------------
|
||||
autohide = 0
|
||||
autohide_show_timeout = 0.3
|
||||
autohide_hide_timeout = 2
|
||||
autohide_height = 4
|
||||
strut_policy = minimum
|
||||
|
||||
|
|
|
@ -114,3 +114,13 @@ mouse_middle = none
|
|||
mouse_right = close
|
||||
mouse_scroll_up = toggle
|
||||
mouse_scroll_down = iconify
|
||||
|
||||
#---------------------------------------------
|
||||
# AUTOHIDE OPTIONS
|
||||
#---------------------------------------------
|
||||
autohide = 0
|
||||
autohide_show_timeout = 0.3
|
||||
autohide_hide_timeout = 2
|
||||
autohide_height = 4
|
||||
strut_policy = minimum
|
||||
|
||||
|
|
|
@ -122,3 +122,12 @@ mouse_right = close
|
|||
mouse_scroll_up = toggle
|
||||
mouse_scroll_down = iconify
|
||||
|
||||
#---------------------------------------------
|
||||
# AUTOHIDE OPTIONS
|
||||
#---------------------------------------------
|
||||
autohide = 0
|
||||
autohide_show_timeout = 0.3
|
||||
autohide_hide_timeout = 2
|
||||
autohide_height = 4
|
||||
strut_policy = minimum
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ char *path_energy_full=0;
|
|||
char *path_current_now=0;
|
||||
char *path_status=0;
|
||||
|
||||
void update_batterys()
|
||||
void update_batterys(void* arg)
|
||||
{
|
||||
int i;
|
||||
update_battery();
|
||||
|
@ -133,7 +133,7 @@ void init_battery()
|
|||
g_free(battery_dir);
|
||||
|
||||
if (battery_enabled && battery_timeout==0)
|
||||
battery_timeout = add_timeout(10, 5000, update_batterys);
|
||||
battery_timeout = add_timeout(10, 5000, update_batterys, 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ int clock_enabled;
|
|||
static const struct timeout* clock_timeout=0;
|
||||
|
||||
|
||||
void update_clocks()
|
||||
void update_clocks(void* arg)
|
||||
{
|
||||
gettimeofday(&time_clock, 0);
|
||||
int i;
|
||||
|
@ -87,9 +87,9 @@ void init_clock()
|
|||
{
|
||||
if(time1_format && clock_timeout==0) {
|
||||
if (strchr(time1_format, 'S') || strchr(time1_format, 'T') || strchr(time1_format, 'r'))
|
||||
clock_timeout = add_timeout(10, 1000, update_clocks);
|
||||
clock_timeout = add_timeout(10, 1000, update_clocks, 0);
|
||||
else
|
||||
clock_timeout = add_timeout(10, 60000, update_clocks);
|
||||
clock_timeout = add_timeout(10, 60000, update_clocks, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,9 +282,9 @@ void clock_action(int button)
|
|||
pid = fork();
|
||||
if (pid == 0) {
|
||||
// change for the fork the signal mask
|
||||
sigset_t sigset;
|
||||
sigprocmask(SIG_SETMASK, &sigset, 0);
|
||||
sigprocmask(SIG_UNBLOCK, &sigset, 0);
|
||||
// sigset_t sigset;
|
||||
// sigprocmask(SIG_SETMASK, &sigset, 0);
|
||||
// sigprocmask(SIG_UNBLOCK, &sigset, 0);
|
||||
execl("/bin/sh", "/bin/sh", "-c", command, NULL);
|
||||
_exit(0);
|
||||
}
|
||||
|
|
16
src/config.c
16
src/config.c
|
@ -607,6 +607,22 @@ void add_entry (char *key, char *value)
|
|||
else if (strcmp (key, "mouse_scroll_down") == 0)
|
||||
get_action (value, &mouse_scroll_down);
|
||||
|
||||
/* autohide options */
|
||||
else if (strcmp(key, "autohide") == 0)
|
||||
panel_autohide = atoi(value);
|
||||
else if (strcmp(key, "autohide_show_timeout") == 0)
|
||||
panel_autohide_show_timeout = 1000*atof(value);
|
||||
else if (strcmp(key, "autohide_hide_timeout") == 0)
|
||||
panel_autohide_hide_timeout = 1000*atof(value);
|
||||
else if (strcmp(key, "strut_policy") == 0) {
|
||||
if (strcmp(value, "follow_size") == 0)
|
||||
panel_strut_policy = STRUT_FOLLOW_SIZE;
|
||||
else
|
||||
panel_strut_policy = STRUT_MINIMUM;
|
||||
}
|
||||
else if (strcmp(key, "autohide_height") == 0)
|
||||
panel_autohide_height = atoi(value);
|
||||
|
||||
|
||||
/* Read tint-0.6 config for backward compatibility */
|
||||
else if (strcmp (key, "panel_mode") == 0) {
|
||||
|
|
229
src/panel.c
229
src/panel.c
|
@ -51,6 +51,12 @@ int panel_position;
|
|||
int panel_horizontal;
|
||||
int panel_refresh;
|
||||
|
||||
int panel_autohide = 0;
|
||||
int panel_autohide_show_timeout = 0;
|
||||
int panel_autohide_hide_timeout = 0;
|
||||
int panel_autohide_height = 5; // for vertical panels this is of course the width
|
||||
int panel_strut_policy = STRUT_MINIMUM;
|
||||
|
||||
Task *task_active;
|
||||
Task *task_drag;
|
||||
int max_tick_urgent;
|
||||
|
@ -64,6 +70,9 @@ int nb_panel = 0;
|
|||
Imlib_Image default_icon = NULL;
|
||||
|
||||
|
||||
void autohide_hide(void* p);
|
||||
void autohide_show(void* p);
|
||||
|
||||
|
||||
void init_panel()
|
||||
{
|
||||
|
@ -152,6 +161,8 @@ void init_panel()
|
|||
long event_mask = ExposureMask|ButtonPressMask|ButtonReleaseMask;
|
||||
if (g_tooltip.enabled)
|
||||
event_mask |= PointerMotionMask|LeaveWindowMask;
|
||||
if (panel_autohide)
|
||||
event_mask |= LeaveWindowMask|EnterWindowMask;
|
||||
XSetWindowAttributes att = { .event_mask=event_mask, .colormap=server.colormap, .background_pixel=0, .border_pixel=0 };
|
||||
unsigned long mask = CWEventMask|CWColormap|CWBackPixel|CWBorderPixel;
|
||||
p->main_win = XCreateWindow(server.dsp, server.root_win, p->posx, p->posy, p->area.width, p->area.height, 0, server.depth, InputOutput, server.visual, mask, &att);
|
||||
|
@ -172,6 +183,9 @@ void init_panel()
|
|||
// map new panel
|
||||
XMapWindow (server.dsp, p->main_win);
|
||||
}
|
||||
|
||||
if (panel_autohide)
|
||||
add_timeout(panel_autohide_hide_timeout, 0, autohide_hide, p);
|
||||
}
|
||||
|
||||
panel1 = new_panel;
|
||||
|
@ -234,6 +248,18 @@ void init_panel_size_and_position(Panel *panel)
|
|||
panel->posy = server.monitor[panel->monitor].y + ((server.monitor[panel->monitor].height - panel->area.height) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (panel_autohide) {
|
||||
int diff = (panel_horizontal ? panel->area.height : panel->area.width) - panel_autohide_height;
|
||||
if (panel_horizontal) {
|
||||
panel->hidden_width = panel->area.width;
|
||||
panel->hidden_height = panel->area.height - diff;
|
||||
}
|
||||
else {
|
||||
panel->hidden_width = panel->area.width - diff;
|
||||
panel->hidden_height = panel->area.height;
|
||||
}
|
||||
}
|
||||
// printf("panel : posx %d, posy %d, width %d, height %d\n", panel->posx, panel->posy, panel->area.width, panel->area.height);
|
||||
}
|
||||
|
||||
|
@ -258,6 +284,9 @@ void cleanup_panel()
|
|||
XFreePixmap(server.dsp, p->temp_pmap);
|
||||
p->temp_pmap = 0;
|
||||
}
|
||||
if (p->hidden_pixmap)
|
||||
XFreePixmap(server.dsp, p->hidden_pixmap);
|
||||
p->hidden_pixmap = 0;
|
||||
if (p->main_win) {
|
||||
XDestroyWindow(server.dsp, p->main_win);
|
||||
p->main_win = 0;
|
||||
|
@ -378,6 +407,54 @@ void visible_object()
|
|||
panel_refresh = 1;
|
||||
}
|
||||
|
||||
void update_strut(Panel* p)
|
||||
{
|
||||
// Reserved space
|
||||
unsigned int d1, screen_width, screen_height;
|
||||
Window d2;
|
||||
int d3;
|
||||
XGetGeometry(server.dsp, server.root_win, &d2, &d3, &d3, &screen_width, &screen_height, &d1, &d1);
|
||||
Monitor monitor = server.monitor[p->monitor];
|
||||
long struts [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
if (panel_horizontal) {
|
||||
int height = p->area.height + p->marginy;
|
||||
if (panel_autohide && (panel_strut_policy == STRUT_MINIMUM || (panel_strut_policy == STRUT_FOLLOW_SIZE && p->is_hidden)) )
|
||||
height = p->hidden_height;
|
||||
if (panel_position & TOP) {
|
||||
struts[2] = height + monitor.y;
|
||||
struts[8] = p->posx;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[9] = p->posx + p->area.width - 1;
|
||||
}
|
||||
else {
|
||||
struts[3] = height + screen_height - monitor.y - monitor.height;
|
||||
struts[10] = p->posx;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[11] = p->posx + p->area.width - 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int width = p->area.width + p->marginx;
|
||||
if (panel_autohide && (panel_strut_policy == STRUT_MINIMUM || (panel_strut_policy == STRUT_FOLLOW_SIZE && p->is_hidden)) )
|
||||
width = p->hidden_width;
|
||||
if (panel_position & LEFT) {
|
||||
struts[0] = width + monitor.x;
|
||||
struts[4] = p->posy;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[5] = p->posy + p->area.height - 1;
|
||||
}
|
||||
else {
|
||||
struts[1] = width + screen_width - monitor.x - monitor.width;
|
||||
struts[6] = p->posy;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[7] = p->posy + p->area.height - 1;
|
||||
}
|
||||
}
|
||||
// Old specification : fluxbox need _NET_WM_STRUT.
|
||||
XChangeProperty (server.dsp, p->main_win, server.atom._NET_WM_STRUT, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 4);
|
||||
XChangeProperty (server.dsp, p->main_win, server.atom._NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 12);
|
||||
}
|
||||
|
||||
|
||||
void set_panel_properties(Panel *p)
|
||||
{
|
||||
|
@ -402,7 +479,8 @@ void set_panel_properties(Panel *p)
|
|||
state[1] = server.atom._NET_WM_STATE_SKIP_TASKBAR;
|
||||
state[2] = server.atom._NET_WM_STATE_STICKY;
|
||||
state[3] = panel_layer == BOTTOM_LAYER ? server.atom._NET_WM_STATE_BELOW : server.atom._NET_WM_STATE_ABOVE;
|
||||
XChangeProperty (server.dsp, p->main_win, server.atom._NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *) state, panel_layer == NORMAL_LAYER ? 3 : 4);
|
||||
int nb_atoms = panel_layer == NORMAL_LAYER ? 3 : 4;
|
||||
XChangeProperty (server.dsp, p->main_win, server.atom._NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *) state, nb_atoms);
|
||||
|
||||
// Unfocusable
|
||||
XWMHints wmhints;
|
||||
|
@ -425,51 +503,18 @@ void set_panel_properties(Panel *p)
|
|||
int version=5;
|
||||
XChangeProperty(server.dsp, p->main_win, server.atom.XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&version, 1);
|
||||
|
||||
// Reserved space
|
||||
unsigned int d1, screen_width, screen_height;
|
||||
Window d2;
|
||||
int d3;
|
||||
XGetGeometry(server.dsp, server.root_win, &d2, &d3, &d3, &screen_width, &screen_height, &d1, &d1);
|
||||
Monitor monitor = server.monitor[p->monitor];
|
||||
long struts [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
if (panel_horizontal) {
|
||||
if (panel_position & TOP) {
|
||||
struts[2] = p->area.height + p->marginy + monitor.y;
|
||||
struts[8] = p->posx;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[9] = p->posx + p->area.width - 1;
|
||||
}
|
||||
else {
|
||||
struts[3] = p->area.height + p->marginy + screen_height - monitor.y - monitor.height;
|
||||
struts[10] = p->posx;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[11] = p->posx + p->area.width - 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (panel_position & LEFT) {
|
||||
struts[0] = p->area.width + p->marginx + monitor.x;
|
||||
struts[4] = p->posy;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[5] = p->posy + p->area.height - 1;
|
||||
}
|
||||
else {
|
||||
struts[1] = p->area.width + p->marginx + screen_width - monitor.x - monitor.width;
|
||||
struts[6] = p->posy;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[7] = p->posy + p->area.height - 1;
|
||||
}
|
||||
}
|
||||
// Old specification : fluxbox need _NET_WM_STRUT.
|
||||
XChangeProperty (server.dsp, p->main_win, server.atom._NET_WM_STRUT, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 4);
|
||||
XChangeProperty (server.dsp, p->main_win, server.atom._NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 12);
|
||||
update_strut(p);
|
||||
|
||||
// Fixed position and non-resizable window
|
||||
// Allow panel move and resize when tint2 reload config file
|
||||
int minwidth = panel_autohide ? p->hidden_width : p->area.width;
|
||||
int minheight = panel_autohide ? p->hidden_height : p->area.height;
|
||||
XSizeHints size_hints;
|
||||
size_hints.flags = PPosition|PMinSize|PMaxSize;
|
||||
size_hints.min_width = size_hints.max_width = p->area.width;
|
||||
size_hints.min_height = size_hints.max_height = p->area.height;
|
||||
size_hints.min_width = minwidth;
|
||||
size_hints.max_width = p->area.width;
|
||||
size_hints.min_height = minheight;
|
||||
size_hints.max_height = p->area.height;
|
||||
XSetWMNormalHints(server.dsp, p->main_win, &size_hints);
|
||||
|
||||
// Set WM_CLASS
|
||||
|
@ -504,12 +549,21 @@ void set_panel_background(Panel *p)
|
|||
cairo_t *c;
|
||||
cs = cairo_xlib_surface_create (server.dsp, p->area.pix.pmap, server.visual, p->area.width, p->area.height);
|
||||
c = cairo_create (cs);
|
||||
|
||||
draw_background(&p->area, c, 0);
|
||||
|
||||
cairo_destroy (c);
|
||||
cairo_surface_destroy (cs);
|
||||
|
||||
if (panel_autohide) {
|
||||
if (p->hidden_pixmap) XFreePixmap(server.dsp, p->hidden_pixmap);
|
||||
p->hidden_pixmap = XCreatePixmap(server.dsp, server.root_win, p->hidden_width, p->hidden_height, server.depth);
|
||||
int xoff=0, yoff=0;
|
||||
if (panel_horizontal && panel_position & BOTTOM)
|
||||
yoff = p->area.height-p->hidden_height;
|
||||
else if (!panel_horizontal && panel_position & RIGHT)
|
||||
xoff = p->area.width-p->hidden_width;
|
||||
XCopyArea(server.dsp, p->area.pix.pmap, p->hidden_pixmap, server.gc, xoff, yoff, p->hidden_width, p->hidden_height, 0, 0);
|
||||
}
|
||||
|
||||
// redraw panel's object
|
||||
GSList *l0;
|
||||
Area *a;
|
||||
|
@ -637,3 +691,92 @@ Area* click_area(Panel *panel, int x, int y)
|
|||
} while (new_result != result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void stop_autohide_timeout(Panel* p)
|
||||
{
|
||||
if (p->autohide_timeout) {
|
||||
stop_timeout(p->autohide_timeout);
|
||||
p->autohide_timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void autohide_show(void* p)
|
||||
{
|
||||
Panel* panel = p;
|
||||
stop_autohide_timeout(panel);
|
||||
panel->is_hidden = 0;
|
||||
if (panel_strut_policy == STRUT_FOLLOW_SIZE)
|
||||
update_strut(p);
|
||||
|
||||
XMapSubwindows(server.dsp, panel->main_win);
|
||||
if (panel_horizontal) {
|
||||
if (panel_position & TOP)
|
||||
XResizeWindow(server.dsp, panel->main_win, panel->area.width, panel->area.height);
|
||||
else
|
||||
XMoveResizeWindow(server.dsp, panel->main_win, panel->posx, panel->posy, panel->area.width, panel->area.height);
|
||||
}
|
||||
else {
|
||||
if (panel_position & LEFT)
|
||||
XResizeWindow(server.dsp, panel->main_win, panel->area.width, panel->area.height);
|
||||
else
|
||||
XMoveResizeWindow(server.dsp, panel->main_win, panel->posx, panel->posy, panel->area.width, panel->area.height);
|
||||
}
|
||||
panel_refresh = 1;
|
||||
}
|
||||
|
||||
|
||||
void autohide_hide(void* p)
|
||||
{
|
||||
Panel* panel = p;
|
||||
stop_autohide_timeout(panel);
|
||||
panel->is_hidden = 1;
|
||||
if (panel_strut_policy == STRUT_FOLLOW_SIZE)
|
||||
update_strut(p);
|
||||
|
||||
XUnmapSubwindows(server.dsp, panel->main_win);
|
||||
int diff = (panel_horizontal ? panel->area.height : panel->area.width) - panel_autohide_height;
|
||||
if (panel_horizontal) {
|
||||
if (panel_position & TOP)
|
||||
XResizeWindow(server.dsp, panel->main_win, panel->hidden_width, panel->hidden_height);
|
||||
else
|
||||
XMoveResizeWindow(server.dsp, panel->main_win, panel->posx, panel->posy+diff, panel->hidden_width, panel->hidden_height);
|
||||
}
|
||||
else {
|
||||
if (panel_position & LEFT)
|
||||
XResizeWindow(server.dsp, panel->main_win, panel->hidden_width, panel->hidden_height);
|
||||
else
|
||||
XMoveResizeWindow(server.dsp, panel->main_win, panel->posx+diff, panel->posy, panel->hidden_width, panel->hidden_height);
|
||||
}
|
||||
panel_refresh = 1;
|
||||
}
|
||||
|
||||
|
||||
void autohide_trigger_show(Panel* p)
|
||||
{
|
||||
if (!p)
|
||||
return;
|
||||
if (p->autohide_timeout)
|
||||
change_timeout(p->autohide_timeout, panel_autohide_show_timeout, 0, autohide_show, p);
|
||||
else
|
||||
p->autohide_timeout = add_timeout(panel_autohide_show_timeout, 0, autohide_show, p);
|
||||
}
|
||||
|
||||
|
||||
void autohide_trigger_hide(Panel* p)
|
||||
{
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
Window root, child;
|
||||
int xr, yr, xw, yw;
|
||||
unsigned int mask;
|
||||
if (XQueryPointer(server.dsp, p->main_win, &root, &child, &xr, &yr, &xw, &yw, &mask))
|
||||
if (child) return; // mouse over one of the system tray icons
|
||||
|
||||
if (p->autohide_timeout)
|
||||
change_timeout(p->autohide_timeout, panel_autohide_hide_timeout, 0, autohide_hide, p);
|
||||
else
|
||||
p->autohide_timeout = add_timeout(panel_autohide_hide_timeout, 0, autohide_hide, p);
|
||||
}
|
||||
|
|
15
src/panel.h
15
src/panel.h
|
@ -50,6 +50,14 @@ extern int panel_horizontal;
|
|||
|
||||
extern int panel_refresh;
|
||||
|
||||
//panel autohide
|
||||
enum { STRUT_MINIMUM, STRUT_FOLLOW_SIZE };
|
||||
extern int panel_autohide;
|
||||
extern int panel_autohide_show_timeout;
|
||||
extern int panel_autohide_hide_timeout;
|
||||
extern int panel_autohide_height; // for vertical panels this is of course the width
|
||||
extern int panel_strut_policy;
|
||||
|
||||
extern Task *task_active;
|
||||
extern Task *task_drag;
|
||||
extern int max_tick_urgent;
|
||||
|
@ -97,6 +105,10 @@ typedef struct {
|
|||
#ifdef ENABLE_BATTERY
|
||||
Battery battery;
|
||||
#endif
|
||||
int is_hidden;
|
||||
int hidden_width, hidden_height;
|
||||
Pixmap hidden_pixmap;
|
||||
const struct timeout* autohide_timeout;
|
||||
} Panel;
|
||||
|
||||
|
||||
|
@ -127,4 +139,7 @@ int click_padding(Panel *panel, int x, int y);
|
|||
int click_clock(Panel *panel, int x, int y);
|
||||
Area* click_area(Panel *panel, int x, int y);
|
||||
|
||||
void autohide_trigger_show();
|
||||
void autohide_trigger_hide();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -469,7 +469,7 @@ void active_task()
|
|||
}
|
||||
|
||||
|
||||
void blink_urgent()
|
||||
void blink_urgent(void* arg)
|
||||
{
|
||||
GSList* urgent_task = urgent_list;
|
||||
while (urgent_task) {
|
||||
|
@ -510,7 +510,7 @@ void add_urgent(Task *tsk)
|
|||
urgent_list = g_slist_concat(urgent_add, urgent_list);
|
||||
|
||||
if (urgent_timeout == 0)
|
||||
urgent_timeout = add_timeout(10, 1000, blink_urgent);
|
||||
urgent_timeout = add_timeout(10, 1000, blink_urgent, 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
46
src/tint.c
46
src/tint.c
|
@ -80,13 +80,16 @@ void init (int argc, char *argv[])
|
|||
sigaction(SIGTERM, &sa, 0);
|
||||
sigaction(SIGHUP, &sa, 0);
|
||||
signal(SIGCHLD, SIG_IGN); // don't have to wait() after fork()
|
||||
|
||||
// BSD is too stupid to support pselect(), therefore we have to use select and hope that we do not
|
||||
// end up in a race condition there
|
||||
// block all signals, such that no race conditions occur before pselect in our main loop
|
||||
sigset_t block_mask;
|
||||
sigaddset(&block_mask, SIGINT);
|
||||
sigaddset(&block_mask, SIGTERM);
|
||||
sigaddset(&block_mask, SIGHUP);
|
||||
sigaddset(&block_mask, SIGUSR1);
|
||||
sigprocmask(SIG_BLOCK, &block_mask, 0);
|
||||
// sigset_t block_mask;
|
||||
// sigaddset(&block_mask, SIGINT);
|
||||
// sigaddset(&block_mask, SIGTERM);
|
||||
// sigaddset(&block_mask, SIGHUP);
|
||||
// sigaddset(&block_mask, SIGUSR1);
|
||||
// sigprocmask(SIG_BLOCK, &block_mask, 0);
|
||||
|
||||
// set global data
|
||||
memset(&server, 0, sizeof(Server_global));
|
||||
|
@ -681,7 +684,7 @@ int main (int argc, char *argv[])
|
|||
int x11_fd, i;
|
||||
Panel *panel;
|
||||
GSList *it;
|
||||
const struct timespec* timeout;
|
||||
struct timeval* timeout;
|
||||
|
||||
init (argc, argv);
|
||||
init_config();
|
||||
|
@ -710,8 +713,8 @@ int main (int argc, char *argv[])
|
|||
x11_fd = ConnectionNumber(server.dsp);
|
||||
XSync(server.dsp, False);
|
||||
|
||||
sigset_t empty_mask;
|
||||
sigemptyset(&empty_mask);
|
||||
// sigset_t empty_mask;
|
||||
// sigemptyset(&empty_mask);
|
||||
|
||||
while (1) {
|
||||
if (panel_refresh) {
|
||||
|
@ -725,15 +728,19 @@ int main (int argc, char *argv[])
|
|||
for (i=0 ; i < nb_panel ; i++) {
|
||||
panel = &panel1[i];
|
||||
|
||||
if (panel->is_hidden)
|
||||
XCopyArea(server.dsp, panel->hidden_pixmap, panel->main_win, server.gc, 0, 0, panel->hidden_width, panel->hidden_height, 0, 0);
|
||||
else {
|
||||
if (panel->temp_pmap) XFreePixmap(server.dsp, panel->temp_pmap);
|
||||
panel->temp_pmap = XCreatePixmap(server.dsp, server.root_win, panel->area.width, panel->area.height, server.depth);
|
||||
|
||||
refresh(&panel->area);
|
||||
XCopyArea(server.dsp, panel->temp_pmap, panel->main_win, server.gc, 0, 0, panel->area.width, panel->area.height, 0, 0);
|
||||
}
|
||||
}
|
||||
XFlush (server.dsp);
|
||||
|
||||
if (refresh_systray) {
|
||||
panel = (Panel*)systray.area.panel;
|
||||
if (refresh_systray && !panel->is_hidden) {
|
||||
refresh_systray = 0;
|
||||
panel = (Panel*)systray.area.panel;
|
||||
// tint2 doen't draw systray icons. it just redraw background.
|
||||
|
@ -748,19 +755,29 @@ int main (int argc, char *argv[])
|
|||
FD_ZERO (&fdset);
|
||||
FD_SET (x11_fd, &fdset);
|
||||
update_next_timeout();
|
||||
if (next_timeout.tv_sec >= 0 && next_timeout.tv_nsec >= 0)
|
||||
if (next_timeout.tv_sec >= 0 && next_timeout.tv_usec >= 0)
|
||||
timeout = &next_timeout;
|
||||
else
|
||||
timeout = 0;
|
||||
|
||||
// Wait for X Event or a Timer
|
||||
if (pselect(x11_fd+1, &fdset, 0, 0, timeout, &empty_mask) > 0) {
|
||||
if (select(x11_fd+1, &fdset, 0, 0, timeout) > 0) {
|
||||
while (XPending (server.dsp)) {
|
||||
XNextEvent(server.dsp, &e);
|
||||
|
||||
panel = get_panel(e.xany.window);
|
||||
if (panel && panel_autohide) {
|
||||
if (e.type == EnterNotify)
|
||||
autohide_trigger_show(panel);
|
||||
else if (e.type == LeaveNotify)
|
||||
autohide_trigger_hide(panel);
|
||||
if (panel->is_hidden)
|
||||
continue; // discard further processing of this event because the panel is not visible yet
|
||||
}
|
||||
|
||||
switch (e.type) {
|
||||
case ButtonPress:
|
||||
tooltip_hide();
|
||||
tooltip_hide(0);
|
||||
event_button_press (&e);
|
||||
break;
|
||||
|
||||
|
@ -780,6 +797,7 @@ int main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
case LeaveNotify:
|
||||
if (g_tooltip.enabled)
|
||||
tooltip_trigger_hide();
|
||||
break;
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ void init_tooltip()
|
|||
void cleanup_tooltip()
|
||||
{
|
||||
stop_tooltip_timeout();
|
||||
tooltip_hide();
|
||||
tooltip_hide(0);
|
||||
g_tooltip.enabled = False;
|
||||
tooltip_copy_text(0);
|
||||
if (g_tooltip.window) {
|
||||
|
@ -104,7 +104,7 @@ void tooltip_trigger_show(Area* area, Panel* p, int x_root, int y_root)
|
|||
}
|
||||
|
||||
|
||||
void tooltip_show()
|
||||
void tooltip_show(void* arg)
|
||||
{
|
||||
int mx, my;
|
||||
Window w;
|
||||
|
@ -200,7 +200,7 @@ void tooltip_adjust_geometry()
|
|||
void tooltip_update()
|
||||
{
|
||||
if (!g_tooltip.tooltip_text) {
|
||||
tooltip_hide();
|
||||
tooltip_hide(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,7 @@ void tooltip_trigger_hide(Tooltip* tooltip)
|
|||
}
|
||||
|
||||
|
||||
void tooltip_hide()
|
||||
void tooltip_hide(void* arg)
|
||||
{
|
||||
stop_tooltip_timeout();
|
||||
if (g_tooltip.mapped) {
|
||||
|
@ -279,18 +279,18 @@ void tooltip_hide()
|
|||
void start_show_timeout()
|
||||
{
|
||||
if (g_tooltip.timeout)
|
||||
change_timeout(g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show);
|
||||
change_timeout(g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
|
||||
else
|
||||
g_tooltip.timeout = add_timeout(g_tooltip.show_timeout_msec, 0, tooltip_show);
|
||||
g_tooltip.timeout = add_timeout(g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
|
||||
}
|
||||
|
||||
|
||||
void start_hide_timeout()
|
||||
{
|
||||
if (g_tooltip.timeout)
|
||||
change_timeout(g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide);
|
||||
change_timeout(g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
|
||||
else
|
||||
g_tooltip.timeout = add_timeout(g_tooltip.hide_timeout_msec, 0, tooltip_hide);
|
||||
g_tooltip.timeout = add_timeout(g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -46,9 +46,9 @@ extern Tooltip g_tooltip;
|
|||
void init_tooltip();
|
||||
void cleanup_tooltip();
|
||||
void tooltip_trigger_show(Area* area, Panel* p, int x, int y);
|
||||
void tooltip_show();
|
||||
void tooltip_show(void* /*arg*/);
|
||||
void tooltip_update();
|
||||
void tooltip_trigger_hide();
|
||||
void tooltip_hide();
|
||||
void tooltip_hide(void* /*arg*/);
|
||||
|
||||
#endif // TOOLTIP_H
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
#include "timer.h"
|
||||
|
||||
GSList* timeout_list = 0;
|
||||
struct timespec next_timeout;
|
||||
struct timeval next_timeout;
|
||||
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), struct timeout* t);
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(void*), void* arg, struct timeout* t);
|
||||
gint compare_timeouts(gconstpointer t1, gconstpointer t2);
|
||||
gint compare_timespecs(const struct timespec* t1, const struct timespec* t2);
|
||||
int timespec_subtract(struct timespec* result, struct timespec* x, struct timespec* y);
|
||||
|
@ -36,20 +36,27 @@ int timespec_subtract(struct timespec* result, struct timespec* x, struct timesp
|
|||
* is in the past to the current time.
|
||||
* As time measurement we use clock_gettime(CLOCK_MONOTONIC) because this refers to a timer, which
|
||||
* reference point lies somewhere in the past and cannot be changed, but just queried.
|
||||
* If a single shot timer is installed it will be automatically deleted. I.e. the returned value
|
||||
* of add_timeout will not be valid anymore. You do not need to call stop_timeout for these timeouts,
|
||||
* however it's save to call it.
|
||||
**/
|
||||
|
||||
const struct timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)())
|
||||
const struct timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg)
|
||||
{
|
||||
struct timeout* t = malloc(sizeof(struct timeout));
|
||||
add_timeout_intern(value_msec, interval_msec, _callback, t);
|
||||
add_timeout_intern(value_msec, interval_msec, _callback, arg, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
void change_timeout(const struct timeout *t, int value_msec, int interval_msec, void(*_callback)())
|
||||
void change_timeout(const struct timeout *t, int value_msec, int interval_msec, void(*_callback)(), void* arg)
|
||||
{
|
||||
if ( g_slist_find(timeout_list, t) == 0 )
|
||||
printf("timeout already deleted...");
|
||||
else {
|
||||
timeout_list = g_slist_remove(timeout_list, t);
|
||||
add_timeout_intern(value_msec, interval_msec, _callback, (struct timeout*)t);
|
||||
add_timeout_intern(value_msec, interval_msec, _callback, arg, (struct timeout*)t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,10 +65,15 @@ void update_next_timeout()
|
|||
if (timeout_list) {
|
||||
struct timeout* t = timeout_list->data;
|
||||
struct timespec cur_time;
|
||||
struct timespec next_timeout2 = { .tv_sec=next_timeout.tv_sec, .tv_nsec=next_timeout.tv_usec*1000 };
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
if (timespec_subtract(&next_timeout, &t->timeout_expires, &cur_time)) {
|
||||
if (timespec_subtract(&next_timeout2, &t->timeout_expires, &cur_time)) {
|
||||
next_timeout.tv_sec = 0;
|
||||
next_timeout.tv_nsec = 0;
|
||||
next_timeout.tv_usec = 0;
|
||||
}
|
||||
else {
|
||||
next_timeout.tv_sec = next_timeout2.tv_sec;
|
||||
next_timeout.tv_usec = next_timeout2.tv_nsec/1000;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -78,12 +90,12 @@ void callback_timeout_expired()
|
|||
t = timeout_list->data;
|
||||
if (compare_timespecs(&t->timeout_expires, &cur_time) <= 0) {
|
||||
// it's time for the callback function
|
||||
t->_callback();
|
||||
t->_callback(t->arg);
|
||||
if (g_slist_find(timeout_list, t)) {
|
||||
// if _callback() calls stop_timeout(t) the timeout 't' was freed and is not in the timeout_list
|
||||
timeout_list = g_slist_remove(timeout_list, t);
|
||||
if (t->interval_msec > 0)
|
||||
add_timeout_intern(t->interval_msec, t->interval_msec, t->_callback, t);
|
||||
add_timeout_intern(t->interval_msec, t->interval_msec, t->_callback, t->arg, t);
|
||||
else
|
||||
free(t);
|
||||
}
|
||||
|
@ -113,10 +125,11 @@ void stop_all_timeouts()
|
|||
}
|
||||
|
||||
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), struct timeout *t)
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), void* arg, struct timeout *t)
|
||||
{
|
||||
t->interval_msec = interval_msec;
|
||||
t->_callback = _callback;
|
||||
t->arg = arg;
|
||||
struct timespec expire;
|
||||
clock_gettime(CLOCK_MONOTONIC, &expire);
|
||||
expire.tv_sec += value_msec / 1000;
|
||||
|
|
|
@ -22,13 +22,14 @@
|
|||
#include <glib.h>
|
||||
|
||||
extern GSList* timeout_list;
|
||||
extern struct timespec next_timeout;
|
||||
extern struct timeval next_timeout;
|
||||
|
||||
|
||||
struct timeout {
|
||||
int interval_msec;
|
||||
struct timespec timeout_expires;
|
||||
void (*_callback)();
|
||||
void* arg;
|
||||
};
|
||||
|
||||
|
||||
|
@ -36,9 +37,9 @@ struct timeout {
|
|||
/** installs a timeout with the first timeout of 'value_msec' and then a periodic timeout with
|
||||
* 'interval_msec'. '_callback' is the callback function when the timer reaches the timeout.
|
||||
* returns a pointer to the timeout, which is needed for stopping it again **/
|
||||
const struct timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)());
|
||||
const struct timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
|
||||
|
||||
void change_timeout(const struct timeout* t, int value_msec, int interval_msec, void (*_callback)());
|
||||
void change_timeout(const struct timeout* t, int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
|
||||
|
||||
/** stops the timeout 't' **/
|
||||
void stop_timeout(const struct timeout* t);
|
||||
|
|
Loading…
Reference in a new issue