Compare commits
12 Commits
v0.12.12
...
BenoitAver
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
187e7f294e | ||
|
|
8976f35c5f | ||
|
|
008eebe4b1 | ||
|
|
cbb76849ea | ||
|
|
cf930fa42e | ||
|
|
da51d37322 | ||
|
|
a09e1a0e45 | ||
|
|
1d4f64d745 | ||
|
|
2857b96c4d | ||
|
|
8b08930268 | ||
|
|
2922708c18 | ||
|
|
5c6385b4c3 |
@@ -1,3 +1,7 @@
|
|||||||
|
2016-08-07 master
|
||||||
|
- Enhancements:
|
||||||
|
- Desktop files (shortcuts) used in launcher are reloaded on click, in case the file has changed
|
||||||
|
|
||||||
2016-08-02 0.12.12
|
2016-08-02 0.12.12
|
||||||
- Fixes:
|
- Fixes:
|
||||||
- Set task maximum height equal to width if not specified, instead of hardcoding 30 (issue #583; thanks @VastOne)
|
- Set task maximum height equal to width if not specified, instead of hardcoding 30 (issue #583; thanks @VastOne)
|
||||||
|
|||||||
@@ -32,12 +32,11 @@ Execp *create_execp()
|
|||||||
Execp *execp = calloc(1, sizeof(Execp));
|
Execp *execp = calloc(1, sizeof(Execp));
|
||||||
execp->backend = calloc(1, sizeof(ExecpBackend));
|
execp->backend = calloc(1, sizeof(ExecpBackend));
|
||||||
execp->backend->child_pipe = -1;
|
execp->backend->child_pipe = -1;
|
||||||
|
execp->backend->cmd_pids = g_tree_new(cmp_ptr);
|
||||||
execp->backend->interval = 30;
|
execp->backend->interval = 30;
|
||||||
execp->backend->cache_icon = TRUE;
|
execp->backend->cache_icon = TRUE;
|
||||||
execp->backend->centered = TRUE;
|
execp->backend->centered = TRUE;
|
||||||
execp->backend->font_color.alpha = 0.5;
|
execp->backend->font_color.alpha = 0.5;
|
||||||
|
|
||||||
return execp;
|
return execp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +58,9 @@ void destroy_execp(void *obj)
|
|||||||
// This is a frontend element
|
// This is a frontend element
|
||||||
execp->backend->instances = g_list_remove_all(execp->backend->instances, execp);
|
execp->backend->instances = g_list_remove_all(execp->backend->instances, execp);
|
||||||
free_and_null(execp->frontend);
|
free_and_null(execp->frontend);
|
||||||
|
remove_area(&execp->area);
|
||||||
|
free_area(&execp->area);
|
||||||
|
free_and_null(execp);
|
||||||
} else {
|
} else {
|
||||||
// This is a backend element
|
// This is a backend element
|
||||||
stop_timeout(execp->backend->timer);
|
stop_timeout(execp->backend->timer);
|
||||||
@@ -80,6 +82,10 @@ void destroy_execp(void *obj)
|
|||||||
close(execp->backend->child_pipe);
|
close(execp->backend->child_pipe);
|
||||||
execp->backend->child_pipe = -1;
|
execp->backend->child_pipe = -1;
|
||||||
}
|
}
|
||||||
|
if (execp->backend->cmd_pids) {
|
||||||
|
g_tree_destroy(execp->backend->cmd_pids);
|
||||||
|
execp->backend->cmd_pids = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
execp->backend->bg = NULL;
|
execp->backend->bg = NULL;
|
||||||
pango_font_description_free(execp->backend->font_desc);
|
pango_font_description_free(execp->backend->font_desc);
|
||||||
@@ -464,6 +470,18 @@ void execp_dump_geometry(void *obj, int indent)
|
|||||||
execp->backend->text);
|
execp->backend->text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void execp_force_update(Execp *execp)
|
||||||
|
{
|
||||||
|
if (execp->backend->child_pipe > 0) {
|
||||||
|
// Command currently running, nothing to do
|
||||||
|
} else {
|
||||||
|
if (execp->backend->timer)
|
||||||
|
stop_timeout(execp->backend->timer);
|
||||||
|
// Run command right away
|
||||||
|
execp->backend->timer = add_timeout(10, 0, execp_timer_callback, execp, &execp->backend->timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void execp_action(void *obj, int button, int x, int y)
|
void execp_action(void *obj, int button, int x, int y)
|
||||||
{
|
{
|
||||||
Execp *execp = obj;
|
Execp *execp = obj;
|
||||||
@@ -495,20 +513,32 @@ void execp_action(void *obj, int button, int x, int y)
|
|||||||
execp->area.width,
|
execp->area.width,
|
||||||
execp->area.height,
|
execp->area.height,
|
||||||
command);
|
command);
|
||||||
tint_exec(full_cmd);
|
pid_t pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
|
fprintf(stderr, "Could not fork\n");
|
||||||
|
} else if (pid == 0) {
|
||||||
|
// Child process
|
||||||
|
// Allow children to exist after parent destruction
|
||||||
|
setsid();
|
||||||
|
// Run the command
|
||||||
|
execl("/bin/sh", "/bin/sh", "-c", full_cmd, NULL);
|
||||||
|
fprintf(stderr, "Failed to execlp %s\n", full_cmd);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
// Parent process
|
||||||
|
g_tree_insert(execp->backend->cmd_pids, GINT_TO_POINTER(pid), GINT_TO_POINTER(1));
|
||||||
g_free(full_cmd);
|
g_free(full_cmd);
|
||||||
} else {
|
} else {
|
||||||
if (execp->backend->child_pipe > 0) {
|
execp_force_update(execp);
|
||||||
// Command currently running, nothing to do
|
|
||||||
} else {
|
|
||||||
if (execp->backend->timer)
|
|
||||||
stop_timeout(execp->backend->timer);
|
|
||||||
// Run command right away
|
|
||||||
execp->backend->timer = add_timeout(10, 0, execp_timer_callback, execp, &execp->backend->timer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void execp_cmd_completed(Execp *execp, pid_t pid)
|
||||||
|
{
|
||||||
|
g_tree_remove(execp->backend->cmd_pids, GINT_TO_POINTER(pid));
|
||||||
|
execp_force_update(execp);
|
||||||
|
}
|
||||||
|
|
||||||
void execp_timer_callback(void *arg)
|
void execp_timer_callback(void *arg)
|
||||||
{
|
{
|
||||||
Execp *execp = arg;
|
Execp *execp = arg;
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ typedef struct ExecpBackend {
|
|||||||
|
|
||||||
// List of Execp which are frontends for this backend, one for each panel
|
// List of Execp which are frontends for this backend, one for each panel
|
||||||
GList *instances;
|
GList *instances;
|
||||||
|
GTree *cmd_pids;
|
||||||
} ExecpBackend;
|
} ExecpBackend;
|
||||||
|
|
||||||
typedef struct ExecpFrontend {
|
typedef struct ExecpFrontend {
|
||||||
@@ -130,6 +131,8 @@ gboolean resize_execp(void *obj);
|
|||||||
// Called on mouse click event.
|
// Called on mouse click event.
|
||||||
void execp_action(void *obj, int button, int x, int y);
|
void execp_action(void *obj, int button, int x, int y);
|
||||||
|
|
||||||
|
void execp_cmd_completed(Execp *obj, pid_t pid);
|
||||||
|
|
||||||
// Called to check if new output from the command can be read.
|
// Called to check if new output from the command can be read.
|
||||||
// No command might be running.
|
// No command might be running.
|
||||||
// Returns 1 if the output has been updated and a redraw is needed.
|
// Returns 1 if the output has been updated and a redraw is needed.
|
||||||
|
|||||||
@@ -305,6 +305,7 @@ void free_themes(IconThemeWrapper *wrapper)
|
|||||||
{
|
{
|
||||||
if (!wrapper)
|
if (!wrapper)
|
||||||
return;
|
return;
|
||||||
|
free(wrapper->icon_theme_name);
|
||||||
for (GSList *l = wrapper->themes; l; l = l->next) {
|
for (GSList *l = wrapper->themes; l; l = l->next) {
|
||||||
IconTheme *theme = (IconTheme *)l->data;
|
IconTheme *theme = (IconTheme *)l->data;
|
||||||
free_icon_theme(theme);
|
free_icon_theme(theme);
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ Background *launcher_icon_bg;
|
|||||||
Imlib_Image scale_icon(Imlib_Image original, int icon_size);
|
Imlib_Image scale_icon(Imlib_Image original, int icon_size);
|
||||||
void free_icon(Imlib_Image icon);
|
void free_icon(Imlib_Image icon);
|
||||||
void launcher_icon_dump_geometry(void *obj, int indent);
|
void launcher_icon_dump_geometry(void *obj, int indent);
|
||||||
|
void launcher_reload_icon(Launcher *launcher, LauncherIcon *launcherIcon);
|
||||||
|
void launcher_reload_icon_image(Launcher *launcher, LauncherIcon *launcherIcon);
|
||||||
|
void launcher_reload_hidden_icons(Launcher *launcher);
|
||||||
|
void launcher_icon_on_change_layout(void *obj);
|
||||||
|
|
||||||
void default_launcher()
|
void default_launcher()
|
||||||
{
|
{
|
||||||
@@ -143,6 +147,7 @@ void cleanup_launcher_theme(Launcher *launcher)
|
|||||||
free(launcherIcon->icon_path);
|
free(launcherIcon->icon_path);
|
||||||
free(launcherIcon->cmd);
|
free(launcherIcon->cmd);
|
||||||
g_free(launcherIcon->icon_tooltip);
|
g_free(launcherIcon->icon_tooltip);
|
||||||
|
free(launcherIcon->config_path);
|
||||||
}
|
}
|
||||||
free(launcherIcon);
|
free(launcherIcon);
|
||||||
}
|
}
|
||||||
@@ -176,61 +181,17 @@ gboolean resize_launcher(void *obj)
|
|||||||
launcherIcon->icon_size = icon_size;
|
launcherIcon->icon_size = icon_size;
|
||||||
launcherIcon->area.width = launcherIcon->icon_size;
|
launcherIcon->area.width = launcherIcon->icon_size;
|
||||||
launcherIcon->area.height = launcherIcon->icon_size;
|
launcherIcon->area.height = launcherIcon->icon_size;
|
||||||
|
launcher_reload_icon_image(launcher, launcherIcon);
|
||||||
// Get the path for an icon file with the new size
|
|
||||||
char *new_icon_path =
|
|
||||||
get_icon_path(launcher->icon_theme_wrapper, launcherIcon->icon_name, launcherIcon->icon_size);
|
|
||||||
if (!new_icon_path) {
|
|
||||||
// Draw a blank icon
|
|
||||||
free_icon(launcherIcon->image);
|
|
||||||
free_icon(launcherIcon->image_hover);
|
|
||||||
free_icon(launcherIcon->image_pressed);
|
|
||||||
launcherIcon->image = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free the old files
|
|
||||||
free_icon(launcherIcon->image);
|
|
||||||
free_icon(launcherIcon->image_hover);
|
|
||||||
free_icon(launcherIcon->image_pressed);
|
|
||||||
// Load the new file
|
|
||||||
launcherIcon->image = load_image(new_icon_path, 1);
|
|
||||||
// On loading error, fallback to default
|
|
||||||
if (!launcherIcon->image) {
|
|
||||||
free(new_icon_path);
|
|
||||||
new_icon_path = get_icon_path(launcher->icon_theme_wrapper, DEFAULT_ICON, launcherIcon->icon_size);
|
|
||||||
if (new_icon_path)
|
|
||||||
launcherIcon->image = imlib_load_image_immediately(new_icon_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!launcherIcon->image) {
|
|
||||||
// Loading default icon failed, draw a blank icon
|
|
||||||
free(new_icon_path);
|
|
||||||
} else {
|
|
||||||
// Loaded icon successfully, rescale it
|
|
||||||
Imlib_Image original = launcherIcon->image;
|
|
||||||
launcherIcon->image = scale_icon(launcherIcon->image, launcherIcon->icon_size);
|
|
||||||
free_icon(original);
|
|
||||||
free(launcherIcon->icon_path);
|
|
||||||
launcherIcon->icon_path = new_icon_path;
|
|
||||||
fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (panel_config.mouse_effects) {
|
|
||||||
launcherIcon->image_hover = adjust_icon(launcherIcon->image,
|
|
||||||
panel_config.mouse_over_alpha,
|
|
||||||
panel_config.mouse_over_saturation,
|
|
||||||
panel_config.mouse_over_brightness);
|
|
||||||
launcherIcon->image_pressed = adjust_icon(launcherIcon->image,
|
|
||||||
panel_config.mouse_pressed_alpha,
|
|
||||||
panel_config.mouse_pressed_saturation,
|
|
||||||
panel_config.mouse_pressed_brightness);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
save_icon_cache(launcher->icon_theme_wrapper);
|
save_icon_cache(launcher->icon_theme_wrapper);
|
||||||
|
|
||||||
int count = g_slist_length(launcher->list_icons);
|
int count = 0;
|
||||||
|
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
||||||
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
|
if (launcherIcon->area.on_screen)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
if (!count) {
|
if (!count) {
|
||||||
@@ -268,17 +229,15 @@ gboolean resize_launcher(void *obj)
|
|||||||
posy = top_border_width(&launcher->area) + launcher->area.paddingxlr;
|
posy = top_border_width(&launcher->area) + launcher->area.paddingxlr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i = 0;
|
||||||
GSList *l;
|
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
||||||
for (i = 1, l = launcher->list_icons; l; i++, l = l->next) {
|
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
|
if (!launcherIcon->area.on_screen)
|
||||||
|
continue;
|
||||||
|
i++;
|
||||||
launcherIcon->y = posy;
|
launcherIcon->y = posy;
|
||||||
launcherIcon->x = posx;
|
launcherIcon->x = posx;
|
||||||
launcherIcon->area.posy = ((Area *)launcherIcon->area.parent)->posy + launcherIcon->y;
|
launcher_icon_on_change_layout(launcherIcon);
|
||||||
launcherIcon->area.posx = ((Area *)launcherIcon->area.parent)->posx + launcherIcon->x;
|
|
||||||
launcherIcon->area.width = launcherIcon->icon_size;
|
|
||||||
launcherIcon->area.height = launcherIcon->icon_size;
|
|
||||||
// printf("launcher %d : %d,%d\n", i, posx, posy);
|
// printf("launcher %d : %d,%d\n", i, posx, posy);
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
if (i % icons_per_column) {
|
if (i % icons_per_column) {
|
||||||
@@ -401,6 +360,8 @@ void free_icon(Imlib_Image icon)
|
|||||||
|
|
||||||
void launcher_action(LauncherIcon *icon, XEvent *evt)
|
void launcher_action(LauncherIcon *icon, XEvent *evt)
|
||||||
{
|
{
|
||||||
|
launcher_reload_icon((Launcher *)icon->area.parent, icon);
|
||||||
|
launcher_reload_hidden_icons((Launcher *)icon->area.parent);
|
||||||
char *cmd = calloc(strlen(icon->cmd) + 10, 1);
|
char *cmd = calloc(strlen(icon->cmd) + 10, 1);
|
||||||
sprintf(cmd, "(%s&)", icon->cmd);
|
sprintf(cmd, "(%s&)", icon->cmd);
|
||||||
#if HAVE_SN
|
#if HAVE_SN
|
||||||
@@ -461,56 +422,109 @@ void launcher_load_icons(Launcher *launcher)
|
|||||||
// Load apps (.desktop style launcher items)
|
// Load apps (.desktop style launcher items)
|
||||||
GSList *app = launcher->list_apps;
|
GSList *app = launcher->list_apps;
|
||||||
while (app != NULL) {
|
while (app != NULL) {
|
||||||
DesktopEntry entry;
|
LauncherIcon *launcherIcon = calloc(1, sizeof(LauncherIcon));
|
||||||
read_desktop_file(app->data, &entry);
|
launcherIcon->area.panel = launcher->area.panel;
|
||||||
if (entry.exec) {
|
launcherIcon->area._draw_foreground = draw_launcher_icon;
|
||||||
LauncherIcon *launcherIcon = calloc(1, sizeof(LauncherIcon));
|
launcherIcon->area.size_mode = LAYOUT_FIXED;
|
||||||
launcherIcon->area.panel = launcher->area.panel;
|
launcherIcon->area._resize = NULL;
|
||||||
snprintf(launcherIcon->area.name,
|
launcherIcon->area.resize_needed = 0;
|
||||||
sizeof(launcherIcon->area.name),
|
launcherIcon->area.has_mouse_over_effect = panel_config.mouse_effects;
|
||||||
"LauncherIcon %s",
|
launcherIcon->area.has_mouse_press_effect = launcherIcon->area.has_mouse_over_effect;
|
||||||
entry.name ? entry.name : "null");
|
launcherIcon->area.bg = launcher_icon_bg;
|
||||||
launcherIcon->area._draw_foreground = draw_launcher_icon;
|
launcherIcon->area.on_screen = TRUE;
|
||||||
launcherIcon->area.size_mode = LAYOUT_FIXED;
|
launcherIcon->area._on_change_layout = launcher_icon_on_change_layout;
|
||||||
launcherIcon->area._resize = NULL;
|
launcherIcon->area._dump_geometry = launcher_icon_dump_geometry;
|
||||||
launcherIcon->area.resize_needed = 0;
|
if (launcher_tooltip_enabled) {
|
||||||
schedule_redraw(&launcherIcon->area);
|
launcherIcon->area._get_tooltip_text = launcher_icon_get_tooltip_text;
|
||||||
launcherIcon->area.has_mouse_over_effect = panel_config.mouse_effects;
|
} else {
|
||||||
launcherIcon->area.has_mouse_press_effect = launcherIcon->area.has_mouse_over_effect;
|
launcherIcon->area._get_tooltip_text = NULL;
|
||||||
launcherIcon->area.bg = launcher_icon_bg;
|
|
||||||
launcherIcon->area.on_screen = TRUE;
|
|
||||||
launcherIcon->area._on_change_layout = launcher_icon_on_change_layout;
|
|
||||||
launcherIcon->area._dump_geometry = launcher_icon_dump_geometry;
|
|
||||||
if (launcher_tooltip_enabled) {
|
|
||||||
launcherIcon->area._get_tooltip_text = launcher_icon_get_tooltip_text;
|
|
||||||
} else {
|
|
||||||
launcherIcon->area._get_tooltip_text = NULL;
|
|
||||||
}
|
|
||||||
launcherIcon->is_app_desktop = 1;
|
|
||||||
launcherIcon->cmd = strdup(entry.exec);
|
|
||||||
launcherIcon->icon_name = entry.icon ? strdup(entry.icon) : strdup(DEFAULT_ICON);
|
|
||||||
launcherIcon->icon_size = 1;
|
|
||||||
if (entry.name) {
|
|
||||||
if (entry.generic_name) {
|
|
||||||
launcherIcon->icon_tooltip = g_strdup_printf("%s (%s)", entry.name, entry.generic_name);
|
|
||||||
} else {
|
|
||||||
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.name);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (entry.generic_name) {
|
|
||||||
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.generic_name);
|
|
||||||
} else if (entry.exec) {
|
|
||||||
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.exec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
launcher->list_icons = g_slist_append(launcher->list_icons, launcherIcon);
|
|
||||||
add_area(&launcherIcon->area, (Area *)launcher);
|
|
||||||
}
|
}
|
||||||
free_desktop_entry(&entry);
|
launcherIcon->config_path = strdup(app->data);
|
||||||
|
add_area(&launcherIcon->area, (Area *)launcher);
|
||||||
|
launcher->list_icons = g_slist_append(launcher->list_icons, launcherIcon);
|
||||||
|
launcher_reload_icon(launcher, launcherIcon);
|
||||||
app = g_slist_next(app);
|
app = g_slist_next(app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void launcher_reload_icon(Launcher *launcher, LauncherIcon *launcherIcon)
|
||||||
|
{
|
||||||
|
DesktopEntry entry;
|
||||||
|
if (read_desktop_file(launcherIcon->config_path, &entry) && entry.exec) {
|
||||||
|
schedule_redraw(&launcherIcon->area);
|
||||||
|
if (launcherIcon->cmd)
|
||||||
|
free(launcherIcon->cmd);
|
||||||
|
launcherIcon->cmd = strdup(entry.exec);
|
||||||
|
if (launcherIcon->icon_name)
|
||||||
|
free(launcherIcon->icon_name);
|
||||||
|
launcherIcon->icon_name = entry.icon ? strdup(entry.icon) : strdup(DEFAULT_ICON);
|
||||||
|
if (entry.name) {
|
||||||
|
if (entry.generic_name) {
|
||||||
|
launcherIcon->icon_tooltip = g_strdup_printf("%s (%s)", entry.name, entry.generic_name);
|
||||||
|
} else {
|
||||||
|
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (entry.generic_name) {
|
||||||
|
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.generic_name);
|
||||||
|
} else if (entry.exec) {
|
||||||
|
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.exec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
launcher_reload_icon_image(launcher, launcherIcon);
|
||||||
|
if (!launcherIcon->area.on_screen)
|
||||||
|
show(&launcherIcon->area);
|
||||||
|
} else {
|
||||||
|
hide(&launcherIcon->area);
|
||||||
|
}
|
||||||
|
free_desktop_entry(&entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
void launcher_reload_hidden_icons(Launcher *launcher)
|
||||||
|
{
|
||||||
|
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
||||||
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
|
if (!launcherIcon->area.on_screen)
|
||||||
|
launcher_reload_icon(launcher, launcherIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void launcher_reload_icon_image(Launcher *launcher, LauncherIcon *launcherIcon)
|
||||||
|
{
|
||||||
|
free_icon(launcherIcon->image);
|
||||||
|
free_icon(launcherIcon->image_hover);
|
||||||
|
free_icon(launcherIcon->image_pressed);
|
||||||
|
launcherIcon->image = NULL;
|
||||||
|
|
||||||
|
char *new_icon_path = get_icon_path(launcher->icon_theme_wrapper, launcherIcon->icon_name, launcherIcon->icon_size);
|
||||||
|
if (new_icon_path)
|
||||||
|
launcherIcon->image = load_image(new_icon_path, 1);
|
||||||
|
// On loading error, fallback to default
|
||||||
|
if (!launcherIcon->image) {
|
||||||
|
free(new_icon_path);
|
||||||
|
new_icon_path = get_icon_path(launcher->icon_theme_wrapper, DEFAULT_ICON, launcherIcon->icon_size);
|
||||||
|
if (new_icon_path)
|
||||||
|
launcherIcon->image = imlib_load_image_immediately(new_icon_path);
|
||||||
|
}
|
||||||
|
Imlib_Image original = launcherIcon->image;
|
||||||
|
launcherIcon->image = scale_icon(launcherIcon->image, launcherIcon->icon_size);
|
||||||
|
free_icon(original);
|
||||||
|
free(launcherIcon->icon_path);
|
||||||
|
launcherIcon->icon_path = new_icon_path;
|
||||||
|
// fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);
|
||||||
|
|
||||||
|
if (panel_config.mouse_effects) {
|
||||||
|
launcherIcon->image_hover = adjust_icon(launcherIcon->image,
|
||||||
|
panel_config.mouse_over_alpha,
|
||||||
|
panel_config.mouse_over_saturation,
|
||||||
|
panel_config.mouse_over_brightness);
|
||||||
|
launcherIcon->image_pressed = adjust_icon(launcherIcon->image,
|
||||||
|
panel_config.mouse_pressed_alpha,
|
||||||
|
panel_config.mouse_pressed_saturation,
|
||||||
|
panel_config.mouse_pressed_brightness);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Populates the icon_theme_wrapper list
|
// Populates the icon_theme_wrapper list
|
||||||
void launcher_load_themes(Launcher *launcher)
|
void launcher_load_themes(Launcher *launcher)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ typedef struct Launcher {
|
|||||||
typedef struct LauncherIcon {
|
typedef struct LauncherIcon {
|
||||||
// always start with area
|
// always start with area
|
||||||
Area area;
|
Area area;
|
||||||
|
char *config_path;
|
||||||
Imlib_Image image;
|
Imlib_Image image;
|
||||||
Imlib_Image image_hover;
|
Imlib_Image image_hover;
|
||||||
Imlib_Image image_pressed;
|
Imlib_Image image_pressed;
|
||||||
@@ -31,7 +32,6 @@ typedef struct LauncherIcon {
|
|||||||
char *icon_path;
|
char *icon_path;
|
||||||
char *icon_tooltip;
|
char *icon_tooltip;
|
||||||
int icon_size;
|
int icon_size;
|
||||||
int is_app_desktop;
|
|
||||||
int x, y;
|
int x, y;
|
||||||
} LauncherIcon;
|
} LauncherIcon;
|
||||||
|
|
||||||
|
|||||||
13
src/panel.c
13
src/panel.c
@@ -269,12 +269,11 @@ void init_panel()
|
|||||||
|
|
||||||
if (panel_autohide)
|
if (panel_autohide)
|
||||||
autohide_trigger_hide(p);
|
autohide_trigger_hide(p);
|
||||||
|
|
||||||
update_taskbar_visibility(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
taskbar_refresh_tasklist();
|
taskbar_refresh_tasklist();
|
||||||
reset_active_task();
|
reset_active_task();
|
||||||
|
update_all_taskbars_visibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_panel_size_and_position(Panel *panel)
|
void init_panel_size_and_position(Panel *panel)
|
||||||
@@ -395,7 +394,11 @@ gboolean resize_panel(void *obj)
|
|||||||
int total_size = 0;
|
int total_size = 0;
|
||||||
int total_name_size = 0;
|
int total_name_size = 0;
|
||||||
int total_items = 0;
|
int total_items = 0;
|
||||||
|
int visible_taskbars = 0;
|
||||||
for (int i = 0; i < panel->num_desktops; i++) {
|
for (int i = 0; i < panel->num_desktops; i++) {
|
||||||
|
if (!panel->taskbar[i].area.on_screen)
|
||||||
|
continue;
|
||||||
|
visible_taskbars++;
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
total_size += panel->taskbar[i].area.width;
|
total_size += panel->taskbar[i].area.width;
|
||||||
} else {
|
} else {
|
||||||
@@ -427,14 +430,16 @@ gboolean resize_panel(void *obj)
|
|||||||
if (total_items) {
|
if (total_items) {
|
||||||
int actual_name_size;
|
int actual_name_size;
|
||||||
if (total_name_size <= total_size) {
|
if (total_name_size <= total_size) {
|
||||||
actual_name_size = total_name_size / panel->num_desktops;
|
actual_name_size = total_name_size / visible_taskbars;
|
||||||
} else {
|
} else {
|
||||||
actual_name_size = total_size / panel->num_desktops;
|
actual_name_size = total_size / visible_taskbars;
|
||||||
}
|
}
|
||||||
total_size -= total_name_size;
|
total_size -= total_name_size;
|
||||||
|
|
||||||
for (int i = 0; i < panel->num_desktops; i++) {
|
for (int i = 0; i < panel->num_desktops; i++) {
|
||||||
Taskbar *taskbar = &panel->taskbar[i];
|
Taskbar *taskbar = &panel->taskbar[i];
|
||||||
|
if (!taskbar->area.on_screen)
|
||||||
|
continue;
|
||||||
|
|
||||||
int requested_size = (panel_horizontal ? left_right_border_width(&taskbar->area)
|
int requested_size = (panel_horizontal ? left_right_border_width(&taskbar->area)
|
||||||
: top_bottom_border_width(&taskbar->area)) +
|
: top_bottom_border_width(&taskbar->area)) +
|
||||||
|
|||||||
@@ -140,6 +140,11 @@ void cleanup_server()
|
|||||||
XFreeGC(server.display, server.gc);
|
XFreeGC(server.display, server.gc);
|
||||||
server.gc = NULL;
|
server.gc = NULL;
|
||||||
server.disable_transparency = FALSE;
|
server.disable_transparency = FALSE;
|
||||||
|
#ifdef HAVE_SN
|
||||||
|
if (server.pids)
|
||||||
|
g_tree_destroy(server.pids);
|
||||||
|
server.pids = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_event32(Window win, Atom at, long data1, long data2, long data3)
|
void send_event32(Window win, Atom at, long data1, long data2, long data3)
|
||||||
|
|||||||
@@ -268,21 +268,26 @@ void task_update_icon(Task *task)
|
|||||||
|
|
||||||
Imlib_Image img = NULL;
|
Imlib_Image img = NULL;
|
||||||
|
|
||||||
int i;
|
if (!img) {
|
||||||
gulong *data = server_get_property(task->win, server.atom._NET_WM_ICON, XA_CARDINAL, &i);
|
int i;
|
||||||
if (data) {
|
gulong *data = server_get_property(task->win, server.atom._NET_WM_ICON, XA_CARDINAL, &i);
|
||||||
// get ARGB icon
|
if (data) {
|
||||||
int w, h;
|
// get ARGB icon
|
||||||
gulong *tmp_data;
|
int w, h;
|
||||||
|
gulong *tmp_data;
|
||||||
|
|
||||||
tmp_data = get_best_icon(data, get_icon_count(data, i), i, &w, &h, panel->g_task.icon_size1);
|
tmp_data = get_best_icon(data, get_icon_count(data, i), i, &w, &h, panel->g_task.icon_size1);
|
||||||
DATA32 icon_data[w * h];
|
DATA32 icon_data[w * h];
|
||||||
for (int j = 0; j < w * h; ++j)
|
for (int j = 0; j < w * h; ++j)
|
||||||
icon_data[j] = tmp_data[j];
|
icon_data[j] = tmp_data[j];
|
||||||
img = imlib_create_image_using_copied_data(w, h, icon_data);
|
img = imlib_create_image_using_copied_data(w, h, icon_data);
|
||||||
XFree(data);
|
if (img)
|
||||||
} else {
|
fprintf(stderr, "%s: Got %dx%d icon via _NET_WM_ICON for %s\n", __FUNCTION__, w, h, task->title ? task->title : "task");
|
||||||
// get Pixmap icon
|
XFree(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!img) {
|
||||||
XWMHints *hints = XGetWMHints(server.display, task->win);
|
XWMHints *hints = XGetWMHints(server.display, task->win);
|
||||||
if (hints) {
|
if (hints) {
|
||||||
if (hints->flags & IconPixmapHint && hints->icon_pixmap != 0) {
|
if (hints->flags & IconPixmapHint && hints->icon_pixmap != 0) {
|
||||||
@@ -292,17 +297,20 @@ void task_update_icon(Task *task)
|
|||||||
uint border_width, bpp;
|
uint border_width, bpp;
|
||||||
uint w, h;
|
uint w, h;
|
||||||
|
|
||||||
// printf(" get pixmap\n");
|
|
||||||
XGetGeometry(server.display, hints->icon_pixmap, &root, &icon_x, &icon_y, &w, &h, &border_width, &bpp);
|
XGetGeometry(server.display, hints->icon_pixmap, &root, &icon_x, &icon_y, &w, &h, &border_width, &bpp);
|
||||||
imlib_context_set_drawable(hints->icon_pixmap);
|
imlib_context_set_drawable(hints->icon_pixmap);
|
||||||
img = imlib_create_image_from_drawable(hints->icon_mask, 0, 0, w, h, 0);
|
img = imlib_create_image_from_drawable(hints->icon_mask, 0, 0, w, h, 0);
|
||||||
|
if (img)
|
||||||
|
fprintf(stderr, "%s: Got %dx%d pixmap icon via WM_HINTS for %s\n", __FUNCTION__, w, h, task->title ? task->title : "task");
|
||||||
}
|
}
|
||||||
XFree(hints);
|
XFree(hints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (img == NULL) {
|
if (img == NULL) {
|
||||||
imlib_context_set_image(default_icon);
|
imlib_context_set_image(default_icon);
|
||||||
img = imlib_clone_image();
|
img = imlib_clone_image();
|
||||||
|
fprintf(stderr, "%s: Using default icon for %s\n", __FUNCTION__, task->title ? task->title : "task");
|
||||||
}
|
}
|
||||||
|
|
||||||
// transform icons
|
// transform icons
|
||||||
@@ -348,7 +356,7 @@ void task_update_icon(Task *task)
|
|||||||
|
|
||||||
GPtrArray *task_buttons = get_task_buttons(task->win);
|
GPtrArray *task_buttons = get_task_buttons(task->win);
|
||||||
if (task_buttons) {
|
if (task_buttons) {
|
||||||
for (i = 0; i < task_buttons->len; ++i) {
|
for (int i = 0; i < task_buttons->len; ++i) {
|
||||||
Task *task2 = g_ptr_array_index(task_buttons, i);
|
Task *task2 = g_ptr_array_index(task_buttons, i);
|
||||||
task2->icon_width = task->icon_width;
|
task2->icon_width = task->icon_width;
|
||||||
task2->icon_height = task->icon_height;
|
task2->icon_height = task->icon_height;
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ void init_taskbar_panel(void *p)
|
|||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
panel->g_taskbar.area.posy = top_border_width(&panel->area) + panel->area.paddingy;
|
panel->g_taskbar.area.posy = top_border_width(&panel->area) + panel->area.paddingy;
|
||||||
panel->g_taskbar.area.height =
|
panel->g_taskbar.area.height =
|
||||||
panel->area.height - top_bottom_border_width(&panel->area) - 2 * panel->area.paddingy;
|
panel->area.height - top_bottom_border_width(&panel->area) - 2 * panel->area.paddingy;
|
||||||
panel->g_taskbar.area_name.posy = panel->g_taskbar.area.posy;
|
panel->g_taskbar.area_name.posy = panel->g_taskbar.area.posy;
|
||||||
panel->g_taskbar.area_name.height = panel->g_taskbar.area.height;
|
panel->g_taskbar.area_name.height = panel->g_taskbar.area.height;
|
||||||
} else {
|
} else {
|
||||||
@@ -430,18 +430,51 @@ gboolean resize_taskbar(void *obj)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean taskbar_is_empty(Taskbar *taskbar)
|
||||||
|
{
|
||||||
|
GList *l = taskbar->area.children;
|
||||||
|
if (taskbarname_enabled)
|
||||||
|
l = l->next;
|
||||||
|
for (; l != NULL; l = l->next) {
|
||||||
|
if (((Task *)l->data)->area.on_screen) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_one_taskbar_visibility(Taskbar *taskbar)
|
||||||
|
{
|
||||||
|
if (taskbar->desktop == server.desktop) {
|
||||||
|
// Taskbar for current desktop is always shown
|
||||||
|
show(&taskbar->area);
|
||||||
|
} else if (taskbar_mode == MULTI_DESKTOP && taskbar_is_empty(taskbar)) {
|
||||||
|
// MULTI_DESKTOP : show non-empty taskbars
|
||||||
|
show(&taskbar->area);
|
||||||
|
} else {
|
||||||
|
hide(&taskbar->area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_all_taskbars_visibility()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < num_panels; i++) {
|
||||||
|
Panel *panel = &panels[i];
|
||||||
|
for (int j = 0; j < panel->num_desktops; j++) {
|
||||||
|
update_one_taskbar_visibility(&panel->taskbar[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void set_taskbar_state(Taskbar *taskbar, TaskbarState state)
|
void set_taskbar_state(Taskbar *taskbar, TaskbarState state)
|
||||||
{
|
{
|
||||||
taskbar->area.bg = panels[0].g_taskbar.background[state];
|
taskbar->area.bg = panels[0].g_taskbar.background[state];
|
||||||
if (taskbarname_enabled) {
|
if (taskbarname_enabled) {
|
||||||
taskbar->bar_name.area.bg = panels[0].g_taskbar.background_name[state];
|
taskbar->bar_name.area.bg = panels[0].g_taskbar.background_name[state];
|
||||||
}
|
}
|
||||||
if (taskbar_mode != MULTI_DESKTOP) {
|
|
||||||
if (state == TASKBAR_NORMAL)
|
update_one_taskbar_visibility(taskbar);
|
||||||
taskbar->area.on_screen = FALSE;
|
|
||||||
else
|
|
||||||
taskbar->area.on_screen = TRUE;
|
|
||||||
}
|
|
||||||
if (taskbar->area.on_screen) {
|
if (taskbar->area.on_screen) {
|
||||||
schedule_redraw(&taskbar->area);
|
schedule_redraw(&taskbar->area);
|
||||||
if (taskbarname_enabled) {
|
if (taskbarname_enabled) {
|
||||||
@@ -459,22 +492,6 @@ void set_taskbar_state(Taskbar *taskbar, TaskbarState state)
|
|||||||
panel_refresh = TRUE;
|
panel_refresh = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_taskbar_visibility(void *p)
|
|
||||||
{
|
|
||||||
Panel *panel = (Panel *)p;
|
|
||||||
|
|
||||||
for (int j = 0; j < panel->num_desktops; j++) {
|
|
||||||
Taskbar *taskbar = &panel->taskbar[j];
|
|
||||||
if (taskbar_mode != MULTI_DESKTOP && taskbar->desktop != server.desktop) {
|
|
||||||
// SINGLE_DESKTOP and not current desktop
|
|
||||||
taskbar->area.on_screen = FALSE;
|
|
||||||
} else {
|
|
||||||
taskbar->area.on_screen = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
panel_refresh = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NONTRIVIAL 2
|
#define NONTRIVIAL 2
|
||||||
gint compare_tasks_trivial(Task *a, Task *b, Taskbar *taskbar)
|
gint compare_tasks_trivial(Task *a, Task *b, Taskbar *taskbar)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -79,10 +79,11 @@ Task *get_task(Window win);
|
|||||||
// However for windows shown on all desktops, there are multiple buttons, one for each taskbar.
|
// However for windows shown on all desktops, there are multiple buttons, one for each taskbar.
|
||||||
GPtrArray *get_task_buttons(Window win);
|
GPtrArray *get_task_buttons(Window win);
|
||||||
|
|
||||||
|
// Change state of a taskbar (ACTIVE or NORMAL)
|
||||||
void set_taskbar_state(Taskbar *taskbar, TaskbarState state);
|
void set_taskbar_state(Taskbar *taskbar, TaskbarState state);
|
||||||
|
|
||||||
// Updates the visibility of each taskbar when the current desktop changes.
|
// Updates the visibility of all taskbars
|
||||||
void update_taskbar_visibility(void *p);
|
void update_all_taskbars_visibility();
|
||||||
|
|
||||||
// Sorts the taskbar(s) on which the window is present.
|
// Sorts the taskbar(s) on which the window is present.
|
||||||
void sort_taskbar_for_win(Window win);
|
void sort_taskbar_for_win(Window win);
|
||||||
|
|||||||
98
src/tint.c
98
src/tint.c
@@ -18,6 +18,7 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -36,10 +37,10 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#ifdef HAVE_SN
|
#ifdef HAVE_SN
|
||||||
#include <libsn/sn.h>
|
#include <libsn/sn.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
@@ -376,8 +377,8 @@ void init(int argc, char *argv[])
|
|||||||
debug_geometry = getenv("DEBUG_GEOMETRY") != NULL;
|
debug_geometry = getenv("DEBUG_GEOMETRY") != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sn_pipe_valid = 0;
|
static int sigchild_pipe_valid = FALSE;
|
||||||
static int sn_pipe[2];
|
static int sigchild_pipe[2];
|
||||||
|
|
||||||
#ifdef HAVE_SN
|
#ifdef HAVE_SN
|
||||||
static int error_trap_depth = 0;
|
static int error_trap_depth = 0;
|
||||||
@@ -397,50 +398,41 @@ static void error_trap_pop(SnDisplay *display, Display *xdisplay)
|
|||||||
XSync(xdisplay, False); /* get all errors out of the queue */
|
XSync(xdisplay, False); /* get all errors out of the queue */
|
||||||
--error_trap_depth;
|
--error_trap_depth;
|
||||||
}
|
}
|
||||||
|
#endif // HAVE_SN
|
||||||
|
|
||||||
static void sigchld_handler(int sig)
|
static void sigchld_handler(int sig)
|
||||||
{
|
{
|
||||||
if (!startup_notifications)
|
if (!sigchild_pipe_valid)
|
||||||
return;
|
return;
|
||||||
if (!sn_pipe_valid)
|
int savedErrno = errno;
|
||||||
return;
|
ssize_t unused = write(sigchild_pipe[1], "x", 1);
|
||||||
ssize_t wur = write(sn_pipe[1], "x", 1);
|
(void)unused;
|
||||||
(void)wur;
|
fsync(sigchild_pipe[1]);
|
||||||
fsync(sn_pipe[1]);
|
errno = savedErrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sigchld_handler_async()
|
static void sigchld_handler_async()
|
||||||
{
|
{
|
||||||
if (!startup_notifications)
|
|
||||||
return;
|
|
||||||
// Wait for all dead processes
|
// Wait for all dead processes
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
|
int status;
|
||||||
SnLauncherContext *ctx;
|
while ((pid = waitpid(-1, &status, WNOHANG)) != -1 && pid != 0) {
|
||||||
ctx = (SnLauncherContext *)g_tree_lookup(server.pids, GINT_TO_POINTER(pid));
|
#ifdef HAVE_SN
|
||||||
|
SnLauncherContext *ctx = (SnLauncherContext *)g_tree_lookup(server.pids, GINT_TO_POINTER(pid));
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
g_tree_remove(server.pids, GINT_TO_POINTER(pid));
|
g_tree_remove(server.pids, GINT_TO_POINTER(pid));
|
||||||
sn_launcher_context_complete(ctx);
|
sn_launcher_context_complete(ctx);
|
||||||
sn_launcher_context_unref(ctx);
|
sn_launcher_context_unref(ctx);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
for (GList *l = panel_config.execp_list; l; l = l->next) {
|
||||||
|
Execp *execp = (Execp *)l->data;
|
||||||
|
if (g_tree_lookup(execp->backend->cmd_pids, GINT_TO_POINTER(pid)))
|
||||||
|
execp_cmd_completed(execp, pid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint cmp_ptr(gconstpointer a, gconstpointer b)
|
|
||||||
{
|
|
||||||
if (a < b)
|
|
||||||
return -1;
|
|
||||||
else if (a == b)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static void sigchld_handler_async()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif // HAVE_SN
|
|
||||||
|
|
||||||
void init_X11_pre_config()
|
void init_X11_pre_config()
|
||||||
{
|
{
|
||||||
server.display = XOpenDisplay(NULL);
|
server.display = XOpenDisplay(NULL);
|
||||||
@@ -475,25 +467,32 @@ void init_X11_post_config()
|
|||||||
{
|
{
|
||||||
server_init_visual();
|
server_init_visual();
|
||||||
|
|
||||||
|
gboolean need_sigchld = FALSE;
|
||||||
#ifdef HAVE_SN
|
#ifdef HAVE_SN
|
||||||
// Initialize startup-notification
|
// Initialize startup-notification
|
||||||
if (startup_notifications) {
|
if (startup_notifications) {
|
||||||
server.sn_display = sn_display_new(server.display, error_trap_push, error_trap_pop);
|
server.sn_display = sn_display_new(server.display, error_trap_push, error_trap_pop);
|
||||||
server.pids = g_tree_new(cmp_ptr);
|
server.pids = g_tree_new(cmp_ptr);
|
||||||
|
need_sigchld = TRUE;
|
||||||
|
}
|
||||||
|
#endif // HAVE_SN
|
||||||
|
if (panel_config.execp_list)
|
||||||
|
need_sigchld = TRUE;
|
||||||
|
|
||||||
|
if (need_sigchld) {
|
||||||
// Setup a handler for child termination
|
// Setup a handler for child termination
|
||||||
if (pipe(sn_pipe) != 0) {
|
if (pipe(sigchild_pipe) != 0) {
|
||||||
fprintf(stderr, "Creating pipe failed.\n");
|
fprintf(stderr, "Creating pipe failed.\n");
|
||||||
} else {
|
} else {
|
||||||
fcntl(sn_pipe[0], F_SETFL, O_NONBLOCK | fcntl(sn_pipe[0], F_GETFL));
|
fcntl(sigchild_pipe[0], F_SETFL, O_NONBLOCK | fcntl(sigchild_pipe[0], F_GETFL));
|
||||||
fcntl(sn_pipe[1], F_SETFL, O_NONBLOCK | fcntl(sn_pipe[1], F_GETFL));
|
fcntl(sigchild_pipe[1], F_SETFL, O_NONBLOCK | fcntl(sigchild_pipe[1], F_GETFL));
|
||||||
sn_pipe_valid = 1;
|
sigchild_pipe_valid = 1;
|
||||||
struct sigaction act = {.sa_handler = sigchld_handler, .sa_flags = SA_NOCLDWAIT | SA_RESTART};
|
struct sigaction act = {.sa_handler = sigchld_handler, .sa_flags = SA_RESTART};
|
||||||
if (sigaction(SIGCHLD, &act, 0)) {
|
if (sigaction(SIGCHLD, &act, 0)) {
|
||||||
perror("sigaction");
|
perror("sigaction");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // HAVE_SN
|
|
||||||
|
|
||||||
imlib_context_set_display(server.display);
|
imlib_context_set_display(server.display);
|
||||||
imlib_context_set_visual(server.visual);
|
imlib_context_set_visual(server.visual);
|
||||||
@@ -543,15 +542,11 @@ void cleanup()
|
|||||||
XCloseDisplay(server.display);
|
XCloseDisplay(server.display);
|
||||||
server.display = NULL;
|
server.display = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_SN
|
if (sigchild_pipe_valid) {
|
||||||
if (startup_notifications) {
|
sigchild_pipe_valid = FALSE;
|
||||||
if (sn_pipe_valid) {
|
close(sigchild_pipe[1]);
|
||||||
sn_pipe_valid = 0;
|
close(sigchild_pipe[0]);
|
||||||
close(sn_pipe[1]);
|
|
||||||
close(sn_pipe[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
uevent_cleanup();
|
uevent_cleanup();
|
||||||
}
|
}
|
||||||
@@ -1015,7 +1010,7 @@ void event_property_notify(XEvent *e)
|
|||||||
int old_desktop = server.desktop;
|
int old_desktop = server.desktop;
|
||||||
server_get_number_of_desktops();
|
server_get_number_of_desktops();
|
||||||
server.desktop = get_current_desktop();
|
server.desktop = get_current_desktop();
|
||||||
if (old_num_desktops != server.num_desktops) {
|
if (old_num_desktops != server.num_desktops) { // If number of desktop changed
|
||||||
if (server.num_desktops <= server.desktop) {
|
if (server.num_desktops <= server.desktop) {
|
||||||
server.desktop = server.num_desktops - 1;
|
server.desktop = server.num_desktops - 1;
|
||||||
}
|
}
|
||||||
@@ -1024,11 +1019,11 @@ void event_property_notify(XEvent *e)
|
|||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
init_taskbar_panel(&panels[i]);
|
init_taskbar_panel(&panels[i]);
|
||||||
set_panel_items_order(&panels[i]);
|
set_panel_items_order(&panels[i]);
|
||||||
update_taskbar_visibility(&panels[i]);
|
|
||||||
panels[i].area.resize_needed = 1;
|
panels[i].area.resize_needed = 1;
|
||||||
}
|
}
|
||||||
taskbar_refresh_tasklist();
|
taskbar_refresh_tasklist();
|
||||||
reset_active_task();
|
reset_active_task();
|
||||||
|
update_all_taskbars_visibility();
|
||||||
panel_refresh = TRUE;
|
panel_refresh = TRUE;
|
||||||
} else if (old_desktop != server.desktop) {
|
} else if (old_desktop != server.desktop) {
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
@@ -1097,6 +1092,7 @@ void event_property_notify(XEvent *e)
|
|||||||
if (debug)
|
if (debug)
|
||||||
fprintf(stderr, "%s %d: win = root, atom = _NET_CLIENT_LIST\n", __FUNCTION__, __LINE__);
|
fprintf(stderr, "%s %d: win = root, atom = _NET_CLIENT_LIST\n", __FUNCTION__, __LINE__);
|
||||||
taskbar_refresh_tasklist();
|
taskbar_refresh_tasklist();
|
||||||
|
update_all_taskbars_visibility();
|
||||||
panel_refresh = TRUE;
|
panel_refresh = TRUE;
|
||||||
}
|
}
|
||||||
// Change active
|
// Change active
|
||||||
@@ -1208,6 +1204,8 @@ void event_property_notify(XEvent *e)
|
|||||||
add_urgent(task);
|
add_urgent(task);
|
||||||
}
|
}
|
||||||
XFree(wmhints);
|
XFree(wmhints);
|
||||||
|
task_update_icon(task);
|
||||||
|
panel_refresh = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!server.got_root_win)
|
if (!server.got_root_win)
|
||||||
@@ -1641,9 +1639,9 @@ start:
|
|||||||
FD_ZERO(&fdset);
|
FD_ZERO(&fdset);
|
||||||
FD_SET(x11_fd, &fdset);
|
FD_SET(x11_fd, &fdset);
|
||||||
int maxfd = x11_fd;
|
int maxfd = x11_fd;
|
||||||
if (sn_pipe_valid) {
|
if (sigchild_pipe_valid) {
|
||||||
FD_SET(sn_pipe[0], &fdset);
|
FD_SET(sigchild_pipe[0], &fdset);
|
||||||
maxfd = maxfd < sn_pipe[0] ? sn_pipe[0] : maxfd;
|
maxfd = maxfd < sigchild_pipe[0] ? sigchild_pipe[0] : maxfd;
|
||||||
}
|
}
|
||||||
for (GList *l = panel_config.execp_list; l; l = l->next) {
|
for (GList *l = panel_config.execp_list; l; l = l->next) {
|
||||||
Execp *execp = (Execp *)l->data;
|
Execp *execp = (Execp *)l->data;
|
||||||
@@ -1664,9 +1662,9 @@ start:
|
|||||||
if (XPending(server.display) > 0 || select(maxfd + 1, &fdset, 0, 0, select_timeout) >= 0) {
|
if (XPending(server.display) > 0 || select(maxfd + 1, &fdset, 0, 0, select_timeout) >= 0) {
|
||||||
uevent_handler();
|
uevent_handler();
|
||||||
|
|
||||||
if (sn_pipe_valid) {
|
if (sigchild_pipe_valid) {
|
||||||
char buffer[1];
|
char buffer[1];
|
||||||
while (read(sn_pipe[0], buffer, sizeof(buffer)) > 0) {
|
while (read(sigchild_pipe[0], buffer, sizeof(buffer)) > 0) {
|
||||||
sigchld_handler_async();
|
sigchld_handler_async();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1133,12 +1133,6 @@ msgstr "Prebaci"
|
|||||||
msgid "Iconify"
|
msgid "Iconify"
|
||||||
msgstr "Umanji"
|
msgstr "Umanji"
|
||||||
|
|
||||||
#: ../properties.c:3434 ../properties.c:3470 ../properties.c:3542
|
|
||||||
#: ../properties.c:3578
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Shade"
|
|
||||||
msgstr "Zatamni"
|
|
||||||
|
|
||||||
#: ../properties.c:3435 ../properties.c:3471 ../properties.c:3507
|
#: ../properties.c:3435 ../properties.c:3471 ../properties.c:3507
|
||||||
#: ../properties.c:3543 ../properties.c:3579
|
#: ../properties.c:3543 ../properties.c:3579
|
||||||
msgid "Toggle or iconify"
|
msgid "Toggle or iconify"
|
||||||
@@ -1233,9 +1227,8 @@ msgid "Middle click"
|
|||||||
msgstr "Srednji klik"
|
msgstr "Srednji klik"
|
||||||
|
|
||||||
#: ../properties.c:3506
|
#: ../properties.c:3506
|
||||||
#, fuzzy
|
msgid "Shade"
|
||||||
msgid "sShade"
|
msgstr "Zatamni"
|
||||||
msgstr "zZatamni"
|
|
||||||
|
|
||||||
#: ../properties.c:3514
|
#: ../properties.c:3514
|
||||||
msgid "Specifies the action performed when task buttons receive a middle "
|
msgid "Specifies the action performed when task buttons receive a middle "
|
||||||
|
|||||||
@@ -1257,10 +1257,6 @@ msgstr "Spécifie l'action à engager lorsque les boutons de tâches reçoivent
|
|||||||
msgid "Middle click"
|
msgid "Middle click"
|
||||||
msgstr "Clic milieu"
|
msgstr "Clic milieu"
|
||||||
|
|
||||||
#: ../properties.c:3506
|
|
||||||
msgid "sShade"
|
|
||||||
msgstr "Réduire"
|
|
||||||
|
|
||||||
#: ../properties.c:3514
|
#: ../properties.c:3514
|
||||||
msgid "Specifies the action performed when task buttons receive a middle "
|
msgid "Specifies the action performed when task buttons receive a middle "
|
||||||
"click event: \n"
|
"click event: \n"
|
||||||
|
|||||||
@@ -1232,11 +1232,6 @@ msgstr "Određuje akciju nakon pomijeranja kolutića miša gore na zadatku: \n"
|
|||||||
msgid "Middle click"
|
msgid "Middle click"
|
||||||
msgstr "Srednji klik"
|
msgstr "Srednji klik"
|
||||||
|
|
||||||
#: ../properties.c:3506
|
|
||||||
#, fuzzy
|
|
||||||
msgid "sShade"
|
|
||||||
msgstr "zZatamni"
|
|
||||||
|
|
||||||
#: ../properties.c:3514
|
#: ../properties.c:3514
|
||||||
msgid "Specifies the action performed when task buttons receive a middle "
|
msgid "Specifies the action performed when task buttons receive a middle "
|
||||||
"click event: \n"
|
"click event: \n"
|
||||||
|
|||||||
@@ -1248,10 +1248,6 @@ msgstr "Określa akcję, która zostanie wykonana po poruszeniu kółka myszy w
|
|||||||
msgid "Middle click"
|
msgid "Middle click"
|
||||||
msgstr "Klik środkowym"
|
msgstr "Klik środkowym"
|
||||||
|
|
||||||
#: ../properties.c:3506
|
|
||||||
msgid "sShade"
|
|
||||||
msgstr "Zwiń"
|
|
||||||
|
|
||||||
#: ../properties.c:3514
|
#: ../properties.c:3514
|
||||||
msgid "Specifies the action performed when task buttons receive a middle "
|
msgid "Specifies the action performed when task buttons receive a middle "
|
||||||
"click event: \n"
|
"click event: \n"
|
||||||
|
|||||||
@@ -1220,10 +1220,6 @@ msgstr "Задает действие, выполняемое когда кно
|
|||||||
msgid "Middle click"
|
msgid "Middle click"
|
||||||
msgstr "Средний щелчок"
|
msgstr "Средний щелчок"
|
||||||
|
|
||||||
#: ../properties.c:3506
|
|
||||||
msgid "sShade"
|
|
||||||
msgstr "Скрутить"
|
|
||||||
|
|
||||||
#: ../properties.c:3514
|
#: ../properties.c:3514
|
||||||
msgid "Specifies the action performed when task buttons receive a middle "
|
msgid "Specifies the action performed when task buttons receive a middle "
|
||||||
"click event: \n"
|
"click event: \n"
|
||||||
|
|||||||
@@ -1133,7 +1133,6 @@ msgstr "Умањи"
|
|||||||
|
|
||||||
#: ../properties.c:3434 ../properties.c:3470 ../properties.c:3542
|
#: ../properties.c:3434 ../properties.c:3470 ../properties.c:3542
|
||||||
#: ../properties.c:3578
|
#: ../properties.c:3578
|
||||||
#, fuzzy
|
|
||||||
msgid "Shade"
|
msgid "Shade"
|
||||||
msgstr "Затамни"
|
msgstr "Затамни"
|
||||||
|
|
||||||
@@ -1230,11 +1229,6 @@ msgstr "Одређује акцију након померања колути
|
|||||||
msgid "Middle click"
|
msgid "Middle click"
|
||||||
msgstr "Средњи клик"
|
msgstr "Средњи клик"
|
||||||
|
|
||||||
#: ../properties.c:3506
|
|
||||||
#, fuzzy
|
|
||||||
msgid "sShade"
|
|
||||||
msgstr "зЗатамни"
|
|
||||||
|
|
||||||
#: ../properties.c:3514
|
#: ../properties.c:3514
|
||||||
msgid "Specifies the action performed when task buttons receive a middle "
|
msgid "Specifies the action performed when task buttons receive a middle "
|
||||||
"click event: \n"
|
"click event: \n"
|
||||||
|
|||||||
@@ -1148,7 +1148,7 @@ msgid "Middle click"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../properties.c:3506
|
#: ../properties.c:3506
|
||||||
msgid "sShade"
|
msgid "Shade"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../properties.c:3514
|
#: ../properties.c:3514
|
||||||
|
|||||||
@@ -3503,7 +3503,7 @@ void create_task(GtkWidget *parent)
|
|||||||
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Close"));
|
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Close"));
|
||||||
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Toggle"));
|
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Toggle"));
|
||||||
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Iconify"));
|
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Iconify"));
|
||||||
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("sShade"));
|
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Shade"));
|
||||||
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Toggle or iconify"));
|
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Toggle or iconify"));
|
||||||
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Maximize or restore"));
|
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Maximize or restore"));
|
||||||
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Desktop left"));
|
gtk_combo_box_append_text(GTK_COMBO_BOX(task_mouse_middle), _("Desktop left"));
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ void load_cache(Cache *cache, const gchar *cache_path)
|
|||||||
|
|
||||||
if (parse_line(line, &key, &value)) {
|
if (parse_line(line, &key, &value)) {
|
||||||
g_hash_table_insert(cache->_table, g_strdup(key), g_strdup(value));
|
g_hash_table_insert(cache->_table, g_strdup(key), g_strdup(value));
|
||||||
|
free(key);
|
||||||
|
free(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(line);
|
free(line);
|
||||||
|
|||||||
@@ -73,15 +73,15 @@ void copy_file(const char *path_src, const char *path_dest)
|
|||||||
fclose(file_src);
|
fclose(file_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_line(const char *line, char **key, char **value)
|
gboolean parse_line(const char *line, char **key, char **value)
|
||||||
{
|
{
|
||||||
char *a, *b;
|
char *a, *b;
|
||||||
|
|
||||||
/* Skip useless lines */
|
/* Skip useless lines */
|
||||||
if ((line[0] == '#') || (line[0] == '\n'))
|
if ((line[0] == '#') || (line[0] == '\n'))
|
||||||
return 0;
|
return FALSE;
|
||||||
if (!(a = strchr(line, '=')))
|
if (!(a = strchr(line, '=')))
|
||||||
return 0;
|
return FALSE;
|
||||||
|
|
||||||
/* overwrite '=' with '\0' */
|
/* overwrite '=' with '\0' */
|
||||||
a[0] = '\0';
|
a[0] = '\0';
|
||||||
@@ -96,7 +96,7 @@ int parse_line(const char *line, char **key, char **value)
|
|||||||
|
|
||||||
g_strstrip(*key);
|
g_strstrip(*key);
|
||||||
g_strstrip(*value);
|
g_strstrip(*value);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tint_exec(const char *command)
|
void tint_exec(const char *command)
|
||||||
@@ -673,3 +673,13 @@ GSList *slist_remove_duplicates(GSList *list, GCompareFunc eq, GDestroyNotify fr
|
|||||||
|
|
||||||
return new_list;
|
return new_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gint cmp_ptr(gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
if (a < b)
|
||||||
|
return -1;
|
||||||
|
else if (a == b)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ void copy_file(const char *path_src, const char *path_dest);
|
|||||||
// Strips key and value.
|
// Strips key and value.
|
||||||
// Values may contain spaces and the equal sign.
|
// Values may contain spaces and the equal sign.
|
||||||
// Returns 1 if both key and value could be read, zero otherwise.
|
// Returns 1 if both key and value could be read, zero otherwise.
|
||||||
int parse_line(const char *line, char **key, char **value);
|
gboolean parse_line(const char *line, char **key, char **value);
|
||||||
|
|
||||||
void extract_values(const char *value, char **value1, char **value2, char **value3);
|
void extract_values(const char *value, char **value1, char **value2, char **value3);
|
||||||
|
|
||||||
@@ -120,6 +120,9 @@ GSList *load_locations_from_env(GSList *locations, const char *var, ...);
|
|||||||
|
|
||||||
GSList *slist_remove_duplicates(GSList *list, GCompareFunc eq, GDestroyNotify fr);
|
GSList *slist_remove_duplicates(GSList *list, GCompareFunc eq, GDestroyNotify fr);
|
||||||
|
|
||||||
|
// A trivial pointer comparator.
|
||||||
|
gint cmp_ptr(gconstpointer a, gconstpointer b);
|
||||||
|
|
||||||
#define free_and_null(p) \
|
#define free_and_null(p) \
|
||||||
{ \
|
{ \
|
||||||
free(p); \
|
free(p); \
|
||||||
|
|||||||
Reference in New Issue
Block a user