Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f1dac50f1 | ||
|
|
eb0346e02a | ||
|
|
cae621918e | ||
|
|
f28983e5a7 | ||
|
|
b35cdb70df | ||
|
|
80361a121e | ||
|
|
b4ff007e42 | ||
|
|
ae379d865c | ||
|
|
0a3876dc8c | ||
|
|
e2d95acfa1 | ||
|
|
5ac1a6a653 | ||
|
|
481c409617 | ||
|
|
e8869b4d87 | ||
|
|
b1b95e086d | ||
|
|
df1f2d4e4b | ||
|
|
18b0ef2d1b | ||
|
|
860c100a04 | ||
|
|
9040764cf1 | ||
|
|
d8d4bc76cd | ||
|
|
fbcfa54061 | ||
|
|
b235f77f39 | ||
|
|
1b4b0a8d8d | ||
|
|
7ea0dc241c | ||
|
|
39e67df44d | ||
|
|
cb17e5a662 | ||
|
|
ea67f24051 | ||
| 7e2e1d5adf | |||
|
|
c49d231875 | ||
| d839d80c2e |
1
AUTHORS
1
AUTHORS
@@ -5,6 +5,7 @@ tint2 is developped by :
|
|||||||
- Euan Freeman <euan04@gmail.com> (tintwizard)
|
- Euan Freeman <euan04@gmail.com> (tintwizard)
|
||||||
- Christian Ruppert <Spooky85@gmail.com> (autotools build system)
|
- Christian Ruppert <Spooky85@gmail.com> (autotools build system)
|
||||||
- Ovidiu M <mrovi9000 at gmail.com> : launcher, bug fixes
|
- Ovidiu M <mrovi9000 at gmail.com> : launcher, bug fixes
|
||||||
|
- Mishael A Sibiryakov (death@junki.org) : freespace
|
||||||
|
|
||||||
tint2 is based on ttm source code (http://code.google.com/p/ttm/)
|
tint2 is based on ttm source code (http://code.google.com/p/ttm/)
|
||||||
- 2007-2008 Pål Staurland <staura@gmail.com>
|
- 2007-2008 Pål Staurland <staura@gmail.com>
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ include_directories( ${PROJECT_BINARY_DIR}
|
|||||||
src/launcher
|
src/launcher
|
||||||
src/tooltip
|
src/tooltip
|
||||||
src/util
|
src/util
|
||||||
|
src/freespace
|
||||||
${X11_INCLUDE_DIRS}
|
${X11_INCLUDE_DIRS}
|
||||||
${PANGOCAIRO_INCLUDE_DIRS}
|
${PANGOCAIRO_INCLUDE_DIRS}
|
||||||
${PANGO_INCLUDE_DIRS}
|
${PANGO_INCLUDE_DIRS}
|
||||||
@@ -67,6 +68,7 @@ set( SOURCES src/config.c
|
|||||||
src/taskbar/taskbar.c
|
src/taskbar/taskbar.c
|
||||||
src/taskbar/taskbarname.c
|
src/taskbar/taskbarname.c
|
||||||
src/tooltip/tooltip.c
|
src/tooltip/tooltip.c
|
||||||
|
src/freespace/freespace.c
|
||||||
src/util/area.c
|
src/util/area.c
|
||||||
src/util/common.c
|
src/util/common.c
|
||||||
src/util/strnatcmp.c
|
src/util/strnatcmp.c
|
||||||
|
|||||||
37
ChangeLog
37
ChangeLog
@@ -1,4 +1,4 @@
|
|||||||
2015-05-23 master
|
2015-06-12 master
|
||||||
- Note: the changes listed here are based on the previous release tint2 0.11, however some distributions (e.g. Debian)
|
- Note: the changes listed here are based on the previous release tint2 0.11, however some distributions (e.g. Debian)
|
||||||
offered packages using newer commits and/or patches; thus from the user's perspective some of these features are
|
offered packages using newer commits and/or patches; thus from the user's perspective some of these features are
|
||||||
already present. They are marked with '(already released by distros)'.
|
already present. They are marked with '(already released by distros)'.
|
||||||
@@ -12,7 +12,9 @@
|
|||||||
- 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:
|
- System tray:
|
||||||
- Workaround for misbehaving applications leaving empty tray icons
|
- Icon rendering is faster
|
||||||
|
- Several kinds of graphical corruptions have been fixed
|
||||||
|
- Added 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:
|
||||||
@@ -25,6 +27,7 @@
|
|||||||
- taskbar_hide_inactive_tasks
|
- taskbar_hide_inactive_tasks
|
||||||
- taskbar_sort_order
|
- taskbar_sort_order
|
||||||
- taskbar_name (already released by distros)
|
- taskbar_name (already released by distros)
|
||||||
|
- task_align (already released by distros)
|
||||||
- Launcher:
|
- Launcher:
|
||||||
- launcher* (already released by distros)
|
- launcher* (already released by distros)
|
||||||
- launcher_apps_dir (previously patched in by some distros)
|
- launcher_apps_dir (previously patched in by some distros)
|
||||||
@@ -32,6 +35,7 @@
|
|||||||
- launcher_icon_theme_override
|
- launcher_icon_theme_override
|
||||||
- System tray:
|
- System tray:
|
||||||
- systray_monitor
|
- systray_monitor
|
||||||
|
- Freespace (already released by distros)
|
||||||
- Config options with changed behavior:
|
- Config options with changed behavior:
|
||||||
- Panel:
|
- Panel:
|
||||||
- panel_dock: previously, 'panel_dock = 1' was actually not placing the panel into the dock. This option now
|
- panel_dock: previously, 'panel_dock = 1' was actually not placing the panel into the dock. This option now
|
||||||
@@ -46,8 +50,37 @@
|
|||||||
Reason for change: legibility improved for transparent panels.
|
Reason for change: legibility improved for transparent panels.
|
||||||
- Launcher:
|
- Launcher:
|
||||||
- launcher_item_app: now it expands leading ~ to the path to the user's home directory.
|
- launcher_item_app: now it expands leading ~ to the path to the user's home directory.
|
||||||
|
- Known issues:
|
||||||
|
- tint2 might close unexpectedly and/or cause X to freeze on certain ATI graphics cards.
|
||||||
|
Workaround: set 'disable_transparency = 1' in the config.
|
||||||
|
Reference: https://gitlab.com/o9000/tint2/issues/497
|
||||||
- Project hosting:
|
- Project hosting:
|
||||||
- Migrated from https://code.google.com/p/tint2 to https://gitlab.com/o9000/tint2 and switched from svn to git
|
- Migrated from https://code.google.com/p/tint2 to https://gitlab.com/o9000/tint2 and switched from svn to git
|
||||||
|
- Bugfixes:
|
||||||
|
- task switching from tint2 using the mouse wheel (mouse_scroll_up = prev_task and mouse_scroll_down = next_task) with
|
||||||
|
multiple desktops and taskbar_mode = multi_desktop when hovering over the first/last window in the taskbar was broken;
|
||||||
|
also when a window is set to appear on all desktops;
|
||||||
|
- the launcher was not loading an icon if the icon theme was not providing it in a size close to the value of launcher_icon_size;
|
||||||
|
- the launcher was not loading an icon if the extension was incorrect (e.g. file contents were PNG but the file name
|
||||||
|
had extension SVG);
|
||||||
|
- some launcher icons (PNG files saved with an indexed colormap and alpha mask) were sometimes rendered with white instead of
|
||||||
|
transparency;
|
||||||
|
- icons looked washed out when the panel was very transparent;
|
||||||
|
- the panel border was rendered in the background of every systray icon; sometimes systray icons were rendered in the
|
||||||
|
background of other icons;
|
||||||
|
- a crash caused by a change that prevents Google Chrome (and possibly other misbehaving applications) from leaving a large
|
||||||
|
number of empty icons in the system tray;
|
||||||
|
- a crash caused by the system tray code on computers with ATI cards;
|
||||||
|
- the panel window had a shadow;
|
||||||
|
- some ATI drivers return an extra monitor with size zero which should be ignored when using panel_monitor = all;
|
||||||
|
- the battery applet was sometimes working incorrectly with certain laptop models (the battery applet stopped updating after
|
||||||
|
suspend with the battery unplugged);
|
||||||
|
- crashed caused by incomplete or malformed config files;
|
||||||
|
- with the fvwm window manager, the window title was sometimes not displayed correctly if it changed right after an
|
||||||
|
application was started;
|
||||||
|
- seconds were not updating in the clock;
|
||||||
|
- tint2 hang triggered when an application started from the launcher was closed and startup notifications were enabled;
|
||||||
|
- the code that loads SVG icons was using a lot of memory.
|
||||||
|
|
||||||
2010-06-26
|
2010-06-26
|
||||||
- unhide tint2 panel when dragging something
|
- unhide tint2 panel when dragging something
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -1,14 +1,14 @@
|
|||||||
### New unstable release: 0.12-rc5
|
### New unstable release: 0.12-rc6
|
||||||
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-rc5
|
mkdir tint2-0.12-rc6
|
||||||
cd tint2-0.12-rc5
|
cd tint2-0.12-rc6
|
||||||
wget 'https://gitlab.com/o9000/tint2/repository/archive.tar.gz?ref=v0.12-rc5' --output-document tint2-0.12-rc5.tar.gz
|
wget 'https://gitlab.com/o9000/tint2/repository/archive.tar.gz?ref=v0.12-rc6' --output-document tint2-0.12-rc6.tar.gz
|
||||||
tar -xzf tint2-0.12-rc5.tar.gz
|
tar -xzf tint2-0.12-rc6.tar.gz
|
||||||
cd tint2.git
|
cd tint2.git
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
|
|||||||
45
src/config.c
45
src/config.c
@@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
#include "strnatcmp.h"
|
||||||
#include "panel.h"
|
#include "panel.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "taskbar.h"
|
#include "taskbar.h"
|
||||||
@@ -153,23 +154,48 @@ int config_get_monitor(char* monitor)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint compare_strings(gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
return strnatcasecmp((const char*)a, (const char*)b);
|
||||||
|
}
|
||||||
|
|
||||||
void load_launcher_app_dir(const char *path)
|
void load_launcher_app_dir(const char *path)
|
||||||
{
|
{
|
||||||
|
GList *subdirs = NULL;
|
||||||
|
GList *files = NULL;
|
||||||
|
|
||||||
GDir *d = g_dir_open(path, 0, NULL);
|
GDir *d = g_dir_open(path, 0, NULL);
|
||||||
if (d) {
|
if (d) {
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
while ((name = g_dir_read_name(d))) {
|
while ((name = g_dir_read_name(d))) {
|
||||||
gchar *file = g_build_filename(path, name, NULL);
|
gchar *file = g_build_filename(path, name, NULL);
|
||||||
if (!g_file_test(file, G_FILE_TEST_IS_DIR) &&
|
if (!g_file_test(file, G_FILE_TEST_IS_DIR) && g_str_has_suffix(file, ".desktop")) {
|
||||||
g_str_has_suffix(file, ".desktop")) {
|
files = g_list_append(files, file);
|
||||||
panel_config.launcher.list_apps = g_slist_append(panel_config.launcher.list_apps, strdup(file));
|
|
||||||
} else if (g_file_test(file, G_FILE_TEST_IS_DIR)) {
|
} else if (g_file_test(file, G_FILE_TEST_IS_DIR)) {
|
||||||
load_launcher_app_dir(file);
|
subdirs = g_list_append(subdirs, file);
|
||||||
}
|
} else {
|
||||||
g_free(file);
|
g_free(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g_dir_close(d);
|
g_dir_close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subdirs = g_list_sort(subdirs, compare_strings);
|
||||||
|
GList *l;
|
||||||
|
for (l = subdirs; l; l = g_list_next(l)) {
|
||||||
|
gchar *dir = (gchar *)l->data;
|
||||||
|
load_launcher_app_dir(dir);
|
||||||
|
g_free(dir);
|
||||||
|
}
|
||||||
|
g_list_free(subdirs);
|
||||||
|
|
||||||
|
files = g_list_sort(files, compare_strings);
|
||||||
|
for (l = files; l; l = g_list_next(l)) {
|
||||||
|
gchar *file = (gchar *)l->data;
|
||||||
|
panel_config.launcher.list_apps = g_slist_append(panel_config.launcher.list_apps, strdup(file));
|
||||||
|
g_free(file);
|
||||||
|
}
|
||||||
|
g_list_free(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_entry (char *key, char *value)
|
void add_entry (char *key, char *value)
|
||||||
@@ -518,6 +544,15 @@ void add_entry (char *key, char *value)
|
|||||||
taskbar_sort_method = TASKBAR_NOSORT;
|
taskbar_sort_method = TASKBAR_NOSORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcmp (key, "task_align") == 0) {
|
||||||
|
if (strcmp(value, "center") == 0) {
|
||||||
|
taskbar_alignment = ALIGN_CENTER;
|
||||||
|
} else if (strcmp(value, "right") == 0) {
|
||||||
|
taskbar_alignment = ALIGN_RIGHT;
|
||||||
|
} else {
|
||||||
|
taskbar_alignment = ALIGN_LEFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Task */
|
/* Task */
|
||||||
else if (strcmp (key, "task_text") == 0)
|
else if (strcmp (key, "task_text") == 0)
|
||||||
|
|||||||
93
src/freespace/freespace.c
Normal file
93
src/freespace/freespace.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Tint2 : freespace
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Mishael A Sibiryakov (death@junki.org)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <cairo.h>
|
||||||
|
#include <cairo-xlib.h>
|
||||||
|
#include <pango/pangocairo.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "window.h"
|
||||||
|
#include "server.h"
|
||||||
|
#include "panel.h"
|
||||||
|
#include "freespace.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
void init_freespace_panel(void *p)
|
||||||
|
{
|
||||||
|
Panel *panel = (Panel*)p;
|
||||||
|
FreeSpace *freespace = &panel->freespace;
|
||||||
|
|
||||||
|
if (freespace->area.bg == 0)
|
||||||
|
freespace->area.bg = &g_array_index(backgrounds, Background, 0);
|
||||||
|
freespace->area.parent = p;
|
||||||
|
freespace->area.panel = p;
|
||||||
|
freespace->area.size_mode = SIZE_BY_CONTENT;
|
||||||
|
freespace->area.resize = 1;
|
||||||
|
freespace->area.on_screen = 1;
|
||||||
|
freespace->area._resize = resize_freespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
int freespace_get_max_size(Panel *p) {
|
||||||
|
// Get space used by every element except the freespace
|
||||||
|
GList *walk;
|
||||||
|
int size = 0;
|
||||||
|
for (walk = p->area.list; walk; walk = g_list_next(walk)) {
|
||||||
|
Area *a = (Area *)walk->data;
|
||||||
|
|
||||||
|
if (a->_resize == resize_freespace || !a->on_screen)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (panel_horizontal)
|
||||||
|
size += a->width + (a->bg->border.width * 2) + p->area.paddingx;
|
||||||
|
else
|
||||||
|
size += a->height + (a->bg->border.width * 2) + p->area.paddingy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panel_horizontal)
|
||||||
|
size = p->area.width - size - (p->area.bg->border.width * 2) - p->area.paddingxlr;
|
||||||
|
else
|
||||||
|
size = p->area.height - size - (p->area.bg->border.width * 2) - p->area.paddingxlr;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resize_freespace(void *obj) {
|
||||||
|
FreeSpace *freespace = (FreeSpace*)obj;
|
||||||
|
Panel *panel = (Panel*)freespace->area.panel;
|
||||||
|
if (!freespace->area.on_screen)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int old_size = panel_horizontal ? freespace->area.width : freespace->area.height;
|
||||||
|
int size = freespace_get_max_size(panel);
|
||||||
|
if (old_size == size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (panel_horizontal) {
|
||||||
|
freespace->area.width = size;
|
||||||
|
} else {
|
||||||
|
freespace->area.height = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
freespace->area.redraw = 1;
|
||||||
|
panel_refresh = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
20
src/freespace/freespace.h
Normal file
20
src/freespace/freespace.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
* Copyright (C) 2011 Mishael A Sibiryakov (death@junki.org)
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FREESPACE_H
|
||||||
|
#define FREESPACE_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "area.h"
|
||||||
|
|
||||||
|
typedef struct FreeSpace {
|
||||||
|
Area area;
|
||||||
|
} FreeSpace;
|
||||||
|
|
||||||
|
void cleanup_freespace();
|
||||||
|
void init_freespace_panel(void *panel);
|
||||||
|
|
||||||
|
int resize_freespace(void *obj);
|
||||||
|
|
||||||
|
#endif
|
||||||
33
src/panel.c
33
src/panel.c
@@ -204,6 +204,8 @@ void init_panel()
|
|||||||
}
|
}
|
||||||
if (panel_items_order[k] == 'C')
|
if (panel_items_order[k] == 'C')
|
||||||
init_clock_panel(p);
|
init_clock_panel(p);
|
||||||
|
if (panel_items_order[k] == 'F' && !strstr(panel_items_order, "T"))
|
||||||
|
init_freespace_panel(p);
|
||||||
}
|
}
|
||||||
set_panel_items_order(p);
|
set_panel_items_order(p);
|
||||||
|
|
||||||
@@ -322,13 +324,13 @@ void init_panel_size_and_position(Panel *panel)
|
|||||||
|
|
||||||
int resize_panel(void *obj)
|
int resize_panel(void *obj)
|
||||||
{
|
{
|
||||||
resize_by_layout(obj, 0);
|
Panel *panel = (Panel*)obj;
|
||||||
|
resize_by_layout(panel, 0);
|
||||||
|
|
||||||
//printf("resize_panel\n");
|
//printf("resize_panel\n");
|
||||||
if (panel_mode != MULTI_DESKTOP && taskbar_enabled) {
|
if (panel_mode != MULTI_DESKTOP && taskbar_enabled) {
|
||||||
// propagate width/height on hidden taskbar
|
// propagate width/height on hidden taskbar
|
||||||
int i, width, height;
|
int i, width, height;
|
||||||
Panel *panel = (Panel*)obj;
|
|
||||||
width = panel->taskbar[server.desktop].area.width;
|
width = panel->taskbar[server.desktop].area.width;
|
||||||
height = panel->taskbar[server.desktop].area.height;
|
height = panel->taskbar[server.desktop].area.height;
|
||||||
for (i=0 ; i < panel->nb_desktop ; i++) {
|
for (i=0 ; i < panel->nb_desktop ; i++) {
|
||||||
@@ -339,7 +341,6 @@ int resize_panel(void *obj)
|
|||||||
}
|
}
|
||||||
if (panel_mode == MULTI_DESKTOP && taskbar_enabled && taskbar_distribute_size) {
|
if (panel_mode == MULTI_DESKTOP && taskbar_enabled && taskbar_distribute_size) {
|
||||||
// Distribute the available space between taskbars
|
// Distribute the available space between taskbars
|
||||||
Panel *panel = (Panel*)obj;
|
|
||||||
|
|
||||||
// Compute the total available size, and the total size requested by the taskbars
|
// Compute the total available size, and the total size requested by the taskbars
|
||||||
int total_size = 0;
|
int total_size = 0;
|
||||||
@@ -354,7 +355,7 @@ int resize_panel(void *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Taskbar *taskbar = &panel->taskbar[i];
|
Taskbar *taskbar = &panel->taskbar[i];
|
||||||
GSList *l;
|
GList *l;
|
||||||
for (l = taskbar->area.list; l; l = l->next) {
|
for (l = taskbar->area.list; l; l = l->next) {
|
||||||
Area *child = l->data;
|
Area *child = l->data;
|
||||||
if (!child->on_screen)
|
if (!child->on_screen)
|
||||||
@@ -389,7 +390,7 @@ int resize_panel(void *obj)
|
|||||||
|
|
||||||
int requested_size = (2 * taskbar->area.bg->border.width) + (2 * taskbar->area.paddingxlr);
|
int requested_size = (2 * taskbar->area.bg->border.width) + (2 * taskbar->area.paddingxlr);
|
||||||
int items = 0;
|
int items = 0;
|
||||||
GSList *l = taskbar->area.list;
|
GList *l = taskbar->area.list;
|
||||||
if (taskbarname_enabled)
|
if (taskbarname_enabled)
|
||||||
l = l->next;
|
l = l->next;
|
||||||
for (; l; l = l->next) {
|
for (; l; l = l->next) {
|
||||||
@@ -418,6 +419,8 @@ int resize_panel(void *obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (panel->freespace.area.on_screen)
|
||||||
|
resize_freespace(&panel->freespace);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,29 +485,31 @@ void set_panel_items_order(Panel *p)
|
|||||||
int k, j;
|
int k, j;
|
||||||
|
|
||||||
if (p->area.list) {
|
if (p->area.list) {
|
||||||
g_slist_free(p->area.list);
|
g_list_free(p->area.list);
|
||||||
p->area.list = 0;
|
p->area.list = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k=0 ; k < strlen(panel_items_order) ; k++) {
|
for (k=0 ; k < strlen(panel_items_order) ; k++) {
|
||||||
if (panel_items_order[k] == 'L') {
|
if (panel_items_order[k] == 'L') {
|
||||||
p->area.list = g_slist_append(p->area.list, &p->launcher);
|
p->area.list = g_list_append(p->area.list, &p->launcher);
|
||||||
p->launcher.area.resize = 1;
|
p->launcher.area.resize = 1;
|
||||||
}
|
}
|
||||||
if (panel_items_order[k] == 'T') {
|
if (panel_items_order[k] == 'T') {
|
||||||
for (j=0 ; j < p->nb_desktop ; j++)
|
for (j=0 ; j < p->nb_desktop ; j++)
|
||||||
p->area.list = g_slist_append(p->area.list, &p->taskbar[j]);
|
p->area.list = g_list_append(p->area.list, &p->taskbar[j]);
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_BATTERY
|
#ifdef ENABLE_BATTERY
|
||||||
if (panel_items_order[k] == 'B')
|
if (panel_items_order[k] == 'B')
|
||||||
p->area.list = g_slist_append(p->area.list, &p->battery);
|
p->area.list = g_list_append(p->area.list, &p->battery);
|
||||||
#endif
|
#endif
|
||||||
int i = p - panel1;
|
int i = p - panel1;
|
||||||
if (panel_items_order[k] == 'S' && systray_on_monitor(i, nb_panel)) {
|
if (panel_items_order[k] == 'S' && systray_on_monitor(i, nb_panel)) {
|
||||||
p->area.list = g_slist_append(p->area.list, &systray);
|
p->area.list = g_list_append(p->area.list, &systray);
|
||||||
}
|
}
|
||||||
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_list_append(p->area.list, &p->clock);
|
||||||
|
if (panel_items_order[k] == 'F')
|
||||||
|
p->area.list = g_list_append(p->area.list, &p->freespace);
|
||||||
}
|
}
|
||||||
init_rendering(&p->area, 0);
|
init_rendering(&p->area, 0);
|
||||||
}
|
}
|
||||||
@@ -629,7 +634,7 @@ void set_panel_background(Panel *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// redraw panel's object
|
// redraw panel's object
|
||||||
GSList *l0;
|
GList *l0;
|
||||||
Area *a;
|
Area *a;
|
||||||
for (l0 = p->area.list; l0 ; l0 = l0->next) {
|
for (l0 = p->area.list; l0 ; l0 = l0->next) {
|
||||||
a = l0->data;
|
a = l0->data;
|
||||||
@@ -695,7 +700,7 @@ Taskbar *click_taskbar (Panel *panel, int x, int y)
|
|||||||
|
|
||||||
Task *click_task (Panel *panel, int x, int y)
|
Task *click_task (Panel *panel, int x, int y)
|
||||||
{
|
{
|
||||||
GSList *l0;
|
GList *l0;
|
||||||
Taskbar *tskbar;
|
Taskbar *tskbar;
|
||||||
|
|
||||||
if ( (tskbar = click_taskbar(panel, x, y)) ) {
|
if ( (tskbar = click_taskbar(panel, x, y)) ) {
|
||||||
@@ -797,7 +802,7 @@ Area* click_area(Panel *panel, int x, int y)
|
|||||||
Area* new_result = result;
|
Area* new_result = result;
|
||||||
do {
|
do {
|
||||||
result = new_result;
|
result = new_result;
|
||||||
GSList* it = result->list;
|
GList* it = result->list;
|
||||||
while (it) {
|
while (it) {
|
||||||
Area* a = it->data;
|
Area* a = it->data;
|
||||||
if (a->on_screen && x >= a->posx && x <= (a->posx + a->width)
|
if (a->on_screen && x >= a->posx && x <= (a->posx + a->width)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "taskbar.h"
|
#include "taskbar.h"
|
||||||
#include "systraybar.h"
|
#include "systraybar.h"
|
||||||
#include "launcher.h"
|
#include "launcher.h"
|
||||||
|
#include "freespace.h"
|
||||||
|
|
||||||
#ifdef ENABLE_BATTERY
|
#ifdef ENABLE_BATTERY
|
||||||
#include "battery.h"
|
#include "battery.h"
|
||||||
@@ -116,6 +117,8 @@ typedef struct {
|
|||||||
|
|
||||||
Launcher launcher;
|
Launcher launcher;
|
||||||
|
|
||||||
|
FreeSpace freespace;
|
||||||
|
|
||||||
// autohide
|
// autohide
|
||||||
int is_hidden;
|
int is_hidden;
|
||||||
int hidden_width, hidden_height;
|
int hidden_width, hidden_height;
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ GSList *icons;
|
|||||||
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
|
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
|
||||||
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
|
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
|
||||||
|
|
||||||
#define FORCE_COMPOSITED_RENDERING 1
|
|
||||||
|
|
||||||
// selection window
|
// selection window
|
||||||
Window net_sel_win = None;
|
Window net_sel_win = None;
|
||||||
|
|
||||||
@@ -53,6 +51,7 @@ int systray_enabled;
|
|||||||
int systray_max_icon_size;
|
int systray_max_icon_size;
|
||||||
int systray_monitor;
|
int systray_monitor;
|
||||||
int chrono;
|
int chrono;
|
||||||
|
int systray_composited;
|
||||||
// background pixmap if we render ourselves the icons
|
// background pixmap if we render ourselves the icons
|
||||||
static Pixmap render_background;
|
static Pixmap render_background;
|
||||||
|
|
||||||
@@ -86,16 +85,19 @@ void cleanup_systray()
|
|||||||
|
|
||||||
void init_systray()
|
void init_systray()
|
||||||
{
|
{
|
||||||
start_net();
|
|
||||||
|
|
||||||
if (!systray_enabled)
|
if (!systray_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!server.visual32 && (systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0)) {
|
systray_composited = !server.disable_transparency && server.visual32 && server.colormap32;
|
||||||
printf("No 32 bit visual for your X implementation. 'systray_asb = 100 0 0' will be forced\n");
|
printf("Systray composited rendering %s\n", systray_composited ? "on" : "off");
|
||||||
|
|
||||||
|
if (!systray_composited) {
|
||||||
|
printf("systray_asb forced to 100 0 0\n");
|
||||||
systray.alpha = 100;
|
systray.alpha = 100;
|
||||||
systray.brightness = systray.saturation = 0;
|
systray.brightness = systray.saturation = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start_net();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -123,8 +125,9 @@ void init_systray_panel(void *p)
|
|||||||
|
|
||||||
void draw_systray(void *obj, cairo_t *c)
|
void draw_systray(void *obj, cairo_t *c)
|
||||||
{
|
{
|
||||||
if (FORCE_COMPOSITED_RENDERING || server.real_transparency || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0) {
|
if (systray_composited) {
|
||||||
if (render_background) XFreePixmap(server.dsp, render_background);
|
if (render_background)
|
||||||
|
XFreePixmap(server.dsp, render_background);
|
||||||
render_background = XCreatePixmap(server.dsp, server.root_win, systray.area.width, systray.area.height, server.depth);
|
render_background = XCreatePixmap(server.dsp, server.root_win, systray.area.width, systray.area.height, server.depth);
|
||||||
XCopyArea(server.dsp, systray.area.pix, render_background, server.gc, 0, 0, systray.area.width, systray.area.height, 0, 0);
|
XCopyArea(server.dsp, systray.area.pix, render_background, server.gc, 0, 0, systray.area.width, systray.area.height, 0, 0);
|
||||||
}
|
}
|
||||||
@@ -161,8 +164,7 @@ int resize_systray(void *obj)
|
|||||||
sysbar->marging = height - (sysbar->icons_per_column-1)*(sysbar->icon_size+sysbar->area.paddingx) - sysbar->icon_size;
|
sysbar->marging = height - (sysbar->icons_per_column-1)*(sysbar->icon_size+sysbar->area.paddingx) - sysbar->icon_size;
|
||||||
sysbar->icons_per_row = count / sysbar->icons_per_column + (count%sysbar->icons_per_column != 0);
|
sysbar->icons_per_row = count / sysbar->icons_per_column + (count%sysbar->icons_per_column != 0);
|
||||||
systray.area.width = (2 * systray.area.bg->border.width) + (2 * systray.area.paddingxlr) + (sysbar->icon_size * sysbar->icons_per_row) + ((sysbar->icons_per_row-1) * systray.area.paddingx);
|
systray.area.width = (2 * systray.area.bg->border.width) + (2 * systray.area.paddingxlr) + (sysbar->icon_size * sysbar->icons_per_row) + ((sysbar->icons_per_row-1) * systray.area.paddingx);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
int width = sysbar->area.width - 2*sysbar->area.bg->border.width - 2*sysbar->area.paddingy;
|
int width = sysbar->area.width - 2*sysbar->area.bg->border.width - 2*sysbar->area.paddingy;
|
||||||
// here icons_per_row always higher than 0
|
// here icons_per_row always higher than 0
|
||||||
sysbar->icons_per_row = (width+sysbar->area.paddingx) / (sysbar->icon_size+sysbar->area.paddingx);
|
sysbar->icons_per_row = (width+sysbar->area.paddingx) / (sysbar->icon_size+sysbar->area.paddingx);
|
||||||
@@ -187,45 +189,46 @@ void on_change_systray (void *obj)
|
|||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
posy = start;
|
posy = start;
|
||||||
posx = systray.area.posx + systray.area.bg->border.width + systray.area.paddingxlr;
|
posx = systray.area.posx + systray.area.bg->border.width + systray.area.paddingxlr;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
posx = start;
|
posx = start;
|
||||||
posy = systray.area.posy + systray.area.bg->border.width + systray.area.paddingxlr;
|
posy = systray.area.posy + systray.area.bg->border.width + systray.area.paddingxlr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrayWindow *traywin;
|
TrayWindow *traywin;
|
||||||
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 : pos %d, %d\n", traywin->parent, traywin->win, 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) {
|
||||||
if (i % sysbar->icons_per_column)
|
if (i % sysbar->icons_per_column) {
|
||||||
posy += sysbar->icon_size + sysbar->area.paddingx;
|
posy += sysbar->icon_size + sysbar->area.paddingx;
|
||||||
else {
|
} else {
|
||||||
posy = start;
|
posy = start;
|
||||||
posx += (sysbar->icon_size + systray.area.paddingx);
|
posx += (sysbar->icon_size + systray.area.paddingx);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
if (i % sysbar->icons_per_row) {
|
||||||
if (i % sysbar->icons_per_row)
|
|
||||||
posx += sysbar->icon_size + systray.area.paddingx;
|
posx += sysbar->icon_size + systray.area.paddingx;
|
||||||
else {
|
} else {
|
||||||
posx = start;
|
posx = start;
|
||||||
posy += (sysbar->icon_size + systray.area.paddingx);
|
posy += (sysbar->icon_size + systray.area.paddingx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// position and size the icon window
|
// position and size the icon window
|
||||||
XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y, sysbar->icon_size, sysbar->icon_size);
|
XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height);
|
||||||
XResizeWindow(server.dsp, traywin->tray_id, sysbar->icon_size, sysbar->icon_size);
|
if (traywin->reparented) {
|
||||||
|
XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
refresh_systray = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -239,10 +242,10 @@ void start_net()
|
|||||||
if (!systray_enabled)
|
if (!systray_enabled)
|
||||||
stop_net();
|
stop_net();
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
if (!systray_enabled)
|
if (!systray_enabled)
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Window win = XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN);
|
Window win = XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN);
|
||||||
|
|
||||||
@@ -277,7 +280,7 @@ void start_net()
|
|||||||
long orient = 0;
|
long orient = 0;
|
||||||
XChangeProperty(server.dsp, net_sel_win, server.atom._NET_SYSTEM_TRAY_ORIENTATION, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &orient, 1);
|
XChangeProperty(server.dsp, net_sel_win, server.atom._NET_SYSTEM_TRAY_ORIENTATION, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &orient, 1);
|
||||||
VisualID vid;
|
VisualID vid;
|
||||||
if (server.visual32 && (FORCE_COMPOSITED_RENDERING || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0))
|
if (systray_composited)
|
||||||
vid = XVisualIDFromVisual(server.visual32);
|
vid = XVisualIDFromVisual(server.visual32);
|
||||||
else
|
else
|
||||||
vid = XVisualIDFromVisual(server.visual);
|
vid = XVisualIDFromVisual(server.visual);
|
||||||
@@ -327,10 +330,9 @@ void stop_net()
|
|||||||
gboolean error;
|
gboolean error;
|
||||||
int window_error_handler(Display *d, XErrorEvent *e)
|
int window_error_handler(Display *d, XErrorEvent *e)
|
||||||
{
|
{
|
||||||
d=d;e=e;
|
|
||||||
error = TRUE;
|
error = TRUE;
|
||||||
if (e->error_code != BadWindow) {
|
if (e->error_code != BadWindow) {
|
||||||
printf("error_handler %d\n", e->error_code);
|
printf("systray: error code %d\n", e->error_code);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -342,22 +344,20 @@ static gint compare_traywindows(gconstpointer a, gconstpointer b)
|
|||||||
const TrayWindow * traywin_b = (TrayWindow*)b;
|
const TrayWindow * traywin_b = (TrayWindow*)b;
|
||||||
|
|
||||||
if (traywin_a->empty && !traywin_b->empty)
|
if (traywin_a->empty && !traywin_b->empty)
|
||||||
return 1;
|
return 1 * (systray.sort == SYSTRAY_SORT_RIGHT2LEFT ? -1 : 1);
|
||||||
if (!traywin_a->empty && traywin_b->empty)
|
if (!traywin_a->empty && traywin_b->empty)
|
||||||
return -1;
|
return -1 * (systray.sort == SYSTRAY_SORT_RIGHT2LEFT ? -1 : 1);
|
||||||
|
|
||||||
if (systray.sort == SYSTRAY_SORT_ASCENDING ||
|
if (systray.sort == SYSTRAY_SORT_ASCENDING ||
|
||||||
systray.sort == SYSTRAY_SORT_DESCENDING) {
|
systray.sort == SYSTRAY_SORT_DESCENDING) {
|
||||||
XTextProperty name_a, name_b;
|
XTextProperty name_a, name_b;
|
||||||
|
|
||||||
if (XGetWMName(server.dsp, traywin_a->tray_id, &name_a) == 0) {
|
if (XGetWMName(server.dsp, traywin_a->win, &name_a) == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else if (XGetWMName(server.dsp, traywin_b->win, &name_b) == 0) {
|
||||||
else if (XGetWMName(server.dsp, traywin_b->tray_id, &name_b) == 0) {
|
|
||||||
XFree(name_a.value);
|
XFree(name_a.value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
gint retval = g_ascii_strncasecmp((char*)name_a.value, (char*)name_b.value, -1) *
|
gint retval = g_ascii_strncasecmp((char*)name_a.value, (char*)name_b.value, -1) *
|
||||||
(systray.sort == SYSTRAY_SORT_ASCENDING ? 1 : -1);
|
(systray.sort == SYSTRAY_SORT_ASCENDING ? 1 : -1);
|
||||||
XFree(name_a.value);
|
XFree(name_a.value);
|
||||||
@@ -376,13 +376,13 @@ static gint compare_traywindows(gconstpointer a, gconstpointer b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean add_icon(Window id)
|
gboolean add_icon(Window win)
|
||||||
{
|
{
|
||||||
TrayWindow *traywin;
|
TrayWindow *traywin;
|
||||||
XErrorHandler old;
|
|
||||||
Panel *panel = systray.area.panel;
|
Panel *panel = systray.area.panel;
|
||||||
int hide = 0;
|
int hide = 0;
|
||||||
|
|
||||||
|
// Get the process ID of the application that created the window
|
||||||
int pid = 0;
|
int pid = 0;
|
||||||
{
|
{
|
||||||
Atom actual_type;
|
Atom actual_type;
|
||||||
@@ -390,112 +390,66 @@ gboolean add_icon(Window id)
|
|||||||
unsigned long nitems;
|
unsigned long nitems;
|
||||||
unsigned long bytes_after;
|
unsigned long bytes_after;
|
||||||
unsigned char *prop = 0;
|
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);
|
int ret = XGetWindowProperty(server.dsp, win, server.atom._NET_WM_PID, 0, 1024, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop);
|
||||||
if (ret == Success && prop) {
|
if (ret == Success && prop) {
|
||||||
pid = prop[1] * 256;
|
pid = prop[1] * 256;
|
||||||
pid += prop[0];
|
pid += prop[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the application leaves behind empty icons
|
||||||
GSList *l;
|
GSList *l;
|
||||||
int num_empty_same_pid = 0;
|
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)->win == win)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (pid && ((TrayWindow*)l->data)->pid == pid && ((TrayWindow*)l->data)->empty)
|
if (pid && ((TrayWindow*)l->data)->pid == pid && ((TrayWindow*)l->data)->empty)
|
||||||
num_empty_same_pid++;
|
num_empty_same_pid++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove empty icons if the application leaves behind more than 1
|
||||||
const int max_num_empty_same_pid = 0;
|
const int max_num_empty_same_pid = 0;
|
||||||
if (num_empty_same_pid > max_num_empty_same_pid) {
|
if (num_empty_same_pid > max_num_empty_same_pid) {
|
||||||
for (l = systray.list_icons; l; l = l->next) {
|
for (l = systray.list_icons; l; l = l->next) {
|
||||||
if (pid && ((TrayWindow*)l->data)->pid == pid && ((TrayWindow*)l->data)->empty) {
|
if (pid && ((TrayWindow*)l->data)->pid == pid && ((TrayWindow*)l->data)->empty) {
|
||||||
num_empty_same_pid++;
|
num_empty_same_pid++;
|
||||||
fprintf(stderr, "Removing tray icon %lu from misbehaving application with pid=%d\n", ((TrayWindow*)l->data)->tray_id, pid);
|
fprintf(stderr, "Removing tray icon %lu from misbehaving application with pid=%d\n", ((TrayWindow*)l->data)->win, pid);
|
||||||
remove_icon((TrayWindow*)l->data);
|
remove_icon((TrayWindow*)l->data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//printf("add_icon: %d, pid %d, %d\n", id, pid, num_empty_same_pid);
|
//printf("add_icon: %d, pid %d, %d\n", win, pid, num_empty_same_pid);
|
||||||
|
|
||||||
error = FALSE;
|
// Create the parent window that will embed the icon
|
||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
if ( XGetWindowAttributes(server.dsp, id, &attr) == False ) return FALSE;
|
if (XGetWindowAttributes(server.dsp, win, &attr) == False)
|
||||||
|
return FALSE;
|
||||||
unsigned long mask = 0;
|
unsigned long mask = 0;
|
||||||
XSetWindowAttributes set_attr;
|
XSetWindowAttributes set_attr;
|
||||||
Visual* visual = server.visual;
|
Visual* visual = server.visual;
|
||||||
//printf("icon with depth: %d, width %d, height %d\n", attr.depth, attr.width, attr.height);
|
//printf("icon with depth: %d, width %d, height %d\n", attr.depth, attr.width, attr.height);
|
||||||
//printf("icon with depth: %d\n", attr.depth);
|
if (systray_composited || attr.depth != server.depth) {
|
||||||
if (attr.depth != server.depth || FORCE_COMPOSITED_RENDERING || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0) {
|
|
||||||
visual = attr.visual;
|
visual = attr.visual;
|
||||||
set_attr.colormap = attr.colormap;
|
set_attr.colormap = attr.colormap;
|
||||||
set_attr.background_pixel = 0;
|
set_attr.background_pixel = 0;
|
||||||
set_attr.border_pixel = 0;
|
set_attr.border_pixel = 0;
|
||||||
mask = CWColormap|CWBackPixel|CWBorderPixel;
|
mask = CWColormap|CWBackPixel|CWBorderPixel;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
set_attr.background_pixmap = ParentRelative;
|
set_attr.background_pixmap = ParentRelative;
|
||||||
mask = CWBackPixmap;
|
mask = CWBackPixmap;
|
||||||
}
|
}
|
||||||
Window parent_window;
|
Window parent = XCreateWindow(server.dsp, panel->main_win, 0, 0, 30, 30, 0, attr.depth, InputOutput, visual, mask, &set_attr);
|
||||||
parent_window = XCreateWindow(server.dsp, panel->main_win, 0, 0, 30, 30, 0, attr.depth, InputOutput, visual, mask, &set_attr);
|
|
||||||
old = XSetErrorHandler(window_error_handler);
|
|
||||||
XReparentWindow(server.dsp, id, parent_window, 0, 0);
|
|
||||||
// watch for the icon trying to resize itself / closing again!
|
|
||||||
XSelectInput(server.dsp, id, StructureNotifyMask);
|
|
||||||
XSync(server.dsp, False);
|
|
||||||
XSetErrorHandler(old);
|
|
||||||
if (error != FALSE) {
|
|
||||||
fprintf(stderr, "tint2 : not icon_swallow\n");
|
|
||||||
XDestroyWindow(server.dsp, parent_window);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Atom acttype;
|
|
||||||
int actfmt;
|
|
||||||
unsigned long nbitem, bytes;
|
|
||||||
unsigned char *data = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = XGetWindowProperty(server.dsp, id, server.atom._XEMBED_INFO, 0, 2, False, server.atom._XEMBED_INFO, &acttype, &actfmt, &nbitem, &bytes, &data);
|
|
||||||
if (ret == Success) {
|
|
||||||
if (data) {
|
|
||||||
if (nbitem == 2) {
|
|
||||||
//hide = ((data[1] & XEMBED_MAPPED) == 0);
|
|
||||||
//printf("hide %d\n", hide);
|
|
||||||
}
|
|
||||||
XFree(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "tint2 : xembed error\n");
|
|
||||||
XDestroyWindow(server.dsp, parent_window);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
XEvent e;
|
|
||||||
e.xclient.type = ClientMessage;
|
|
||||||
e.xclient.serial = 0;
|
|
||||||
e.xclient.send_event = True;
|
|
||||||
e.xclient.message_type = server.atom._XEMBED;
|
|
||||||
e.xclient.window = id;
|
|
||||||
e.xclient.format = 32;
|
|
||||||
e.xclient.data.l[0] = CurrentTime;
|
|
||||||
e.xclient.data.l[1] = XEMBED_EMBEDDED_NOTIFY;
|
|
||||||
e.xclient.data.l[2] = 0;
|
|
||||||
e.xclient.data.l[3] = parent_window;
|
|
||||||
e.xclient.data.l[4] = 0;
|
|
||||||
XSendEvent(server.dsp, id, False, 0xFFFFFF, &e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Add the icon to the list
|
||||||
traywin = g_new0(TrayWindow, 1);
|
traywin = g_new0(TrayWindow, 1);
|
||||||
traywin->id = parent_window;
|
traywin->parent = parent;
|
||||||
traywin->tray_id = id;
|
traywin->win = win;
|
||||||
traywin->hide = hide;
|
traywin->hide = hide;
|
||||||
traywin->depth = attr.depth;
|
traywin->depth = attr.depth;
|
||||||
|
// Reparenting is done at the first paint event when the window is positioned correctly over its empty background,
|
||||||
|
// to prevent graphical corruptions in icons with fake transparency
|
||||||
|
traywin->reparented = 0;
|
||||||
traywin->damage = 0;
|
traywin->damage = 0;
|
||||||
traywin->empty = 0;
|
traywin->empty = 0;
|
||||||
traywin->pid = pid;
|
traywin->pid = pid;
|
||||||
@@ -510,45 +464,140 @@ gboolean add_icon(Window id)
|
|||||||
else
|
else
|
||||||
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);
|
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
||||||
//printf("add_icon id %lx, %d\n", id, g_slist_length(systray.list_icons));
|
// printf("add_icon win %lx, %d\n", win, g_slist_length(systray.list_icons));
|
||||||
|
|
||||||
if (FORCE_COMPOSITED_RENDERING || server.real_transparency || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0) {
|
// Resize and redraw the systray
|
||||||
traywin->damage = XDamageCreate(server.dsp, traywin->id, XDamageReportRawRectangles);
|
|
||||||
XCompositeRedirectWindow(server.dsp, traywin->id, CompositeRedirectManual);
|
|
||||||
}
|
|
||||||
|
|
||||||
// show the window
|
|
||||||
if (!traywin->hide)
|
|
||||||
XMapWindow(server.dsp, traywin->tray_id);
|
|
||||||
if (!traywin->hide && !panel->is_hidden)
|
|
||||||
XMapRaised(server.dsp, traywin->id);
|
|
||||||
|
|
||||||
// changed in systray
|
|
||||||
systray.area.resize = 1;
|
systray.area.resize = 1;
|
||||||
|
systray.area.redraw = 1;
|
||||||
|
panel->area.resize = 1;
|
||||||
panel_refresh = 1;
|
panel_refresh = 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean reparent_icon(TrayWindow *traywin)
|
||||||
|
{
|
||||||
|
if (traywin->reparented)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
Panel* panel = systray.area.panel;
|
||||||
|
|
||||||
|
// Reparent
|
||||||
|
XSync(server.dsp, False);
|
||||||
|
error = FALSE;
|
||||||
|
XErrorHandler old = XSetErrorHandler(window_error_handler);
|
||||||
|
XReparentWindow(server.dsp, traywin->win, traywin->parent, 0, 0);
|
||||||
|
XSync(server.dsp, False);
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
if (error != FALSE) {
|
||||||
|
printf("systray %d: cannot embed icon for window %lu parent %lu pid %d\n", __LINE__, traywin->win, traywin->parent, traywin->pid);
|
||||||
|
remove_icon(traywin);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch for the icon trying to resize itself / closing again
|
||||||
|
XSync(server.dsp, False);
|
||||||
|
error = FALSE;
|
||||||
|
old = XSetErrorHandler(window_error_handler);
|
||||||
|
XSelectInput(server.dsp, traywin->win, StructureNotifyMask);
|
||||||
|
XSync(server.dsp, False);
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
if (error != FALSE) {
|
||||||
|
printf("systray %d: cannot embed icon for window %lu parent %lu pid %d\n", __LINE__, traywin->win, traywin->parent, traywin->pid);
|
||||||
|
remove_icon(traywin);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
traywin->reparented = 1;
|
||||||
|
|
||||||
|
// Embed into parent
|
||||||
|
{
|
||||||
|
XEvent e;
|
||||||
|
e.xclient.type = ClientMessage;
|
||||||
|
e.xclient.serial = 0;
|
||||||
|
e.xclient.send_event = True;
|
||||||
|
e.xclient.message_type = server.atom._XEMBED;
|
||||||
|
e.xclient.window = traywin->win;
|
||||||
|
e.xclient.format = 32;
|
||||||
|
e.xclient.data.l[0] = CurrentTime;
|
||||||
|
e.xclient.data.l[1] = XEMBED_EMBEDDED_NOTIFY;
|
||||||
|
e.xclient.data.l[2] = 0;
|
||||||
|
e.xclient.data.l[3] = traywin->parent;
|
||||||
|
e.xclient.data.l[4] = 0;
|
||||||
|
XSync(server.dsp, False);
|
||||||
|
error = FALSE;
|
||||||
|
XErrorHandler old = XSetErrorHandler(window_error_handler);
|
||||||
|
XSendEvent(server.dsp, traywin->win, False, 0xFFFFFF, &e);
|
||||||
|
XSync(server.dsp, False);
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
if (error != FALSE) {
|
||||||
|
printf("systray %d: cannot embed icon for window %lu pid %d\n", __LINE__, traywin->win, traywin->pid);
|
||||||
|
remove_icon(traywin);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if window was embedded
|
||||||
|
{
|
||||||
|
Atom acttype;
|
||||||
|
int actfmt;
|
||||||
|
unsigned long nbitem, bytes;
|
||||||
|
unsigned char *data = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = XGetWindowProperty(server.dsp, traywin->win, server.atom._XEMBED_INFO, 0, 2, False, server.atom._XEMBED_INFO, &acttype, &actfmt, &nbitem, &bytes, &data);
|
||||||
|
if (ret == Success) {
|
||||||
|
if (data) {
|
||||||
|
if (nbitem == 2) {
|
||||||
|
//hide = ((data[1] & XEMBED_MAPPED) == 0);
|
||||||
|
//printf("hide %d\n", hide);
|
||||||
|
}
|
||||||
|
XFree(data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "tint2 : xembed error\n");
|
||||||
|
remove_icon(traywin);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect rendering when using compositing
|
||||||
|
if (systray_composited) {
|
||||||
|
traywin->damage = XDamageCreate(server.dsp, traywin->parent, XDamageReportRawRectangles);
|
||||||
|
XCompositeRedirectWindow(server.dsp, traywin->parent, CompositeRedirectManual);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the icon visible
|
||||||
|
if (!traywin->hide)
|
||||||
|
XMapWindow(server.dsp, traywin->win);
|
||||||
|
if (!traywin->hide && !panel->is_hidden)
|
||||||
|
XMapRaised(server.dsp, traywin->parent);
|
||||||
|
|
||||||
|
XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height);
|
||||||
|
XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
|
||||||
|
|
||||||
|
XFlush(server.dsp);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void remove_icon(TrayWindow *traywin)
|
void remove_icon(TrayWindow *traywin)
|
||||||
{
|
{
|
||||||
XErrorHandler old;
|
|
||||||
|
|
||||||
// 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: %lu\n", traywin->win);
|
||||||
|
|
||||||
XSelectInput(server.dsp, traywin->tray_id, NoEventMask);
|
XSelectInput(server.dsp, traywin->win, NoEventMask);
|
||||||
if (traywin->damage)
|
if (traywin->damage)
|
||||||
XDamageDestroy(server.dsp, traywin->damage);
|
XDamageDestroy(server.dsp, traywin->damage);
|
||||||
|
|
||||||
// reparent to root
|
// reparent to root
|
||||||
|
XSync(server.dsp, False);
|
||||||
error = FALSE;
|
error = FALSE;
|
||||||
old = XSetErrorHandler(window_error_handler);
|
XErrorHandler old = XSetErrorHandler(window_error_handler);
|
||||||
if (!traywin->hide)
|
if (!traywin->hide)
|
||||||
XUnmapWindow(server.dsp, traywin->tray_id);
|
XUnmapWindow(server.dsp, traywin->win);
|
||||||
XReparentWindow(server.dsp, traywin->tray_id, server.root_win, 0, 0);
|
XReparentWindow(server.dsp, traywin->win, server.root_win, 0, 0);
|
||||||
XDestroyWindow(server.dsp, traywin->id);
|
XDestroyWindow(server.dsp, traywin->parent);
|
||||||
XSync(server.dsp, False);
|
XSync(server.dsp, False);
|
||||||
XSetErrorHandler(old);
|
XSetErrorHandler(old);
|
||||||
stop_timeout(traywin->render_timeout);
|
stop_timeout(traywin->render_timeout);
|
||||||
@@ -574,13 +623,14 @@ void remove_icon(TrayWindow *traywin)
|
|||||||
void net_message(XClientMessageEvent *e)
|
void net_message(XClientMessageEvent *e)
|
||||||
{
|
{
|
||||||
unsigned long opcode;
|
unsigned long opcode;
|
||||||
Window id;
|
Window win;
|
||||||
|
|
||||||
opcode = e->data.l[1];
|
opcode = e->data.l[1];
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case SYSTEM_TRAY_REQUEST_DOCK:
|
case SYSTEM_TRAY_REQUEST_DOCK:
|
||||||
id = e->data.l[2];
|
win = e->data.l[2];
|
||||||
if (id) add_icon(id);
|
if (win)
|
||||||
|
add_icon(win);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYSTEM_TRAY_BEGIN_MESSAGE:
|
case SYSTEM_TRAY_BEGIN_MESSAGE:
|
||||||
@@ -597,32 +647,84 @@ void net_message(XClientMessageEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void systray_render_icon_now(void* t)
|
Display *display = NULL;
|
||||||
|
XImage *tintXGetImage(Window win)
|
||||||
|
{
|
||||||
|
char *display_name = XDisplayName(NULL);
|
||||||
|
if (!display_name)
|
||||||
|
return NULL;
|
||||||
|
if (!display)
|
||||||
|
display = XOpenDisplay(display_name);
|
||||||
|
if (!display)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
unsigned int border_width;
|
||||||
|
int xpos, ypos;
|
||||||
|
unsigned int width, height, depth;
|
||||||
|
Window root;
|
||||||
|
if (!XGetGeometry(display, win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) {
|
||||||
|
fprintf(stderr, "Couldn't get geometry of window!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return XGetImage(display, win, 0, 0, width, height, AllPlanes, XYPixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void systray_render_icon_composited(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;
|
// wine tray icons update whenever mouse is over them, so we limit the updates to 50 ms
|
||||||
|
struct timespec now;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
struct timespec earliest_render = add_msec_to_timespec(traywin->time_last_render, 50);
|
||||||
|
if (compare_timespecs(&earliest_render, &now) > 0) {
|
||||||
|
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
traywin->time_last_render.tv_sec = now.tv_sec;
|
||||||
|
traywin->time_last_render.tv_nsec = now.tv_nsec;
|
||||||
|
|
||||||
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)
|
||||||
systray_render_icon(traywin);
|
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (traywin->render_timeout) {
|
||||||
|
stop_timeout(traywin->render_timeout);
|
||||||
|
traywin->render_timeout = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int empty = 1;
|
int empty = 1;
|
||||||
XImage *ximage = XGetImage(server.dsp, traywin->tray_id, 0, 0, traywin->width, traywin->height, AllPlanes, XYPixmap);
|
XImage *ximage = tintXGetImage(traywin->win);
|
||||||
if (ximage) {
|
if (ximage) {
|
||||||
|
if (ximage->width != traywin->width ||
|
||||||
|
ximage->height != traywin->height) {
|
||||||
|
XFree(ximage);
|
||||||
|
XCloseDisplay(display);
|
||||||
|
display = NULL;
|
||||||
|
XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
XColor color;
|
XColor color;
|
||||||
|
if (ximage->width > 0 && ximage->height > 0) {
|
||||||
|
color.pixel = XGetPixel(ximage, ximage->width/2, ximage->height/2);
|
||||||
|
if (color.pixel != 0)
|
||||||
|
empty = 0;
|
||||||
int x, y;
|
int x, y;
|
||||||
for (x = 0; empty && x < traywin->width; x++) {
|
for (x = 0; empty && x < ximage->width; x++) {
|
||||||
for (y = 0; empty && y < traywin->height; y++) {
|
for (y = 0; empty && y < ximage->height; y++) {
|
||||||
color.pixel = XGetPixel(ximage, x, y);
|
color.pixel = XGetPixel(ximage, x, y);
|
||||||
if (color.pixel != 0)
|
if (color.pixel != 0)
|
||||||
empty = 0;
|
empty = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
XFree(ximage);
|
XFree(ximage);
|
||||||
|
XCloseDisplay(display);
|
||||||
|
display = NULL;
|
||||||
}
|
}
|
||||||
if (traywin->empty != empty) {
|
if (traywin->empty != empty) {
|
||||||
traywin->empty = empty;
|
traywin->empty = empty;
|
||||||
@@ -630,7 +732,7 @@ void systray_render_icon_now(void* t)
|
|||||||
panel_refresh = 1;
|
panel_refresh = 1;
|
||||||
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
||||||
}
|
}
|
||||||
//printf("systray_render_icon_now: %d empty %d\n", traywin->tray_id, empty);
|
//printf("systray_render_icon_now: %d empty %d\n", traywin->win, empty);
|
||||||
if (empty)
|
if (empty)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -642,22 +744,46 @@ void systray_render_icon_now(void* t)
|
|||||||
// Very ugly hack, but somehow imlib2 is not able to get the image from the traywindow itself,
|
// Very ugly hack, but somehow imlib2 is not able to get the image from the traywindow itself,
|
||||||
// so we first render the tray window onto a pixmap, and then we tell imlib2 to use this pixmap as
|
// so we first render the tray window onto a pixmap, and then we tell imlib2 to use this pixmap as
|
||||||
// drawable. If someone knows why it does not work with the traywindow itself, please tell me ;)
|
// drawable. If someone knows why it does not work with the traywindow itself, please tell me ;)
|
||||||
Pixmap tmp_pmap = XCreatePixmap(server.dsp, server.root_win, traywin->width, traywin->height, 32);
|
Pixmap tmp_pmap = XCreatePixmap(server.dsp, traywin->win, traywin->width, traywin->height, 32);
|
||||||
XRenderPictFormat* f;
|
if (!tmp_pmap) {
|
||||||
if (traywin->depth == 24)
|
goto on_systray_error;
|
||||||
|
}
|
||||||
|
XRenderPictFormat *f;
|
||||||
|
if (traywin->depth == 24) {
|
||||||
f = XRenderFindStandardFormat(server.dsp, PictStandardRGB24);
|
f = XRenderFindStandardFormat(server.dsp, PictStandardRGB24);
|
||||||
else if (traywin->depth == 32)
|
} else if (traywin->depth == 32) {
|
||||||
f = XRenderFindStandardFormat(server.dsp, PictStandardARGB32);
|
f = XRenderFindStandardFormat(server.dsp, PictStandardARGB32);
|
||||||
else {
|
} else {
|
||||||
printf("Strange tray icon found with depth: %d\n", traywin->depth);
|
printf("Strange tray icon found with depth: %d\n", traywin->depth);
|
||||||
|
XFreePixmap(server.dsp, tmp_pmap);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Picture pict_image;
|
XRenderPictFormat *f32 = XRenderFindVisualFormat(server.dsp, server.visual32);
|
||||||
|
if (!f || !f32) {
|
||||||
|
XFreePixmap(server.dsp, tmp_pmap);
|
||||||
|
goto on_systray_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
XSync(server.dsp, False);
|
||||||
|
error = FALSE;
|
||||||
|
XErrorHandler old = XSetErrorHandler(window_error_handler);
|
||||||
|
|
||||||
//if (server.real_transparency)
|
//if (server.real_transparency)
|
||||||
//pict_image = XRenderCreatePicture(server.dsp, traywin->id, f, 0, 0);
|
//Picture pict_image = XRenderCreatePicture(server.dsp, traywin->parent, f, 0, 0);
|
||||||
// reverted Rev 407 because here it's breaking alls icon with systray + xcompmgr
|
// reverted Rev 407 because here it's breaking alls icon with systray + xcompmgr
|
||||||
pict_image = XRenderCreatePicture(server.dsp, traywin->tray_id, f, 0, 0);
|
Picture pict_image = XRenderCreatePicture(server.dsp, traywin->win, f, 0, 0);
|
||||||
|
if (!pict_image) {
|
||||||
|
XFreePixmap(server.dsp, tmp_pmap);
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
Picture pict_drawable = XRenderCreatePicture(server.dsp, tmp_pmap, XRenderFindVisualFormat(server.dsp, server.visual32), 0, 0);
|
Picture pict_drawable = XRenderCreatePicture(server.dsp, tmp_pmap, XRenderFindVisualFormat(server.dsp, server.visual32), 0, 0);
|
||||||
|
if (!pict_drawable) {
|
||||||
|
XRenderFreePicture(server.dsp, pict_image);
|
||||||
|
XFreePixmap(server.dsp, tmp_pmap);
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
XRenderComposite(server.dsp, PictOpSrc, pict_image, None, pict_drawable, 0, 0, 0, 0, 0, 0, traywin->width, traywin->height);
|
XRenderComposite(server.dsp, PictOpSrc, pict_image, None, pict_drawable, 0, 0, 0, 0, 0, 0, traywin->width, traywin->height);
|
||||||
XRenderFreePicture(server.dsp, pict_image);
|
XRenderFreePicture(server.dsp, pict_image);
|
||||||
XRenderFreePicture(server.dsp, pict_drawable);
|
XRenderFreePicture(server.dsp, pict_drawable);
|
||||||
@@ -667,8 +793,13 @@ void systray_render_icon_now(void* t)
|
|||||||
imlib_context_set_colormap(server.colormap32);
|
imlib_context_set_colormap(server.colormap32);
|
||||||
imlib_context_set_drawable(tmp_pmap);
|
imlib_context_set_drawable(tmp_pmap);
|
||||||
Imlib_Image image = imlib_create_image_from_drawable(0, 0, 0, traywin->width, traywin->height, 1);
|
Imlib_Image image = imlib_create_image_from_drawable(0, 0, 0, traywin->width, traywin->height, 1);
|
||||||
if (image == 0)
|
if (!image) {
|
||||||
return;
|
imlib_context_set_visual(server.visual);
|
||||||
|
imlib_context_set_colormap(server.colormap);
|
||||||
|
XFreePixmap(server.dsp, tmp_pmap);
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
imlib_context_set_image(image);
|
imlib_context_set_image(image);
|
||||||
//if (traywin->depth == 24)
|
//if (traywin->depth == 24)
|
||||||
@@ -692,21 +823,40 @@ void systray_render_icon_now(void* t)
|
|||||||
if (traywin->damage)
|
if (traywin->damage)
|
||||||
XDamageSubtract(server.dsp, traywin->damage, None, None);
|
XDamageSubtract(server.dsp, traywin->damage, None, None);
|
||||||
XFlush(server.dsp);
|
XFlush(server.dsp);
|
||||||
|
|
||||||
|
XSync(server.dsp, False);
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
printf("systray %d: rendering error for icon %lu pid %d\n", __LINE__, traywin->win, traywin->pid);
|
||||||
|
return;
|
||||||
|
|
||||||
|
on_systray_error:
|
||||||
|
printf("systray %d: rendering error for icon %lu pid %d. Disabling compositing and restarting systray...\n", __LINE__, traywin->win, traywin->pid);
|
||||||
|
systray_composited = 0;
|
||||||
|
stop_net();
|
||||||
|
start_net();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void systray_render_icon(TrayWindow* traywin)
|
void systray_render_icon(TrayWindow* traywin)
|
||||||
{
|
{
|
||||||
if (FORCE_COMPOSITED_RENDERING || server.real_transparency || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0) {
|
if (!reparent_icon(traywin))
|
||||||
// wine tray icons update whenever mouse is over them, so we limit the updates to 50 ms
|
return;
|
||||||
|
|
||||||
|
if (systray_composited) {
|
||||||
if (!traywin->render_timeout)
|
if (!traywin->render_timeout)
|
||||||
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_now, traywin, &traywin->render_timeout);
|
systray_render_icon_composited(traywin);
|
||||||
}
|
} else {
|
||||||
else {
|
// Trigger window repaint
|
||||||
// Pixmap pix = XCreatePixmap(server.dsp, server.root_win, traywin->width, traywin->height, server.depth);
|
XClearArea(server.dsp, traywin->parent, 0, 0, traywin->width, traywin->height, True);
|
||||||
// XCopyArea(server.dsp, panel->temp_pmap, pix, server.gc, traywin->x, traywin->y, traywin->width, traywin->height, 0, 0);
|
XClearArea(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height, True);
|
||||||
// XSetWindowBackgroundPixmap(server.dsp, traywin->id, pix);
|
|
||||||
XClearArea(server.dsp, traywin->tray_id, 0, 0, traywin->width, traywin->height, True);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
Window id;
|
Window parent;
|
||||||
Window tray_id;
|
Window win;
|
||||||
int x, y;
|
int x, y;
|
||||||
int width, height;
|
int width, height;
|
||||||
// TODO: manage icon's show/hide
|
// TODO: manage icon's show/hide
|
||||||
@@ -47,6 +47,8 @@ typedef struct
|
|||||||
int empty;
|
int empty;
|
||||||
int pid;
|
int pid;
|
||||||
int chrono;
|
int chrono;
|
||||||
|
struct timespec time_last_render;
|
||||||
|
int reparented;
|
||||||
} TrayWindow;
|
} TrayWindow;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ Task *add_task (Window win)
|
|||||||
}
|
}
|
||||||
new_tsk2->icon_width = new_tsk.icon_width;
|
new_tsk2->icon_width = new_tsk.icon_width;
|
||||||
new_tsk2->icon_height = new_tsk.icon_height;
|
new_tsk2->icon_height = new_tsk.icon_height;
|
||||||
tskbar->area.list = g_slist_append(tskbar->area.list, new_tsk2);
|
tskbar->area.list = g_list_append(tskbar->area.list, new_tsk2);
|
||||||
tskbar->area.resize = 1;
|
tskbar->area.resize = 1;
|
||||||
g_ptr_array_add(task_group, new_tsk2);
|
g_ptr_array_add(task_group, new_tsk2);
|
||||||
//printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title);
|
//printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title);
|
||||||
@@ -169,7 +169,7 @@ void remove_task (Task *tsk)
|
|||||||
for (i=0; i<task_group->len; ++i) {
|
for (i=0; i<task_group->len; ++i) {
|
||||||
tsk2 = g_ptr_array_index(task_group, i);
|
tsk2 = g_ptr_array_index(task_group, i);
|
||||||
tskbar = tsk2->area.parent;
|
tskbar = tsk2->area.parent;
|
||||||
tskbar->area.list = g_slist_remove(tskbar->area.list, tsk2);
|
tskbar->area.list = g_list_remove(tskbar->area.list, tsk2);
|
||||||
tskbar->area.resize = 1;
|
tskbar->area.resize = 1;
|
||||||
if (tsk2 == task_active) task_active = 0;
|
if (tsk2 == task_active) task_active = 0;
|
||||||
if (tsk2 == task_drag) task_drag = 0;
|
if (tsk2 == task_drag) task_drag = 0;
|
||||||
@@ -424,15 +424,13 @@ Task *find_active_task(Task *current_task, Task *active_task)
|
|||||||
if (active_task == NULL)
|
if (active_task == NULL)
|
||||||
return current_task;
|
return current_task;
|
||||||
|
|
||||||
GSList *l0;
|
|
||||||
Task *tsk;
|
|
||||||
Taskbar* tskbar = current_task->area.parent;
|
Taskbar* tskbar = current_task->area.parent;
|
||||||
|
|
||||||
l0 = tskbar->area.list;
|
GList *l0 = tskbar->area.list;
|
||||||
if (taskbarname_enabled)
|
if (taskbarname_enabled)
|
||||||
l0 = l0->next;
|
l0 = l0->next;
|
||||||
for (; l0 ; l0 = l0->next) {
|
for (; l0 ; l0 = l0->next) {
|
||||||
tsk = l0->data;
|
Task *tsk = l0->data;
|
||||||
if (tsk->win == active_task->win)
|
if (tsk->win == active_task->win)
|
||||||
return tsk;
|
return tsk;
|
||||||
}
|
}
|
||||||
@@ -445,15 +443,13 @@ Task *next_task(Task *tsk)
|
|||||||
if (tsk == 0)
|
if (tsk == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
GSList *l0, *lfirst_tsk;
|
|
||||||
Task *tsk1;
|
|
||||||
Taskbar* tskbar = tsk->area.parent;
|
Taskbar* tskbar = tsk->area.parent;
|
||||||
|
|
||||||
l0 = tskbar->area.list;
|
GList *l0 = tskbar->area.list;
|
||||||
if (taskbarname_enabled) l0 = l0->next;
|
if (taskbarname_enabled) l0 = l0->next;
|
||||||
lfirst_tsk = l0;
|
GList *lfirst_tsk = l0;
|
||||||
for (; l0 ; l0 = l0->next) {
|
for (; l0 ; l0 = l0->next) {
|
||||||
tsk1 = l0->data;
|
Task *tsk1 = l0->data;
|
||||||
if (tsk1 == tsk) {
|
if (tsk1 == tsk) {
|
||||||
if (l0->next == 0) l0 = lfirst_tsk;
|
if (l0->next == 0) l0 = lfirst_tsk;
|
||||||
else l0 = l0->next;
|
else l0 = l0->next;
|
||||||
@@ -469,19 +465,18 @@ Task *prev_task(Task *tsk)
|
|||||||
if (tsk == 0)
|
if (tsk == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
GSList *l0, *lfirst_tsk;
|
|
||||||
Task *tsk1, *tsk2;
|
Task *tsk1, *tsk2;
|
||||||
Taskbar* tskbar = tsk->area.parent;
|
Taskbar* tskbar = tsk->area.parent;
|
||||||
|
|
||||||
tsk2 = 0;
|
tsk2 = 0;
|
||||||
l0 = tskbar->area.list;
|
GList *l0 = tskbar->area.list;
|
||||||
if (taskbarname_enabled) l0 = l0->next;
|
if (taskbarname_enabled) l0 = l0->next;
|
||||||
lfirst_tsk = l0;
|
GList *lfirst_tsk = l0;
|
||||||
for (; l0 ; l0 = l0->next) {
|
for (; l0 ; l0 = l0->next) {
|
||||||
tsk1 = l0->data;
|
tsk1 = l0->data;
|
||||||
if (tsk1 == tsk) {
|
if (tsk1 == tsk) {
|
||||||
if (l0 == lfirst_tsk) {
|
if (l0 == lfirst_tsk) {
|
||||||
l0 = g_slist_last ( l0 );
|
l0 = g_list_last ( l0 );
|
||||||
tsk2 = l0->data;
|
tsk2 = l0->data;
|
||||||
}
|
}
|
||||||
return tsk2;
|
return tsk2;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ int taskbar_distribute_size;
|
|||||||
int hide_inactive_tasks;
|
int hide_inactive_tasks;
|
||||||
int hide_task_diff_monitor;
|
int hide_task_diff_monitor;
|
||||||
int taskbar_sort_method;
|
int taskbar_sort_method;
|
||||||
|
int taskbar_alignment;
|
||||||
|
|
||||||
guint win_hash(gconstpointer key) { return (guint)*((Window*)key); }
|
guint win_hash(gconstpointer key) { return (guint)*((Window*)key); }
|
||||||
gboolean win_compare(gconstpointer a, gconstpointer b) { return (*((Window*)a) == *((Window*)b)); }
|
gboolean win_compare(gconstpointer a, gconstpointer b) { return (*((Window*)a) == *((Window*)b)); }
|
||||||
@@ -63,6 +64,7 @@ void default_taskbar()
|
|||||||
hide_inactive_tasks = 0;
|
hide_inactive_tasks = 0;
|
||||||
hide_task_diff_monitor = 0;
|
hide_task_diff_monitor = 0;
|
||||||
taskbar_sort_method = TASKBAR_NOSORT;
|
taskbar_sort_method = TASKBAR_NOSORT;
|
||||||
|
taskbar_alignment = ALIGN_LEFT;
|
||||||
default_taskbarname();
|
default_taskbarname();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@ void cleanup_taskbar()
|
|||||||
}
|
}
|
||||||
free_area(&tskbar->area);
|
free_area(&tskbar->area);
|
||||||
// remove taskbar from the panel
|
// remove taskbar from the panel
|
||||||
panel->area.list = g_slist_remove(panel->area.list, tskbar);
|
panel->area.list = g_list_remove(panel->area.list, tskbar);
|
||||||
}
|
}
|
||||||
if (panel->taskbar) {
|
if (panel->taskbar) {
|
||||||
free(panel->taskbar);
|
free(panel->taskbar);
|
||||||
@@ -153,6 +155,7 @@ void init_taskbar_panel(void *p)
|
|||||||
panel->g_taskbar.area.parent = panel;
|
panel->g_taskbar.area.parent = panel;
|
||||||
panel->g_taskbar.area.panel = panel;
|
panel->g_taskbar.area.panel = panel;
|
||||||
panel->g_taskbar.area.size_mode = SIZE_BY_LAYOUT;
|
panel->g_taskbar.area.size_mode = SIZE_BY_LAYOUT;
|
||||||
|
panel->g_taskbar.area.alignment = taskbar_alignment;
|
||||||
panel->g_taskbar.area._resize = resize_taskbar;
|
panel->g_taskbar.area._resize = resize_taskbar;
|
||||||
panel->g_taskbar.area._draw_foreground = draw_taskbar;
|
panel->g_taskbar.area._draw_foreground = draw_taskbar;
|
||||||
panel->g_taskbar.area._on_change_layout = on_change_taskbar;
|
panel->g_taskbar.area._on_change_layout = on_change_taskbar;
|
||||||
@@ -334,7 +337,7 @@ int resize_taskbar(void *obj)
|
|||||||
resize_by_layout(obj, panel->g_task.maximum_width);
|
resize_by_layout(obj, panel->g_task.maximum_width);
|
||||||
|
|
||||||
text_width = panel->g_task.maximum_width;
|
text_width = panel->g_task.maximum_width;
|
||||||
GSList *l = taskbar->area.list;
|
GList *l = taskbar->area.list;
|
||||||
if (taskbarname_enabled) l = l->next;
|
if (taskbarname_enabled) l = l->next;
|
||||||
for (; l != NULL; l = l->next) {
|
for (; l != NULL; l = l->next) {
|
||||||
if (((Task *)l->data)->area.on_screen) {
|
if (((Task *)l->data)->area.on_screen) {
|
||||||
@@ -388,7 +391,7 @@ void set_taskbar_state(Taskbar *tskbar, int state)
|
|||||||
if (taskbarname_enabled && tskbar->bar_name.state_pix[state] == 0)
|
if (taskbarname_enabled && tskbar->bar_name.state_pix[state] == 0)
|
||||||
tskbar->bar_name.area.redraw = 1;
|
tskbar->bar_name.area.redraw = 1;
|
||||||
if (panel_mode == MULTI_DESKTOP && panel1[0].g_taskbar.background[TASKBAR_NORMAL] != panel1[0].g_taskbar.background[TASKBAR_ACTIVE]) {
|
if (panel_mode == MULTI_DESKTOP && panel1[0].g_taskbar.background[TASKBAR_NORMAL] != panel1[0].g_taskbar.background[TASKBAR_ACTIVE]) {
|
||||||
GSList *l = tskbar->area.list;
|
GList *l = tskbar->area.list;
|
||||||
if (taskbarname_enabled) l = l->next;
|
if (taskbarname_enabled) l = l->next;
|
||||||
for ( ; l ; l = l->next)
|
for ( ; l ; l = l->next)
|
||||||
set_task_redraw(l->data);
|
set_task_redraw(l->data);
|
||||||
@@ -511,7 +514,7 @@ int taskbar_needs_sort(Taskbar *taskbar)
|
|||||||
if (taskbar_sort_method == TASKBAR_NOSORT)
|
if (taskbar_sort_method == TASKBAR_NOSORT)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
GSList *i, *j;
|
GList *i, *j;
|
||||||
for (i = taskbar->area.list, j = i ? i->next : NULL; i && j; i = i->next, j = j->next) {
|
for (i = taskbar->area.list, j = i ? i->next : NULL; i && j; i = i->next, j = j->next) {
|
||||||
if (compare_tasks(i->data, j->data, taskbar) > 0) {
|
if (compare_tasks(i->data, j->data, taskbar) > 0) {
|
||||||
return 1;
|
return 1;
|
||||||
@@ -528,7 +531,7 @@ void sort_tasks(Taskbar *taskbar)
|
|||||||
if (!taskbar_needs_sort(taskbar)) {
|
if (!taskbar_needs_sort(taskbar)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
taskbar->area.list = g_slist_sort_with_data(taskbar->area.list, (GCompareDataFunc)compare_tasks, taskbar);
|
taskbar->area.list = g_list_sort_with_data(taskbar->area.list, (GCompareDataFunc)compare_tasks, taskbar);
|
||||||
taskbar->area.resize = 1;
|
taskbar->area.resize = 1;
|
||||||
panel_refresh = 1;
|
panel_refresh = 1;
|
||||||
((Panel*)taskbar->area.panel)->area.resize = 1;
|
((Panel*)taskbar->area.panel)->area.resize = 1;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ extern int hide_inactive_tasks;
|
|||||||
extern int hide_task_diff_monitor;
|
extern int hide_task_diff_monitor;
|
||||||
enum { TASKBAR_NOSORT, TASKBAR_SORT_CENTER, TASKBAR_SORT_TITLE };
|
enum { TASKBAR_NOSORT, TASKBAR_SORT_CENTER, TASKBAR_SORT_TITLE };
|
||||||
extern int taskbar_sort_method;
|
extern int taskbar_sort_method;
|
||||||
|
extern int taskbar_alignment;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// always start with area
|
// always start with area
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ void init_taskbarname_panel(void *p)
|
|||||||
tskbar->bar_name.name = g_strdup_printf("%d", j+1);
|
tskbar->bar_name.name = g_strdup_printf("%d", j+1);
|
||||||
|
|
||||||
// append the name at the beginning of taskbar
|
// append the name at the beginning of taskbar
|
||||||
tskbar->area.list = g_slist_append(tskbar->area.list, &tskbar->bar_name);
|
tskbar->area.list = g_list_append(tskbar->area.list, &tskbar->bar_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (l=list ; l ; l = l->next)
|
for (l=list ; l ; l = l->next)
|
||||||
@@ -103,7 +103,7 @@ void cleanup_taskbarname()
|
|||||||
XFreePixmap(server.dsp, tskbar->bar_name.state_pix[k]);
|
XFreePixmap(server.dsp, tskbar->bar_name.state_pix[k]);
|
||||||
tskbar->bar_name.state_pix[k] = 0;
|
tskbar->bar_name.state_pix[k] = 0;
|
||||||
}
|
}
|
||||||
tskbar->area.list = g_slist_remove(tskbar->area.list, &tskbar->bar_name);
|
tskbar->area.list = g_list_remove(tskbar->area.list, &tskbar->bar_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
43
src/tint.c
43
src/tint.c
@@ -117,12 +117,12 @@ void init (int argc, char *argv[])
|
|||||||
// BSD does not support pselect(), therefore we have to use select and hope that we do not
|
// BSD does not support pselect(), therefore we have to use select and hope that we do not
|
||||||
// end up in a race condition there (see 'man select()' on a linux machine for more information)
|
// end up in a race condition there (see 'man select()' on a linux machine for more information)
|
||||||
// block all signals, such that no race conditions occur before pselect in our main loop
|
// block all signals, such that no race conditions occur before pselect in our main loop
|
||||||
// sigset_t block_mask;
|
// sigset_t block_mask;
|
||||||
// sigaddset(&block_mask, SIGINT);
|
// sigaddset(&block_mask, SIGINT);
|
||||||
// sigaddset(&block_mask, SIGTERM);
|
// sigaddset(&block_mask, SIGTERM);
|
||||||
// sigaddset(&block_mask, SIGHUP);
|
// sigaddset(&block_mask, SIGHUP);
|
||||||
// sigaddset(&block_mask, SIGUSR1);
|
// sigaddset(&block_mask, SIGUSR1);
|
||||||
// sigprocmask(SIG_BLOCK, &block_mask, 0);
|
// sigprocmask(SIG_BLOCK, &block_mask, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sn_pipe_valid = 0;
|
static int sn_pipe_valid = 0;
|
||||||
@@ -470,8 +470,8 @@ void event_button_motion_notify (XEvent *e)
|
|||||||
} else {
|
} else {
|
||||||
// Swap the task_drag with the task on the event's location (if they differ)
|
// Swap the task_drag with the task on the event's location (if they differ)
|
||||||
if(event_task && event_task != task_drag) {
|
if(event_task && event_task != task_drag) {
|
||||||
GSList * drag_iter = g_slist_find(event_taskbar->area.list, task_drag);
|
GList * drag_iter = g_list_find(event_taskbar->area.list, task_drag);
|
||||||
GSList * task_iter = g_slist_find(event_taskbar->area.list, event_task);
|
GList * task_iter = g_list_find(event_taskbar->area.list, event_task);
|
||||||
if(drag_iter && task_iter) {
|
if(drag_iter && task_iter) {
|
||||||
gpointer temp = task_iter->data;
|
gpointer temp = task_iter->data;
|
||||||
task_iter->data = drag_iter->data;
|
task_iter->data = drag_iter->data;
|
||||||
@@ -488,14 +488,14 @@ void event_button_motion_notify (XEvent *e)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Taskbar * drag_taskbar = (Taskbar*)task_drag->area.parent;
|
Taskbar * drag_taskbar = (Taskbar*)task_drag->area.parent;
|
||||||
drag_taskbar->area.list = g_slist_remove(drag_taskbar->area.list, task_drag);
|
drag_taskbar->area.list = g_list_remove(drag_taskbar->area.list, task_drag);
|
||||||
|
|
||||||
if(event_taskbar->area.posx > drag_taskbar->area.posx || event_taskbar->area.posy > drag_taskbar->area.posy) {
|
if(event_taskbar->area.posx > drag_taskbar->area.posx || event_taskbar->area.posy > drag_taskbar->area.posy) {
|
||||||
int i = (taskbarname_enabled) ? 1 : 0;
|
int i = (taskbarname_enabled) ? 1 : 0;
|
||||||
event_taskbar->area.list = g_slist_insert(event_taskbar->area.list, task_drag, i);
|
event_taskbar->area.list = g_list_insert(event_taskbar->area.list, task_drag, i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
event_taskbar->area.list = g_slist_append(event_taskbar->area.list, task_drag);
|
event_taskbar->area.list = g_list_append(event_taskbar->area.list, task_drag);
|
||||||
|
|
||||||
// Move task to other desktop (but avoid the 'Window desktop changed' code in 'event_property_notify')
|
// Move task to other desktop (but avoid the 'Window desktop changed' code in 'event_property_notify')
|
||||||
task_drag->area.parent = event_taskbar;
|
task_drag->area.parent = event_taskbar;
|
||||||
@@ -677,10 +677,9 @@ void event_property_notify (XEvent *e)
|
|||||||
// check ALLDESKTOP task => resize taskbar
|
// check ALLDESKTOP task => resize taskbar
|
||||||
Taskbar *tskbar;
|
Taskbar *tskbar;
|
||||||
Task *tsk;
|
Task *tsk;
|
||||||
GSList *l;
|
|
||||||
if (server.nb_desktop > old_desktop) {
|
if (server.nb_desktop > old_desktop) {
|
||||||
tskbar = &panel->taskbar[old_desktop];
|
tskbar = &panel->taskbar[old_desktop];
|
||||||
l = tskbar->area.list;
|
GList *l = tskbar->area.list;
|
||||||
if (taskbarname_enabled) l = l->next;
|
if (taskbarname_enabled) l = l->next;
|
||||||
for (; l ; l = l->next) {
|
for (; l ; l = l->next) {
|
||||||
tsk = l->data;
|
tsk = l->data;
|
||||||
@@ -694,7 +693,7 @@ void event_property_notify (XEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tskbar = &panel->taskbar[server.desktop];
|
tskbar = &panel->taskbar[server.desktop];
|
||||||
l = tskbar->area.list;
|
GList *l = tskbar->area.list;
|
||||||
if (taskbarname_enabled) l = l->next;
|
if (taskbarname_enabled) l = l->next;
|
||||||
for (; l ; l = l->next) {
|
for (; l ; l = l->next) {
|
||||||
tsk = l->data;
|
tsk = l->data;
|
||||||
@@ -831,11 +830,13 @@ void event_configure_notify (Window win)
|
|||||||
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->tray_id == win) {
|
if (traywin->win == win) {
|
||||||
//printf("move tray %d\n", traywin->x);
|
//printf("move tray %d\n", traywin->x);
|
||||||
XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y, traywin->width, traywin->height);
|
XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height);
|
||||||
XResizeWindow(server.dsp, traywin->tray_id, traywin->width, traywin->height);
|
if (traywin->reparented)
|
||||||
|
XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
|
||||||
panel_refresh = 1;
|
panel_refresh = 1;
|
||||||
|
refresh_systray = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1126,8 +1127,8 @@ start:
|
|||||||
dnd_sent_request = 0;
|
dnd_sent_request = 0;
|
||||||
dnd_launcher_exec = 0;
|
dnd_launcher_exec = 0;
|
||||||
|
|
||||||
// sigset_t empty_mask;
|
// sigset_t empty_mask;
|
||||||
// sigemptyset(&empty_mask);
|
// sigemptyset(&empty_mask);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (panel_refresh) {
|
if (panel_refresh) {
|
||||||
@@ -1268,7 +1269,7 @@ start:
|
|||||||
if (e.xany.window == g_tooltip.window || !systray_enabled)
|
if (e.xany.window == g_tooltip.window || !systray_enabled)
|
||||||
break;
|
break;
|
||||||
for (it = systray.list_icons; it; it = g_slist_next(it)) {
|
for (it = systray.list_icons; it; it = g_slist_next(it)) {
|
||||||
if (((TrayWindow*)it->data)->tray_id == e.xany.window) {
|
if (((TrayWindow*)it->data)->win == e.xany.window) {
|
||||||
remove_icon((TrayWindow*)it->data);
|
remove_icon((TrayWindow*)it->data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1413,7 +1414,7 @@ start:
|
|||||||
XDamageNotifyEvent* de = &event_union.de;
|
XDamageNotifyEvent* de = &event_union.de;
|
||||||
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->id == de->drawable ) {
|
if ( traywin->parent == de->drawable ) {
|
||||||
systray_render_icon(traywin);
|
systray_render_icon(traywin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
1834
src/tint2conf/po/pl.po
Normal file
1834
src/tint2conf/po/pl.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -47,7 +47,7 @@ GtkWidget *taskbar_hide_inactive_tasks, *taskbar_hide_diff_monitor;
|
|||||||
GtkWidget *taskbar_name_padding_x, *taskbar_name_padding_y, *taskbar_name_inactive_color, *taskbar_name_active_color, *taskbar_name_font;
|
GtkWidget *taskbar_name_padding_x, *taskbar_name_padding_y, *taskbar_name_inactive_color, *taskbar_name_active_color, *taskbar_name_font;
|
||||||
GtkWidget *taskbar_active_background, *taskbar_inactive_background;
|
GtkWidget *taskbar_active_background, *taskbar_inactive_background;
|
||||||
GtkWidget *taskbar_name_active_background, *taskbar_name_inactive_background;
|
GtkWidget *taskbar_name_active_background, *taskbar_name_inactive_background;
|
||||||
GtkWidget *taskbar_distribute_size, *taskbar_sort_order;
|
GtkWidget *taskbar_distribute_size, *taskbar_sort_order, *taskbar_alignment;
|
||||||
|
|
||||||
// task
|
// task
|
||||||
GtkWidget *task_mouse_left, *task_mouse_middle, *task_mouse_right, *task_mouse_scroll_up, *task_mouse_scroll_down;
|
GtkWidget *task_mouse_left, *task_mouse_middle, *task_mouse_right, *task_mouse_scroll_up, *task_mouse_scroll_down;
|
||||||
@@ -1263,6 +1263,11 @@ void create_panel_items(GtkWidget *parent)
|
|||||||
itemsColName, _("Launcher"),
|
itemsColName, _("Launcher"),
|
||||||
itemsColValue, "L",
|
itemsColValue, "L",
|
||||||
-1);
|
-1);
|
||||||
|
gtk_list_store_append(all_items, &iter);
|
||||||
|
gtk_list_store_set(all_items, &iter,
|
||||||
|
itemsColName, _("Free space"),
|
||||||
|
itemsColValue, "F",
|
||||||
|
-1);
|
||||||
|
|
||||||
panel_items_view = gtk_tree_view_new();
|
panel_items_view = gtk_tree_view_new();
|
||||||
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(panel_items_view),
|
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(panel_items_view),
|
||||||
@@ -1441,6 +1446,9 @@ void set_panel_items(const char *items)
|
|||||||
} else if (v == 'L') {
|
} else if (v == 'L') {
|
||||||
value = "L";
|
value = "L";
|
||||||
name = _("Launcher");
|
name = _("Launcher");
|
||||||
|
} else if (v == 'F') {
|
||||||
|
value = "F";
|
||||||
|
name = _("Free space");
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -2317,6 +2325,24 @@ void create_taskbar(GtkWidget *parent)
|
|||||||
"'By title' means that tasks are sorted by their window titles. \n"
|
"'By title' means that tasks are sorted by their window titles. \n"
|
||||||
"'By center' means that tasks are sorted geometrically by their window centers."), NULL);
|
"'By center' means that tasks are sorted geometrically by their window centers."), NULL);
|
||||||
|
|
||||||
|
row++;
|
||||||
|
col = 2;
|
||||||
|
label = gtk_label_new(_("Task alignment"));
|
||||||
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
|
||||||
|
gtk_widget_show(label);
|
||||||
|
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
|
||||||
|
col++;
|
||||||
|
|
||||||
|
taskbar_alignment = gtk_combo_box_new_text();
|
||||||
|
gtk_widget_show(taskbar_alignment);
|
||||||
|
gtk_table_attach(GTK_TABLE(table), taskbar_alignment, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
|
||||||
|
col++;
|
||||||
|
gtk_combo_box_append_text(GTK_COMBO_BOX(taskbar_alignment), _("Left"));
|
||||||
|
gtk_combo_box_append_text(GTK_COMBO_BOX(taskbar_alignment), _("Center"));
|
||||||
|
gtk_combo_box_append_text(GTK_COMBO_BOX(taskbar_alignment), _("Right"));
|
||||||
|
gtk_combo_box_set_active(GTK_COMBO_BOX(taskbar_alignment), 0);
|
||||||
|
gtk_tooltips_set_tip(tooltips, taskbar_alignment, _("Specifies how tasks should be positioned on the taskbar."), NULL);
|
||||||
|
|
||||||
change_paragraph(parent);
|
change_paragraph(parent);
|
||||||
|
|
||||||
label = gtk_label_new(_("<b>Appearance</b>"));
|
label = gtk_label_new(_("<b>Appearance</b>"));
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ extern GtkWidget *taskbar_hide_inactive_tasks, *taskbar_hide_diff_monitor;
|
|||||||
extern GtkWidget *taskbar_name_padding_x, *taskbar_name_padding_y, *taskbar_name_inactive_color, *taskbar_name_active_color, *taskbar_name_font;
|
extern GtkWidget *taskbar_name_padding_x, *taskbar_name_padding_y, *taskbar_name_inactive_color, *taskbar_name_active_color, *taskbar_name_font;
|
||||||
extern GtkWidget *taskbar_active_background, *taskbar_inactive_background;
|
extern GtkWidget *taskbar_active_background, *taskbar_inactive_background;
|
||||||
extern GtkWidget *taskbar_name_active_background, *taskbar_name_inactive_background;
|
extern GtkWidget *taskbar_name_active_background, *taskbar_name_inactive_background;
|
||||||
extern GtkWidget *taskbar_distribute_size, *taskbar_sort_order;
|
extern GtkWidget *taskbar_distribute_size, *taskbar_sort_order, *taskbar_alignment;
|
||||||
|
|
||||||
// task
|
// task
|
||||||
extern GtkWidget *task_mouse_left, *task_mouse_middle, *task_mouse_right, *task_mouse_scroll_up, *task_mouse_scroll_down;
|
extern GtkWidget *task_mouse_left, *task_mouse_middle, *task_mouse_right, *task_mouse_scroll_up, *task_mouse_scroll_down;
|
||||||
|
|||||||
@@ -272,6 +272,16 @@ void config_write_taskbar(FILE *fp)
|
|||||||
}
|
}
|
||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
|
fprintf(fp, "task_align = ");
|
||||||
|
if (gtk_combo_box_get_active(GTK_COMBO_BOX(taskbar_alignment)) <= 0) {
|
||||||
|
fprintf(fp, "left");
|
||||||
|
} else if (gtk_combo_box_get_active(GTK_COMBO_BOX(taskbar_alignment)) == 1) {
|
||||||
|
fprintf(fp, "center");
|
||||||
|
} else {
|
||||||
|
fprintf(fp, "right");
|
||||||
|
}
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -998,6 +1008,16 @@ void add_entry(char *key, char *value)
|
|||||||
else
|
else
|
||||||
gtk_combo_box_set_active(GTK_COMBO_BOX(taskbar_sort_order), 0);
|
gtk_combo_box_set_active(GTK_COMBO_BOX(taskbar_sort_order), 0);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(key, "task_align") == 0) {
|
||||||
|
if (strcmp(value, "left") == 0)
|
||||||
|
gtk_combo_box_set_active(GTK_COMBO_BOX(taskbar_sort_order), 0);
|
||||||
|
else if (strcmp(value, "center") == 0)
|
||||||
|
gtk_combo_box_set_active(GTK_COMBO_BOX(taskbar_sort_order), 1);
|
||||||
|
else if (strcmp(value, "right") == 0)
|
||||||
|
gtk_combo_box_set_active(GTK_COMBO_BOX(taskbar_sort_order), 2);
|
||||||
|
else
|
||||||
|
gtk_combo_box_set_active(GTK_COMBO_BOX(taskbar_sort_order), 0);
|
||||||
|
}
|
||||||
else if (strcmp(key, "taskbar_padding") == 0) {
|
else if (strcmp(key, "taskbar_padding") == 0) {
|
||||||
extract_values(value, &value1, &value2, &value3);
|
extract_values(value, &value1, &value2, &value3);
|
||||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(taskbar_padding_x), atoi(value1));
|
gtk_spin_button_set_value(GTK_SPIN_BUTTON(taskbar_padding_x), atoi(value1));
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ Name[nb]=Panelbehandler
|
|||||||
Name[nl]=Paneel Manager
|
Name[nl]=Paneel Manager
|
||||||
Name[nn]=Panelhandsamar
|
Name[nn]=Panelhandsamar
|
||||||
Name[pa]=ਪੈਨਲ ਮੈਨੇਜਰ
|
Name[pa]=ਪੈਨਲ ਮੈਨੇਜਰ
|
||||||
Name[pl]=Panel
|
Name[pl]=Ustawienia panelu
|
||||||
Name[pt]=Gestor do Painel
|
Name[pt]=Gestor do Painel
|
||||||
Name[pt_BR]=Gerenciador do painel
|
Name[pt_BR]=Gerenciador do painel
|
||||||
Name[ro]=Manager de panouri
|
Name[ro]=Manager de panouri
|
||||||
|
|||||||
133
src/util/area.c
133
src/util/area.c
@@ -76,7 +76,7 @@ void init_rendering(void *obj, int pos)
|
|||||||
Area *a = (Area*)obj;
|
Area *a = (Area*)obj;
|
||||||
|
|
||||||
// initialize fixed position/size
|
// initialize fixed position/size
|
||||||
GSList *l;
|
GList *l;
|
||||||
for (l = a->list; l ; l = l->next) {
|
for (l = a->list; l ; l = l->next) {
|
||||||
Area *child = ((Area*)l->data);
|
Area *child = ((Area*)l->data);
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
@@ -102,7 +102,7 @@ void rendering(void *obj)
|
|||||||
Panel *panel = (Panel*)obj;
|
Panel *panel = (Panel*)obj;
|
||||||
|
|
||||||
size_by_content(&panel->area);
|
size_by_content(&panel->area);
|
||||||
size_by_layout(&panel->area, 0, 1);
|
size_by_layout(&panel->area, 1);
|
||||||
|
|
||||||
refresh(&panel->area);
|
refresh(&panel->area);
|
||||||
}
|
}
|
||||||
@@ -111,10 +111,11 @@ void rendering(void *obj)
|
|||||||
void size_by_content (Area *a)
|
void size_by_content (Area *a)
|
||||||
{
|
{
|
||||||
// don't resize hiden objects
|
// don't resize hiden objects
|
||||||
if (!a->on_screen) return;
|
if (!a->on_screen)
|
||||||
|
return;
|
||||||
|
|
||||||
// children node are resized before its parent
|
// children node are resized before its parent
|
||||||
GSList *l;
|
GList *l;
|
||||||
for (l = a->list; l ; l = l->next)
|
for (l = a->list; l ; l = l->next)
|
||||||
size_by_content(l->data);
|
size_by_content(l->data);
|
||||||
|
|
||||||
@@ -134,14 +135,15 @@ void size_by_content (Area *a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void size_by_layout (Area *a, int pos, int level)
|
void size_by_layout (Area *a, int level)
|
||||||
{
|
{
|
||||||
// don't resize hiden objects
|
// don't resize hiden objects
|
||||||
if (!a->on_screen) return;
|
if (!a->on_screen)
|
||||||
|
return;
|
||||||
|
|
||||||
// parent node is resized before its children
|
// parent node is resized before its children
|
||||||
// calculate area's size
|
// calculate area's size
|
||||||
GSList *l;
|
GList *l;
|
||||||
if (a->resize && a->size_mode == SIZE_BY_LAYOUT) {
|
if (a->resize && a->size_mode == SIZE_BY_LAYOUT) {
|
||||||
a->resize = 0;
|
a->resize = 0;
|
||||||
|
|
||||||
@@ -156,13 +158,15 @@ void size_by_layout (Area *a, int pos, int level)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update position of childs
|
// update position of children
|
||||||
pos += a->paddingxlr + a->bg->border.width;
|
if (a->list) {
|
||||||
int i=0;
|
if (a->alignment == ALIGN_LEFT) {
|
||||||
|
int pos = (panel_horizontal ? a->posx : a->posy) + a->bg->border.width + a->paddingxlr;
|
||||||
|
|
||||||
for (l = a->list; l ; l = l->next) {
|
for (l = a->list; l ; l = l->next) {
|
||||||
Area *child = ((Area*)l->data);
|
Area *child = ((Area*)l->data);
|
||||||
if (!child->on_screen) continue;
|
if (!child->on_screen)
|
||||||
i++;
|
continue;
|
||||||
|
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
if (pos != child->posx) {
|
if (pos != child->posx) {
|
||||||
@@ -170,8 +174,7 @@ void size_by_layout (Area *a, int pos, int level)
|
|||||||
child->posx = pos;
|
child->posx = pos;
|
||||||
child->on_changed = 1;
|
child->on_changed = 1;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (pos != child->posy) {
|
if (pos != child->posy) {
|
||||||
// pos changed => redraw
|
// pos changed => redraw
|
||||||
child->posy = pos;
|
child->posy = pos;
|
||||||
@@ -179,16 +182,78 @@ void size_by_layout (Area *a, int pos, int level)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// position of each visible object
|
size_by_layout(child, level+1);
|
||||||
int k;
|
|
||||||
for (k=0 ; k < level ; k++) printf(" ");
|
|
||||||
printf("tree level %d, object %d, pos %d, %s\n", level, i, pos, (child->size_mode == SIZE_BY_LAYOUT) ? "SIZE_BY_LAYOUT" : "SIZE_BY_CONTENT");*/
|
|
||||||
size_by_layout(child, pos, level+1);
|
|
||||||
|
|
||||||
if (panel_horizontal)
|
pos += panel_horizontal ? child->width + a->paddingx : child->height + a->paddingx;
|
||||||
pos += child->width + a->paddingx;
|
}
|
||||||
else
|
} else if (a->alignment == ALIGN_RIGHT) {
|
||||||
pos += child->height + a->paddingx;
|
int pos = (panel_horizontal ? a->posx + a->width : a->posy + a->height) - a->bg->border.width - a->paddingxlr;
|
||||||
|
|
||||||
|
for (l = g_list_last(a->list); l ; l = l->prev) {
|
||||||
|
Area *child = ((Area*)l->data);
|
||||||
|
if (!child->on_screen)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pos -= panel_horizontal ? child->width : child->height;
|
||||||
|
|
||||||
|
if (panel_horizontal) {
|
||||||
|
if (pos != child->posx) {
|
||||||
|
// pos changed => redraw
|
||||||
|
child->posx = pos;
|
||||||
|
child->on_changed = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pos != child->posy) {
|
||||||
|
// pos changed => redraw
|
||||||
|
child->posy = pos;
|
||||||
|
child->on_changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_by_layout(child, level+1);
|
||||||
|
|
||||||
|
pos -= a->paddingx;
|
||||||
|
}
|
||||||
|
} else if (a->alignment == ALIGN_CENTER) {
|
||||||
|
|
||||||
|
int children_size = 0;
|
||||||
|
|
||||||
|
for (l = a->list; l ; l = l->next) {
|
||||||
|
Area *child = ((Area*)l->data);
|
||||||
|
if (!child->on_screen)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
children_size += panel_horizontal ? child->width : child->height;
|
||||||
|
children_size += (l == a->list) ? 0 : a->paddingx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = (panel_horizontal ? a->posx : a->posy) + a->bg->border.width + a->paddingxlr;
|
||||||
|
pos += ((panel_horizontal ? a->width : a->height) - children_size) / 2;
|
||||||
|
|
||||||
|
for (l = a->list; l ; l = l->next) {
|
||||||
|
Area *child = ((Area*)l->data);
|
||||||
|
if (!child->on_screen)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (panel_horizontal) {
|
||||||
|
if (pos != child->posx) {
|
||||||
|
// pos changed => redraw
|
||||||
|
child->posx = pos;
|
||||||
|
child->on_changed = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pos != child->posy) {
|
||||||
|
// pos changed => redraw
|
||||||
|
child->posy = pos;
|
||||||
|
child->on_changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_by_layout(child, level+1);
|
||||||
|
|
||||||
|
pos += panel_horizontal ? child->width + a->paddingx : child->height + a->paddingx;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->on_changed) {
|
if (a->on_changed) {
|
||||||
@@ -209,7 +274,7 @@ void refresh (Area *a)
|
|||||||
if (a->redraw) {
|
if (a->redraw) {
|
||||||
a->redraw = 0;
|
a->redraw = 0;
|
||||||
// force redraw of child
|
// force redraw of child
|
||||||
//GSList *l;
|
//GList *l;
|
||||||
//for (l = a->list ; l ; l = l->next)
|
//for (l = a->list ; l ; l = l->next)
|
||||||
//((Area*)l->data)->redraw = 1;
|
//((Area*)l->data)->redraw = 1;
|
||||||
|
|
||||||
@@ -222,7 +287,7 @@ void refresh (Area *a)
|
|||||||
XCopyArea (server.dsp, a->pix, ((Panel *)a->panel)->temp_pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
|
XCopyArea (server.dsp, a->pix, ((Panel *)a->panel)->temp_pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
|
||||||
|
|
||||||
// and then refresh child object
|
// and then refresh child object
|
||||||
GSList *l;
|
GList *l;
|
||||||
for (l = a->list; l ; l = l->next)
|
for (l = a->list; l ; l = l->next)
|
||||||
refresh(l->data);
|
refresh(l->data);
|
||||||
}
|
}
|
||||||
@@ -236,7 +301,7 @@ int resize_by_layout(void *obj, int maximum_size)
|
|||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
// detect free size for SIZE_BY_LAYOUT's Area
|
// detect free size for SIZE_BY_LAYOUT's Area
|
||||||
size = a->width - (2 * (a->paddingxlr + a->bg->border.width));
|
size = a->width - (2 * (a->paddingxlr + a->bg->border.width));
|
||||||
GSList *l;
|
GList *l;
|
||||||
for (l = a->list ; l ; l = l->next) {
|
for (l = a->list ; l ; l = l->next) {
|
||||||
child = (Area*)l->data;
|
child = (Area*)l->data;
|
||||||
if (child->on_screen && child->size_mode == SIZE_BY_CONTENT) {
|
if (child->on_screen && child->size_mode == SIZE_BY_CONTENT) {
|
||||||
@@ -278,7 +343,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
|
||||||
size = a->height - (2 * (a->paddingxlr + a->bg->border.width));
|
size = a->height - (2 * (a->paddingxlr + a->bg->border.width));
|
||||||
GSList *l;
|
GList *l;
|
||||||
for (l = a->list ; l ; l = l->next) {
|
for (l = a->list ; l ; l = l->next) {
|
||||||
child = (Area*)l->data;
|
child = (Area*)l->data;
|
||||||
if (child->on_screen && child->size_mode == SIZE_BY_CONTENT) {
|
if (child->on_screen && child->size_mode == SIZE_BY_CONTENT) {
|
||||||
@@ -291,7 +356,7 @@ int resize_by_layout(void *obj, int maximum_size)
|
|||||||
if (nb_by_content+nb_by_layout)
|
if (nb_by_content+nb_by_layout)
|
||||||
size -= ((nb_by_content+nb_by_layout-1) * a->paddingx);
|
size -= ((nb_by_content+nb_by_layout-1) * a->paddingx);
|
||||||
|
|
||||||
int height=0, modulo=0, old_height;
|
int height=0, modulo=0;
|
||||||
if (nb_by_layout) {
|
if (nb_by_layout) {
|
||||||
height = size / nb_by_layout;
|
height = size / nb_by_layout;
|
||||||
modulo = size % nb_by_layout;
|
modulo = size % nb_by_layout;
|
||||||
@@ -305,7 +370,7 @@ int resize_by_layout(void *obj, int maximum_size)
|
|||||||
for (l = a->list ; l ; l = l->next) {
|
for (l = a->list ; l ; l = l->next) {
|
||||||
child = (Area*)l->data;
|
child = (Area*)l->data;
|
||||||
if (child->on_screen && child->size_mode == SIZE_BY_LAYOUT) {
|
if (child->on_screen && child->size_mode == SIZE_BY_LAYOUT) {
|
||||||
old_height = child->height;
|
int old_height = child->height;
|
||||||
child->height = height;
|
child->height = height;
|
||||||
if (modulo) {
|
if (modulo) {
|
||||||
child->height++;
|
child->height++;
|
||||||
@@ -324,7 +389,7 @@ void set_redraw (Area *a)
|
|||||||
{
|
{
|
||||||
a->redraw = 1;
|
a->redraw = 1;
|
||||||
|
|
||||||
GSList *l;
|
GList *l;
|
||||||
for (l = a->list ; l ; l = l->next)
|
for (l = a->list ; l ; l = l->next)
|
||||||
set_redraw(l->data);
|
set_redraw(l->data);
|
||||||
}
|
}
|
||||||
@@ -438,7 +503,7 @@ void remove_area (Area *a)
|
|||||||
{
|
{
|
||||||
Area *parent = (Area*)a->parent;
|
Area *parent = (Area*)a->parent;
|
||||||
|
|
||||||
parent->list = g_slist_remove(parent->list, a);
|
parent->list = g_list_remove(parent->list, a);
|
||||||
set_redraw (parent);
|
set_redraw (parent);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -448,7 +513,7 @@ void add_area (Area *a)
|
|||||||
{
|
{
|
||||||
Area *parent = (Area*)a->parent;
|
Area *parent = (Area*)a->parent;
|
||||||
|
|
||||||
parent->list = g_slist_append(parent->list, a);
|
parent->list = g_list_append(parent->list, a);
|
||||||
set_redraw (parent);
|
set_redraw (parent);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -459,12 +524,12 @@ void free_area (Area *a)
|
|||||||
if (!a)
|
if (!a)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GSList *l0;
|
GList *l0;
|
||||||
for (l0 = a->list; l0 ; l0 = l0->next)
|
for (l0 = a->list; l0 ; l0 = l0->next)
|
||||||
free_area (l0->data);
|
free_area (l0->data);
|
||||||
|
|
||||||
if (a->list) {
|
if (a->list) {
|
||||||
g_slist_free(a->list);
|
g_list_free(a->list);
|
||||||
a->list = 0;
|
a->list = 0;
|
||||||
}
|
}
|
||||||
if (a->pix) {
|
if (a->pix) {
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ typedef struct
|
|||||||
// SIZE_BY_LAYOUT objects : taskbar and task
|
// SIZE_BY_LAYOUT objects : taskbar and task
|
||||||
// SIZE_BY_CONTENT objects : clock, battery, launcher, systray
|
// SIZE_BY_CONTENT objects : clock, battery, launcher, systray
|
||||||
enum { SIZE_BY_LAYOUT, SIZE_BY_CONTENT };
|
enum { SIZE_BY_LAYOUT, SIZE_BY_CONTENT };
|
||||||
|
enum { ALIGN_LEFT = 0, ALIGN_CENTER = 1, ALIGN_RIGHT = 2 };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// coordinate relative to panel window
|
// coordinate relative to panel window
|
||||||
@@ -61,13 +62,15 @@ typedef struct {
|
|||||||
Background *bg;
|
Background *bg;
|
||||||
|
|
||||||
// list of child : Area object
|
// list of child : Area object
|
||||||
GSList *list;
|
GList *list;
|
||||||
|
|
||||||
// object visible on screen.
|
// object visible on screen.
|
||||||
// An object (like systray) could be enabled but hidden (because no tray icon).
|
// An object (like systray) could be enabled but hidden (because no tray icon).
|
||||||
int on_screen;
|
int on_screen;
|
||||||
// way to calculate the size (SIZE_BY_CONTENT or SIZE_BY_LAYOUT)
|
// way to calculate the size (SIZE_BY_CONTENT or SIZE_BY_LAYOUT)
|
||||||
int size_mode;
|
int size_mode;
|
||||||
|
|
||||||
|
int alignment;
|
||||||
// need to calculate position and width
|
// need to calculate position and width
|
||||||
int resize;
|
int resize;
|
||||||
// need redraw Pixmap
|
// need redraw Pixmap
|
||||||
@@ -96,7 +99,7 @@ void init_rendering(void *obj, int pos);
|
|||||||
|
|
||||||
void rendering(void *obj);
|
void rendering(void *obj);
|
||||||
void size_by_content (Area *a);
|
void size_by_content (Area *a);
|
||||||
void size_by_layout (Area *a, int pos, int level);
|
void size_by_layout (Area *a, int level);
|
||||||
// draw background and foreground
|
// draw background and foreground
|
||||||
void refresh (Area *a);
|
void refresh (Area *a);
|
||||||
|
|
||||||
|
|||||||
@@ -49,9 +49,7 @@ struct _timeout {
|
|||||||
|
|
||||||
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(void*), void* arg, timeout* t);
|
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(void*), void* arg, timeout* t);
|
||||||
gint compare_timeouts(gconstpointer t1, gconstpointer t2);
|
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);
|
int timespec_subtract(struct timespec* result, struct timespec* x, struct timespec* y);
|
||||||
struct timespec add_msec_to_timespec(struct timespec ts, int msec);
|
|
||||||
|
|
||||||
|
|
||||||
int align_with_existing_timeouts(timeout* t);
|
int align_with_existing_timeouts(timeout* t);
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#define TIMER_H
|
#define TIMER_H
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
extern struct timeval next_timeout;
|
extern struct timeval next_timeout;
|
||||||
|
|
||||||
@@ -66,4 +68,9 @@ void update_next_timeout();
|
|||||||
/** Callback of all expired timeouts **/
|
/** Callback of all expired timeouts **/
|
||||||
void callback_timeout_expired();
|
void callback_timeout_expired();
|
||||||
|
|
||||||
|
/** Returns -1 if t1 < t2, 0 if t1 == t2, 1 if t1 > t2 **/
|
||||||
|
gint compare_timespecs(const struct timespec* t1, const struct timespec* t2);
|
||||||
|
|
||||||
|
struct timespec add_msec_to_timespec(struct timespec ts, int msec);
|
||||||
|
|
||||||
#endif // TIMER_H
|
#endif // TIMER_H
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ Name[zh_CN]=面板 tint2
|
|||||||
Name[zh_TW]=面板 tint2
|
Name[zh_TW]=面板 tint2
|
||||||
Comment=Lightweight panel
|
Comment=Lightweight panel
|
||||||
Comment[fr_FR]=Panel léger
|
Comment[fr_FR]=Panel léger
|
||||||
|
Comment[pl]=Lekki panel
|
||||||
Exec=tint2
|
Exec=tint2
|
||||||
Icon=taskbar
|
Icon=taskbar
|
||||||
Terminal=false
|
Terminal=false
|
||||||
|
|||||||
Reference in New Issue
Block a user