Commit adb784a8 authored by Andreas.Fink85's avatar Andreas.Fink85

*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
parent 755d6672
......@@ -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);
}
......
......@@ -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) {
......
This diff is collapsed.
......@@ -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);
}
......
......@@ -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->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);
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,7 +797,8 @@ int main (int argc, char *argv[])
}
case LeaveNotify:
tooltip_trigger_hide();
if (g_tooltip.enabled)
tooltip_trigger_hide();
break;
case Expose:
......
......@@ -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)
{
timeout_list = g_slist_remove(timeout_list, t);
add_timeout_intern(value_msec, interval_msec, _callback, (struct timeout*)t);
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, 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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment