Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4e1ceec38 |
@@ -11,8 +11,6 @@
|
|||||||
- Experimental, testing/feedback needed
|
- Experimental, testing/feedback needed
|
||||||
- Icons (system tray, task buttons, launcher):
|
- Icons (system tray, task buttons, launcher):
|
||||||
- Changed rendering method to fix icon corruptions (please report any problems)
|
- Changed rendering method to fix icon corruptions (please report any problems)
|
||||||
- System tray:
|
|
||||||
- Workaround for misbehaving applications leaving empty tray icons
|
|
||||||
- Many bugfixes
|
- Many bugfixes
|
||||||
- New config options (see https://gitlab.com/o9000/tint2/wikis/Configure):
|
- New config options (see https://gitlab.com/o9000/tint2/wikis/Configure):
|
||||||
- Panel:
|
- Panel:
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -1,14 +1,14 @@
|
|||||||
### New unstable release: 0.12-rc4
|
### New unstable release: 0.12-rc3
|
||||||
Changes: https://gitlab.com/o9000/tint2/blob/master/ChangeLog
|
Changes: https://gitlab.com/o9000/tint2/blob/master/ChangeLog
|
||||||
|
|
||||||
Documentation: https://gitlab.com/o9000/tint2/wikis/home
|
Documentation: https://gitlab.com/o9000/tint2/wikis/home
|
||||||
|
|
||||||
Try it out with (see also [dependencies](https://gitlab.com/o9000/tint2/wikis/Install#dependencies)):
|
Try it out with (see also [dependencies](https://gitlab.com/o9000/tint2/wikis/Install#dependencies)):
|
||||||
```
|
```
|
||||||
mkdir tint2-0.12-rc4
|
mkdir tint2-0.12-rc3
|
||||||
cd tint2-0.12-rc4
|
cd tint2-0.12-rc3
|
||||||
wget 'https://gitlab.com/o9000/tint2/repository/archive.tar.gz?ref=v0.12-rc4' --output-document tint2-0.12-rc4.tar.gz
|
wget 'https://gitlab.com/o9000/tint2/repository/archive.tar.gz?ref=v0.12-rc3' --output-document tint2-0.12-rc3.tar.gz
|
||||||
tar -xzf tint2-0.12-rc4.tar.gz
|
tar -xzf tint2-0.12-rc3.tar.gz
|
||||||
cd tint2.git
|
cd tint2.git
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
|
|||||||
@@ -76,9 +76,6 @@ void update_battery_tick(void* arg)
|
|||||||
int16_t old_hours = battery_state.time.hours;
|
int16_t old_hours = battery_state.time.hours;
|
||||||
int8_t old_minutes = battery_state.time.minutes;
|
int8_t old_minutes = battery_state.time.minutes;
|
||||||
|
|
||||||
if (!battery_found) {
|
|
||||||
init_battery();
|
|
||||||
}
|
|
||||||
if (update_battery() != 0) {
|
if (update_battery() != 0) {
|
||||||
// Reconfigure
|
// Reconfigure
|
||||||
init_battery();
|
init_battery();
|
||||||
@@ -106,23 +103,15 @@ void update_battery_tick(void* arg)
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nb_panel; i++) {
|
for (i = 0; i < nb_panel; i++) {
|
||||||
if (!battery_found) {
|
if (!battery_found && panel1[i].battery.area.on_screen == 1) {
|
||||||
if (panel1[i].battery.area.on_screen == 1) {
|
hide(&panel1[i].battery.area);
|
||||||
hide(&panel1[i].battery.area);
|
panel_refresh = 1;
|
||||||
panel_refresh = 1;
|
} else if (battery_state.percentage >= percentage_hide && panel1[i].battery.area.on_screen == 1) {
|
||||||
}
|
hide(&panel1[i].battery.area);
|
||||||
} else {
|
panel_refresh = 1;
|
||||||
if (battery_state.percentage >= percentage_hide) {
|
} else if (battery_state.percentage < percentage_hide && panel1[i].battery.area.on_screen == 0) {
|
||||||
if (panel1[i].battery.area.on_screen == 1) {
|
show(&panel1[i].battery.area);
|
||||||
hide(&panel1[i].battery.area);
|
panel_refresh = 1;
|
||||||
panel_refresh = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (panel1[i].battery.area.on_screen == 0) {
|
|
||||||
show(&panel1[i].battery.area);
|
|
||||||
panel_refresh = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (panel1[i].battery.area.on_screen == 1) {
|
if (panel1[i].battery.area.on_screen == 1) {
|
||||||
panel1[i].battery.area.resize = 1;
|
panel1[i].battery.area.resize = 1;
|
||||||
@@ -290,7 +279,7 @@ void init_battery()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!battery_timeout)
|
if (!battery_timeout)
|
||||||
battery_timeout = add_timeout(10, 30000, update_battery_tick, 0, &battery_timeout);
|
battery_timeout = add_timeout(10, 10000, update_battery_tick, 0, &battery_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -485,7 +474,7 @@ int update_battery() {
|
|||||||
battery_state.time.seconds = seconds;
|
battery_state.time.seconds = seconds;
|
||||||
|
|
||||||
if (energy_full > 0)
|
if (energy_full > 0)
|
||||||
new_percentage = 0.5 + ((energy_now <= energy_full ? energy_now : energy_full) * 100.0) / energy_full;
|
new_percentage = ((energy_now <= energy_full ? energy_now : energy_full) * 100) / energy_full;
|
||||||
|
|
||||||
battery_state.percentage = new_percentage;
|
battery_state.percentage = new_percentage;
|
||||||
|
|
||||||
|
|||||||
@@ -613,13 +613,13 @@ void add_entry (char *key, char *value)
|
|||||||
}
|
}
|
||||||
else if (strcmp(key, "systray_sort") == 0) {
|
else if (strcmp(key, "systray_sort") == 0) {
|
||||||
if (strcmp(value, "descending") == 0)
|
if (strcmp(value, "descending") == 0)
|
||||||
systray.sort = SYSTRAY_SORT_DESCENDING;
|
systray.sort = -1;
|
||||||
else if (strcmp(value, "ascending") == 0)
|
else if (strcmp(value, "ascending") == 0)
|
||||||
systray.sort = SYSTRAY_SORT_ASCENDING;
|
systray.sort = 1;
|
||||||
else if (strcmp(value, "left2right") == 0)
|
else if (strcmp(value, "left2right") == 0)
|
||||||
systray.sort = SYSTRAY_SORT_LEFT2RIGHT;
|
systray.sort = 2;
|
||||||
else if (strcmp(value, "right2left") == 0)
|
else if (strcmp(value, "right2left") == 0)
|
||||||
systray.sort = SYSTRAY_SORT_RIGHT2LEFT;
|
systray.sort = 3;
|
||||||
}
|
}
|
||||||
else if (strcmp(key, "systray_icon_size") == 0) {
|
else if (strcmp(key, "systray_icon_size") == 0) {
|
||||||
systray_max_icon_size = atoi(value);
|
systray_max_icon_size = atoi(value);
|
||||||
|
|||||||
@@ -536,9 +536,6 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
|||||||
char *next_larger = NULL;
|
char *next_larger = NULL;
|
||||||
GSList *next_larger_theme = NULL;
|
GSList *next_larger_theme = NULL;
|
||||||
|
|
||||||
int file_name_size = 4096;
|
|
||||||
char *file_name = calloc(file_name_size, 1);
|
|
||||||
|
|
||||||
for (theme = themes; theme; theme = g_slist_next(theme)) {
|
for (theme = themes; theme; theme = g_slist_next(theme)) {
|
||||||
((IconTheme*)theme->data)->list_directories = g_slist_sort_with_data(((IconTheme*)theme->data)->list_directories,
|
((IconTheme*)theme->data)->list_directories = g_slist_sort_with_data(((IconTheme*)theme->data)->list_directories,
|
||||||
compare_theme_directories,
|
compare_theme_directories,
|
||||||
@@ -563,13 +560,8 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
|||||||
char *theme_name = ((IconTheme*)theme->data)->name;
|
char *theme_name = ((IconTheme*)theme->data)->name;
|
||||||
char *dir_name = ((IconThemeDir*)dir->data)->name;
|
char *dir_name = ((IconThemeDir*)dir->data)->name;
|
||||||
char *extension = (char*) ext->data;
|
char *extension = (char*) ext->data;
|
||||||
if (strlen(base_name) + strlen(theme_name) +
|
char *file_name = calloc(strlen(base_name) + strlen(theme_name) +
|
||||||
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100 > file_name_size) {
|
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100, 1);
|
||||||
file_name_size = strlen(base_name) + strlen(theme_name) +
|
|
||||||
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100;
|
|
||||||
file_name = realloc(file_name, file_name_size);
|
|
||||||
}
|
|
||||||
file_name[0] = 0;
|
|
||||||
// filename = directory/$(themename)/subdirectory/iconname.extension
|
// filename = directory/$(themename)/subdirectory/iconname.extension
|
||||||
sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension);
|
sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension);
|
||||||
if (DEBUG_ICON_SEARCH)
|
if (DEBUG_ICON_SEARCH)
|
||||||
@@ -604,12 +596,11 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
|||||||
printf("next_larger = %s; next_larger_size = %d\n", next_larger, next_larger_size);
|
printf("next_larger = %s; next_larger_size = %d\n", next_larger, next_larger_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(file_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(file_name);
|
|
||||||
file_name = NULL;
|
|
||||||
if (next_larger) {
|
if (next_larger) {
|
||||||
g_slist_free(extensions);
|
g_slist_free(extensions);
|
||||||
free(best_file_name);
|
free(best_file_name);
|
||||||
|
|||||||
@@ -31,8 +31,6 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_RSVG
|
#ifdef HAVE_RSVG
|
||||||
#include <librsvg/rsvg.h>
|
#include <librsvg/rsvg.h>
|
||||||
@@ -152,7 +150,8 @@ void cleanup_launcher_theme(Launcher *launcher)
|
|||||||
for (l = launcher->list_icons; l ; l = l->next) {
|
for (l = launcher->list_icons; l ; l = l->next) {
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon*)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon*)l->data;
|
||||||
if (launcherIcon) {
|
if (launcherIcon) {
|
||||||
free_icon(launcherIcon->image);
|
free_icon(launcherIcon->icon_scaled);
|
||||||
|
free_icon(launcherIcon->icon_original);
|
||||||
free(launcherIcon->icon_name);
|
free(launcherIcon->icon_name);
|
||||||
free(launcherIcon->icon_path);
|
free(launcherIcon->icon_path);
|
||||||
free(launcherIcon->cmd);
|
free(launcherIcon->cmd);
|
||||||
@@ -187,7 +186,7 @@ int resize_launcher(void *obj)
|
|||||||
// Resize icons if necessary
|
// Resize icons if necessary
|
||||||
for (l = launcher->list_icons; l ; l = l->next) {
|
for (l = launcher->list_icons; l ; l = l->next) {
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
if (launcherIcon->icon_size != icon_size || !launcherIcon->image) {
|
if (launcherIcon->icon_size != icon_size || !launcherIcon->icon_original) {
|
||||||
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;
|
||||||
@@ -196,69 +195,69 @@ int resize_launcher(void *obj)
|
|||||||
char *new_icon_path = get_icon_path(launcher->list_themes, launcherIcon->icon_name, launcherIcon->icon_size);
|
char *new_icon_path = get_icon_path(launcher->list_themes, launcherIcon->icon_name, launcherIcon->icon_size);
|
||||||
if (!new_icon_path) {
|
if (!new_icon_path) {
|
||||||
// Draw a blank icon
|
// Draw a blank icon
|
||||||
free_icon(launcherIcon->image);
|
free_icon(launcherIcon->icon_original);
|
||||||
launcherIcon->image = NULL;
|
launcherIcon->icon_original = NULL;
|
||||||
|
free_icon(launcherIcon->icon_scaled);
|
||||||
|
launcherIcon->icon_scaled = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (launcherIcon->icon_path && strcmp(new_icon_path, launcherIcon->icon_path) == 0) {
|
||||||
// Free the old files
|
// If it's the same file just rescale
|
||||||
free_icon(launcherIcon->image);
|
free_icon(launcherIcon->icon_scaled);
|
||||||
launcherIcon->image = NULL;
|
launcherIcon->icon_scaled = scale_icon(launcherIcon->icon_original, icon_size);
|
||||||
// Load the new file and scale
|
free(new_icon_path);
|
||||||
launcherIcon->image = imlib_load_image_immediately(new_icon_path);
|
fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);
|
||||||
|
} else {
|
||||||
|
// Free the old files
|
||||||
|
free_icon(launcherIcon->icon_original);
|
||||||
|
free_icon(launcherIcon->icon_scaled);
|
||||||
|
launcherIcon->icon_original = launcherIcon->icon_scaled = NULL;
|
||||||
|
// Load the new file and scale
|
||||||
|
launcherIcon->icon_original = imlib_load_image_immediately(new_icon_path);
|
||||||
#ifdef HAVE_RSVG
|
#ifdef HAVE_RSVG
|
||||||
if (!launcherIcon->image && g_str_has_suffix(new_icon_path, ".svg")) {
|
if (!launcherIcon->icon_original && g_str_has_suffix(new_icon_path, ".svg")) {
|
||||||
char suffix[128];
|
|
||||||
sprintf(suffix, "tmpicon-%d.png", getpid());
|
|
||||||
// We fork here because librsvg allocates memory like crazy
|
|
||||||
pid_t pid = fork();
|
|
||||||
if (pid == 0) {
|
|
||||||
// Child
|
|
||||||
GError* err = NULL;
|
GError* err = NULL;
|
||||||
RsvgHandle* svg = rsvg_handle_new_from_file(new_icon_path, &err);
|
RsvgHandle* svg = rsvg_handle_new_from_file(new_icon_path, &err);
|
||||||
|
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
fprintf(stderr, "Could not load svg image!: %s", err->message);
|
fprintf(stderr, "Could not load svg image!: %s", err->message);
|
||||||
g_error_free(err);
|
g_error_free(err);
|
||||||
launcherIcon->image = NULL;
|
launcherIcon->icon_original = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
char suffix[128];
|
||||||
|
sprintf(suffix, "tmpicon-%d.png", getpid());
|
||||||
gchar *name = g_build_filename(g_get_user_config_dir(), "tint2", suffix, NULL);
|
gchar *name = g_build_filename(g_get_user_config_dir(), "tint2", suffix, NULL);
|
||||||
GdkPixbuf *pixbuf = rsvg_handle_get_pixbuf(svg);
|
GdkPixbuf *pixbuf = rsvg_handle_get_pixbuf(svg);
|
||||||
gdk_pixbuf_save(pixbuf, name, "png", NULL, NULL);
|
gdk_pixbuf_save(pixbuf, name, "png", NULL, NULL);
|
||||||
|
launcherIcon->icon_original = imlib_load_image_immediately_without_cache(name);
|
||||||
|
g_remove(name);
|
||||||
|
g_free(name);
|
||||||
|
g_object_unref(G_OBJECT(pixbuf));
|
||||||
|
g_object_unref(G_OBJECT(svg));
|
||||||
}
|
}
|
||||||
exit(0);
|
} else
|
||||||
} else {
|
|
||||||
// Parent
|
|
||||||
waitpid(pid, 0, 0);
|
|
||||||
gchar *name = g_build_filename(g_get_user_config_dir(), "tint2", suffix, NULL);
|
|
||||||
launcherIcon->image = imlib_load_image_immediately_without_cache(name);
|
|
||||||
g_remove(name);
|
|
||||||
g_free(name);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
launcherIcon->image = imlib_load_image_immediately(new_icon_path);
|
launcherIcon->icon_original = imlib_load_image_immediately(new_icon_path);
|
||||||
}
|
}
|
||||||
// On loading error, fallback to default
|
// On loading error, fallback to default
|
||||||
if (!launcherIcon->image) {
|
if (!launcherIcon->icon_original) {
|
||||||
free(new_icon_path);
|
free(new_icon_path);
|
||||||
new_icon_path = get_icon_path(launcher->list_themes, DEFAULT_ICON, launcherIcon->icon_size);
|
new_icon_path = get_icon_path(launcher->list_themes, DEFAULT_ICON, launcherIcon->icon_size);
|
||||||
if (new_icon_path)
|
if (new_icon_path)
|
||||||
launcherIcon->image = imlib_load_image_immediately(new_icon_path);
|
launcherIcon->icon_original = imlib_load_image_immediately(new_icon_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!launcherIcon->image) {
|
if (!launcherIcon->icon_original) {
|
||||||
// Loading default icon failed, draw a blank icon
|
// Loading default icon failed, draw a blank icon
|
||||||
free(new_icon_path);
|
free(new_icon_path);
|
||||||
} else {
|
} else {
|
||||||
// Loaded icon successfully
|
// Loaded icon successfully
|
||||||
Imlib_Image original = launcherIcon->image;
|
launcherIcon->icon_scaled = scale_icon(launcherIcon->icon_original, launcherIcon->icon_size);
|
||||||
launcherIcon->image = scale_icon(launcherIcon->image, launcherIcon->icon_size);
|
free(launcherIcon->icon_path);
|
||||||
free_icon(original);
|
launcherIcon->icon_path = new_icon_path;
|
||||||
free(launcherIcon->icon_path);
|
fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);
|
||||||
launcherIcon->icon_path = new_icon_path;
|
}
|
||||||
fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,7 +331,6 @@ int resize_launcher(void *obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,8 +355,9 @@ void draw_launcher_icon(void *obj, cairo_t *c)
|
|||||||
{
|
{
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon*)obj;
|
LauncherIcon *launcherIcon = (LauncherIcon*)obj;
|
||||||
|
|
||||||
|
Imlib_Image icon_scaled = launcherIcon->icon_scaled;
|
||||||
// Render
|
// Render
|
||||||
imlib_context_set_image(launcherIcon->image);
|
imlib_context_set_image(icon_scaled);
|
||||||
if (server.real_transparency) {
|
if (server.real_transparency) {
|
||||||
render_image(launcherIcon->area.pix, 0, 0);
|
render_image(launcherIcon->area.pix, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ typedef struct Launcher {
|
|||||||
typedef struct LauncherIcon {
|
typedef struct LauncherIcon {
|
||||||
// always start with area
|
// always start with area
|
||||||
Area area;
|
Area area;
|
||||||
Imlib_Image image;
|
Imlib_Image icon_scaled;
|
||||||
|
Imlib_Image icon_original;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
char *icon_name;
|
char *icon_name;
|
||||||
char *icon_path;
|
char *icon_path;
|
||||||
|
|||||||
10
src/panel.c
10
src/panel.c
@@ -505,6 +505,16 @@ void set_panel_items_order(Panel *p)
|
|||||||
}
|
}
|
||||||
if (panel_items_order[k] == 'C')
|
if (panel_items_order[k] == 'C')
|
||||||
p->area.list = g_slist_append(p->area.list, &p->clock);
|
p->area.list = g_slist_append(p->area.list, &p->clock);
|
||||||
|
if (panel_items_order[k] == 'F') {
|
||||||
|
Area *spacer = calloc(sizeof(Area), 1);
|
||||||
|
spacer->panel = p;
|
||||||
|
spacer->parent = p;
|
||||||
|
spacer->bg = &g_array_index(backgrounds, Background, 0);
|
||||||
|
spacer->on_screen = 1;
|
||||||
|
spacer->size_mode = SIZE_BY_LAYOUT;
|
||||||
|
spacer->gc = 1;
|
||||||
|
p->area.list = g_slist_append(p->area.list, spacer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
init_rendering(&p->area, 0);
|
init_rendering(&p->area, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ void server_init_atoms ()
|
|||||||
server.atom._NET_SYSTEM_TRAY_ORIENTATION = XInternAtom(server.dsp, "_NET_SYSTEM_TRAY_ORIENTATION", False);
|
server.atom._NET_SYSTEM_TRAY_ORIENTATION = XInternAtom(server.dsp, "_NET_SYSTEM_TRAY_ORIENTATION", False);
|
||||||
server.atom._XEMBED = XInternAtom(server.dsp, "_XEMBED", False);
|
server.atom._XEMBED = XInternAtom(server.dsp, "_XEMBED", False);
|
||||||
server.atom._XEMBED_INFO = XInternAtom(server.dsp, "_XEMBED_INFO", False);
|
server.atom._XEMBED_INFO = XInternAtom(server.dsp, "_XEMBED_INFO", False);
|
||||||
server.atom._NET_WM_PID = XInternAtom(server.dsp, "_NET_WM_PID", True);
|
|
||||||
|
|
||||||
// drag 'n' drop
|
// drag 'n' drop
|
||||||
server.atom.XdndAware = XInternAtom(server.dsp, "XdndAware", False);
|
server.atom.XdndAware = XInternAtom(server.dsp, "XdndAware", False);
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ typedef struct Global_atom
|
|||||||
Atom _NET_SYSTEM_TRAY_ORIENTATION;
|
Atom _NET_SYSTEM_TRAY_ORIENTATION;
|
||||||
Atom _XEMBED;
|
Atom _XEMBED;
|
||||||
Atom _XEMBED_INFO;
|
Atom _XEMBED_INFO;
|
||||||
Atom _NET_WM_PID;
|
|
||||||
Atom _XSETTINGS_SCREEN;
|
Atom _XSETTINGS_SCREEN;
|
||||||
Atom _XSETTINGS_SETTINGS;
|
Atom _XSETTINGS_SETTINGS;
|
||||||
Atom XdndAware;
|
Atom XdndAware;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ int refresh_systray;
|
|||||||
int systray_enabled;
|
int systray_enabled;
|
||||||
int systray_max_icon_size;
|
int systray_max_icon_size;
|
||||||
int systray_monitor;
|
int systray_monitor;
|
||||||
int chrono;
|
|
||||||
// background pixmap if we render ourselves the icons
|
// background pixmap if we render ourselves the icons
|
||||||
static Pixmap render_background;
|
static Pixmap render_background;
|
||||||
|
|
||||||
@@ -61,9 +61,8 @@ void default_systray()
|
|||||||
{
|
{
|
||||||
memset(&systray, 0, sizeof(Systraybar));
|
memset(&systray, 0, sizeof(Systraybar));
|
||||||
render_background = 0;
|
render_background = 0;
|
||||||
chrono = 0;
|
|
||||||
systray.alpha = 100;
|
systray.alpha = 100;
|
||||||
systray.sort = SYSTRAY_SORT_LEFT2RIGHT;
|
systray.sort = 3;
|
||||||
systray.area._draw_foreground = draw_systray;
|
systray.area._draw_foreground = draw_systray;
|
||||||
systray.area._on_change_layout = on_change_systray;
|
systray.area._on_change_layout = on_change_systray;
|
||||||
systray.area.size_mode = SIZE_BY_CONTENT;
|
systray.area.size_mode = SIZE_BY_CONTENT;
|
||||||
@@ -109,9 +108,8 @@ void init_systray_panel(void *p)
|
|||||||
GSList *l;
|
GSList *l;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (l = systray.list_icons; l ; l = l->next) {
|
for (l = systray.list_icons; l ; l = l->next) {
|
||||||
if (((TrayWindow*)l->data)->hide)
|
if (!((TrayWindow*)l->data)->hide)
|
||||||
continue;
|
count++;
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
hide(&systray.area);
|
hide(&systray.area);
|
||||||
@@ -148,9 +146,8 @@ int resize_systray(void *obj)
|
|||||||
sysbar->icon_size = systray_max_icon_size;
|
sysbar->icon_size = systray_max_icon_size;
|
||||||
count = 0;
|
count = 0;
|
||||||
for (l = systray.list_icons; l ; l = l->next) {
|
for (l = systray.list_icons; l ; l = l->next) {
|
||||||
if (((TrayWindow*)l->data)->hide)
|
if (!((TrayWindow*)l->data)->hide)
|
||||||
continue;
|
count++;
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
//printf("count %d\n", count);
|
//printf("count %d\n", count);
|
||||||
|
|
||||||
@@ -197,12 +194,11 @@ void on_change_systray (void *obj)
|
|||||||
GSList *l;
|
GSList *l;
|
||||||
for (i=1, l = systray.list_icons; l ; i++, l = l->next) {
|
for (i=1, l = systray.list_icons; l ; i++, l = l->next) {
|
||||||
traywin = (TrayWindow*)l->data;
|
traywin = (TrayWindow*)l->data;
|
||||||
if (traywin->hide)
|
if (traywin->hide) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
traywin->y = posy;
|
traywin->y = posy;
|
||||||
traywin->x = posx;
|
traywin->x = posx;
|
||||||
// printf("systray %d : pos %d, %d\n", traywin->tray_id, posx, posy);
|
//printf("systray %d : %d,%d\n", i, posx, posy);
|
||||||
traywin->width = sysbar->icon_size;
|
traywin->width = sysbar->icon_size;
|
||||||
traywin->height = sysbar->icon_size;
|
traywin->height = sysbar->icon_size;
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
@@ -340,39 +336,21 @@ static gint compare_traywindows(gconstpointer a, gconstpointer b)
|
|||||||
{
|
{
|
||||||
const TrayWindow * traywin_a = (TrayWindow*)a;
|
const TrayWindow * traywin_a = (TrayWindow*)a;
|
||||||
const TrayWindow * traywin_b = (TrayWindow*)b;
|
const TrayWindow * traywin_b = (TrayWindow*)b;
|
||||||
|
XTextProperty name_a, name_b;
|
||||||
|
|
||||||
if (traywin_a->empty && !traywin_b->empty)
|
if(XGetWMName(server.dsp, traywin_a->tray_id, &name_a) == 0) {
|
||||||
return 1;
|
|
||||||
if (!traywin_a->empty && traywin_b->empty)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (systray.sort == SYSTRAY_SORT_ASCENDING ||
|
|
||||||
systray.sort == SYSTRAY_SORT_DESCENDING) {
|
|
||||||
XTextProperty name_a, name_b;
|
|
||||||
|
|
||||||
if (XGetWMName(server.dsp, traywin_a->tray_id, &name_a) == 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (XGetWMName(server.dsp, traywin_b->tray_id, &name_b) == 0) {
|
|
||||||
XFree(name_a.value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
gint retval = g_ascii_strncasecmp((char*)name_a.value, (char*)name_b.value, -1) *
|
|
||||||
(systray.sort == SYSTRAY_SORT_ASCENDING ? 1 : -1);
|
|
||||||
XFree(name_a.value);
|
|
||||||
XFree(name_b.value);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if(XGetWMName(server.dsp, traywin_b->tray_id, &name_b) == 0) {
|
||||||
if (systray.sort == SYSTRAY_SORT_LEFT2RIGHT ||
|
XFree(name_a.value);
|
||||||
systray.sort == SYSTRAY_SORT_RIGHT2LEFT) {
|
return 1;
|
||||||
return (traywin_a->chrono - traywin_b->chrono) *
|
}
|
||||||
(systray.sort == SYSTRAY_SORT_LEFT2RIGHT ? 1 : -1);
|
else {
|
||||||
|
gint retval = g_ascii_strncasecmp((char*)name_a.value, (char*)name_b.value, -1) * systray.sort;
|
||||||
|
XFree(name_a.value);
|
||||||
|
XFree(name_b.value);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -383,42 +361,12 @@ gboolean add_icon(Window id)
|
|||||||
Panel *panel = systray.area.panel;
|
Panel *panel = systray.area.panel;
|
||||||
int hide = 0;
|
int hide = 0;
|
||||||
|
|
||||||
int pid = 0;
|
|
||||||
{
|
|
||||||
Atom actual_type;
|
|
||||||
int actual_format;
|
|
||||||
unsigned long nitems;
|
|
||||||
unsigned long bytes_after;
|
|
||||||
unsigned char *prop = 0;
|
|
||||||
int ret = XGetWindowProperty(server.dsp, id, server.atom._NET_WM_PID, 0, 1024, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop);
|
|
||||||
if (ret == Success && prop) {
|
|
||||||
pid = prop[1] * 256;
|
|
||||||
pid += prop[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GSList *l;
|
GSList *l;
|
||||||
int num_empty_same_pid = 0;
|
|
||||||
for (l = systray.list_icons; l; l = l->next) {
|
for (l = systray.list_icons; l; l = l->next) {
|
||||||
if (((TrayWindow*)l->data)->tray_id == id)
|
if (((TrayWindow*)l->data)->tray_id == id)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (pid && ((TrayWindow*)l->data)->pid == pid && ((TrayWindow*)l->data)->empty)
|
|
||||||
num_empty_same_pid++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int max_num_empty_same_pid = 0;
|
|
||||||
if (num_empty_same_pid > max_num_empty_same_pid) {
|
|
||||||
for (l = systray.list_icons; l; l = l->next) {
|
|
||||||
if (pid && ((TrayWindow*)l->data)->pid == pid && ((TrayWindow*)l->data)->empty) {
|
|
||||||
num_empty_same_pid++;
|
|
||||||
fprintf(stderr, "Removing tray icon %lu from misbehaving application with pid=%d\n", ((TrayWindow*)l->data)->tray_id, pid);
|
|
||||||
remove_icon((TrayWindow*)l->data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//printf("add_icon: %d, pid %d, %d\n", id, pid, num_empty_same_pid);
|
|
||||||
|
|
||||||
error = FALSE;
|
error = FALSE;
|
||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
if ( XGetWindowAttributes(server.dsp, id, &attr) == False ) return FALSE;
|
if ( XGetWindowAttributes(server.dsp, id, &attr) == False ) return FALSE;
|
||||||
@@ -497,19 +445,16 @@ gboolean add_icon(Window id)
|
|||||||
traywin->hide = hide;
|
traywin->hide = hide;
|
||||||
traywin->depth = attr.depth;
|
traywin->depth = attr.depth;
|
||||||
traywin->damage = 0;
|
traywin->damage = 0;
|
||||||
traywin->empty = 0;
|
|
||||||
traywin->pid = pid;
|
|
||||||
traywin->chrono = chrono;
|
|
||||||
chrono++;
|
|
||||||
|
|
||||||
if (systray.area.on_screen == 0)
|
if (systray.area.on_screen == 0)
|
||||||
show(&systray.area);
|
show(&systray.area);
|
||||||
|
|
||||||
if (systray.sort == SYSTRAY_SORT_RIGHT2LEFT)
|
if (systray.sort == 3)
|
||||||
systray.list_icons = g_slist_prepend(systray.list_icons, traywin);
|
systray.list_icons = g_slist_prepend(systray.list_icons, traywin);
|
||||||
else
|
else if (systray.sort == 2)
|
||||||
systray.list_icons = g_slist_append(systray.list_icons, traywin);
|
systray.list_icons = g_slist_append(systray.list_icons, traywin);
|
||||||
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
else
|
||||||
|
systray.list_icons = g_slist_insert_sorted(systray.list_icons, traywin, compare_traywindows);
|
||||||
//printf("add_icon id %lx, %d\n", id, g_slist_length(systray.list_icons));
|
//printf("add_icon id %lx, %d\n", id, g_slist_length(systray.list_icons));
|
||||||
|
|
||||||
if (FORCE_COMPOSITED_RENDERING || server.real_transparency || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0) {
|
if (FORCE_COMPOSITED_RENDERING || server.real_transparency || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0) {
|
||||||
@@ -536,7 +481,7 @@ void remove_icon(TrayWindow *traywin)
|
|||||||
|
|
||||||
// remove from our list
|
// remove from our list
|
||||||
systray.list_icons = g_slist_remove(systray.list_icons, traywin);
|
systray.list_icons = g_slist_remove(systray.list_icons, traywin);
|
||||||
//printf("remove_icon: %d\n", traywin->tray_id);
|
//printf("remove_icon id %lx, %d\n", traywin->id);
|
||||||
|
|
||||||
XSelectInput(server.dsp, traywin->tray_id, NoEventMask);
|
XSelectInput(server.dsp, traywin->tray_id, NoEventMask);
|
||||||
if (traywin->damage)
|
if (traywin->damage)
|
||||||
@@ -558,9 +503,8 @@ void remove_icon(TrayWindow *traywin)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
GSList *l;
|
GSList *l;
|
||||||
for (l = systray.list_icons; l; l = l->next) {
|
for (l = systray.list_icons; l; l = l->next) {
|
||||||
if (((TrayWindow*)l->data)->hide)
|
if (!((TrayWindow*)l->data)->hide)
|
||||||
continue;
|
count++;
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
hide(&systray.area);
|
hide(&systray.area);
|
||||||
@@ -602,7 +546,6 @@ void systray_render_icon_now(void* t)
|
|||||||
// we end up in this function only in real transparency mode or if systray_task_asb != 100 0 0
|
// we end up in this function only in real transparency mode or if systray_task_asb != 100 0 0
|
||||||
// we made also sure, that we always have a 32 bit visual, i.e. we can safely create 32 bit pixmaps here
|
// we made also sure, that we always have a 32 bit visual, i.e. we can safely create 32 bit pixmaps here
|
||||||
TrayWindow* traywin = t;
|
TrayWindow* traywin = t;
|
||||||
|
|
||||||
traywin->render_timeout = 0;
|
traywin->render_timeout = 0;
|
||||||
if ( traywin->width == 0 || traywin->height == 0 ) {
|
if ( traywin->width == 0 || traywin->height == 0 ) {
|
||||||
// reschedule rendering since the geometry information has not yet been processed (can happen on slow cpu)
|
// reschedule rendering since the geometry information has not yet been processed (can happen on slow cpu)
|
||||||
@@ -610,27 +553,6 @@ void systray_render_icon_now(void* t)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
XImage *ximage = XGetImage(server.dsp, traywin->tray_id, 0, 0, traywin->width, traywin->height, AllPlanes, XYPixmap);
|
|
||||||
XColor color;
|
|
||||||
int x, y, empty = 1;
|
|
||||||
for (x = 0; empty && x < traywin->width; x++) {
|
|
||||||
for (y = 0; empty && y < traywin->height; y++) {
|
|
||||||
color.pixel = XGetPixel(ximage, x, y);
|
|
||||||
if (color.pixel != 0)
|
|
||||||
empty = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
XFree(ximage);
|
|
||||||
if (traywin->empty != empty) {
|
|
||||||
traywin->empty = empty;
|
|
||||||
systray.area.resize = 1;
|
|
||||||
panel_refresh = 1;
|
|
||||||
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
|
||||||
}
|
|
||||||
//printf("systray_render_icon_now: %d empty %d\n", traywin->tray_id, empty);
|
|
||||||
if (empty)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// good systray icons support 32 bit depth, but some icons are still 24 bit.
|
// good systray icons support 32 bit depth, but some icons are still 24 bit.
|
||||||
// We create a heuristic mask for these icons, i.e. we get the rgb value in the top left corner, and
|
// We create a heuristic mask for these icons, i.e. we get the rgb value in the top left corner, and
|
||||||
// mask out all pixel with the same rgb value
|
// mask out all pixel with the same rgb value
|
||||||
@@ -714,8 +636,7 @@ void refresh_systray_icon()
|
|||||||
GSList *l;
|
GSList *l;
|
||||||
for (l = systray.list_icons; l ; l = l->next) {
|
for (l = systray.list_icons; l ; l = l->next) {
|
||||||
traywin = (TrayWindow*)l->data;
|
traywin = (TrayWindow*)l->data;
|
||||||
if (traywin->hide)
|
if (traywin->hide) continue;
|
||||||
continue;
|
|
||||||
systray_render_icon(traywin);
|
systray_render_icon(traywin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
// Flags for _XEMBED_INFO
|
// Flags for _XEMBED_INFO
|
||||||
#define XEMBED_MAPPED (1 << 0)
|
#define XEMBED_MAPPED (1 << 0)
|
||||||
|
|
||||||
enum { SYSTRAY_SORT_ASCENDING, SYSTRAY_SORT_DESCENDING, SYSTRAY_SORT_LEFT2RIGHT, SYSTRAY_SORT_RIGHT2LEFT };
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// always start with area
|
// always start with area
|
||||||
@@ -44,9 +43,6 @@ typedef struct
|
|||||||
int depth;
|
int depth;
|
||||||
Damage damage;
|
Damage damage;
|
||||||
timeout* render_timeout;
|
timeout* render_timeout;
|
||||||
int empty;
|
|
||||||
int pid;
|
|
||||||
int chrono;
|
|
||||||
} TrayWindow;
|
} TrayWindow;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,6 @@ Task *add_task (Window win)
|
|||||||
if (!win) return 0;
|
if (!win) return 0;
|
||||||
if (window_is_hidden(win)) return 0;
|
if (window_is_hidden(win)) return 0;
|
||||||
|
|
||||||
XSelectInput(server.dsp, win, PropertyChangeMask|StructureNotifyMask);
|
|
||||||
XFlush(server.dsp);
|
|
||||||
|
|
||||||
int monitor;
|
int monitor;
|
||||||
if (nb_panel > 1) {
|
if (nb_panel > 1) {
|
||||||
monitor = window_get_monitor (win);
|
monitor = window_get_monitor (win);
|
||||||
@@ -78,7 +75,8 @@ Task *add_task (Window win)
|
|||||||
get_title(&new_tsk);
|
get_title(&new_tsk);
|
||||||
get_icon(&new_tsk);
|
get_icon(&new_tsk);
|
||||||
|
|
||||||
//printf("new task %s win %u: desktop %d, monitor %d\n", new_tsk.title, win, new_tsk.desktop, monitor);
|
//printf("task %s : desktop %d, monitor %d\n", new_tsk->title, desktop, monitor);
|
||||||
|
XSelectInput (server.dsp, new_tsk.win, PropertyChangeMask|StructureNotifyMask);
|
||||||
|
|
||||||
GPtrArray* task_group = g_ptr_array_new();
|
GPtrArray* task_group = g_ptr_array_new();
|
||||||
Taskbar *tskbar;
|
Taskbar *tskbar;
|
||||||
|
|||||||
@@ -727,7 +727,6 @@ void event_property_notify (XEvent *e)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tsk = task_get_task (win);
|
tsk = task_get_task (win);
|
||||||
//printf("change win = %u, task = %p\n", win, tsk);
|
|
||||||
if (!tsk) {
|
if (!tsk) {
|
||||||
if (at != server.atom._NET_WM_STATE)
|
if (at != server.atom._NET_WM_STATE)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ int resize_by_layout(void *obj, int maximum_size)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// detect free size for SIZE_BY_LAYOUT's Area
|
// detect free size for SIZE_BY_LAYOUT's Area
|
||||||
|
// TODO the spacer should collapse when the other areas are overflowing
|
||||||
size = a->height - (2 * (a->paddingxlr + a->bg->border.width));
|
size = a->height - (2 * (a->paddingxlr + a->bg->border.width));
|
||||||
GSList *l;
|
GSList *l;
|
||||||
for (l = a->list ; l ; l = l->next) {
|
for (l = a->list ; l ; l = l->next) {
|
||||||
@@ -471,6 +472,8 @@ void free_area (Area *a)
|
|||||||
XFreePixmap (server.dsp, a->pix);
|
XFreePixmap (server.dsp, a->pix);
|
||||||
a->pix = 0;
|
a->pix = 0;
|
||||||
}
|
}
|
||||||
|
if (a->gc)
|
||||||
|
free(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ typedef struct {
|
|||||||
int resize;
|
int resize;
|
||||||
// need redraw Pixmap
|
// need redraw Pixmap
|
||||||
int redraw;
|
int redraw;
|
||||||
|
int gc;
|
||||||
// paddingxlr = horizontal padding left/right
|
// paddingxlr = horizontal padding left/right
|
||||||
// paddingx = horizontal padding between childs
|
// paddingx = horizontal padding between childs
|
||||||
int paddingxlr, paddingx, paddingy;
|
int paddingxlr, paddingx, paddingy;
|
||||||
|
|||||||
Reference in New Issue
Block a user