Cleanup indentation with clang-format and changed a few variable names
This commit is contained in:
66
.clang-format
Normal file
66
.clang-format
Normal file
@@ -0,0 +1,66 @@
|
||||
# works with clang-format-3.7
|
||||
#
|
||||
# Most controversial fields are UseTab, IndentWidth, ContinuationIndentWidth, ColumnLimit, BreakBeforeBraces
|
||||
|
||||
#BasedOnStyle: Google
|
||||
AccessModifierOffset: 0
|
||||
AlignAfterOpenBracket: true
|
||||
AlignConsecutiveAssignments: false
|
||||
#AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Linux
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: ''
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 0
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DerivePointerBinding: false
|
||||
DisableFormat: false
|
||||
ForEachMacros: ['foreach']
|
||||
IndentCaseLabels: false
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
Language: Cpp
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 1000
|
||||
PenaltyBreakComment: 100
|
||||
PenaltyBreakFirstLessLess: 0
|
||||
PenaltyBreakString: 100
|
||||
PenaltyExcessCharacter: 100
|
||||
PenaltyReturnTypeOnItsOwnLine: 2000
|
||||
PointerAlignment: Right
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: ForIndentation
|
||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
build
|
||||
*.user
|
||||
@@ -170,7 +170,7 @@ endif( RT_LIBRARY )
|
||||
target_link_libraries( tint2 m )
|
||||
|
||||
add_dependencies( tint2 version )
|
||||
set_target_properties( tint2 PROPERTIES COMPILE_FLAGS "-Wall -fno-strict-aliasing -pthread ${ASAN_C_FLAGS}" )
|
||||
set_target_properties( tint2 PROPERTIES COMPILE_FLAGS "-Wall -Wshadow -Wpointer-arith -fno-strict-aliasing -pthread ${ASAN_C_FLAGS}" )
|
||||
set_target_properties( tint2 PROPERTIES LINK_FLAGS "-pthread -fno-strict-aliasing ${ASAN_L_FLAGS}" )
|
||||
|
||||
install( TARGETS tint2 DESTINATION bin )
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
PangoFontDescription *bat1_font_desc;
|
||||
PangoFontDescription *bat2_font_desc;
|
||||
struct batstate battery_state;
|
||||
int battery_enabled;
|
||||
int battery_tooltip_enabled;
|
||||
gboolean battery_enabled;
|
||||
gboolean battery_tooltip_enabled;
|
||||
int percentage_hide;
|
||||
static timeout *battery_timeout;
|
||||
|
||||
@@ -81,48 +81,44 @@ void update_battery_tick(void* arg)
|
||||
tint_exec(ac_disconnected_cmd);
|
||||
}
|
||||
|
||||
if (old_found == battery_found &&
|
||||
old_percentage == battery_state.percentage &&
|
||||
old_hours == battery_state.time.hours &&
|
||||
old_minutes == battery_state.time.minutes) {
|
||||
if (old_found == battery_found && old_percentage == battery_state.percentage &&
|
||||
old_hours == battery_state.time.hours && old_minutes == battery_state.time.minutes) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (battery_state.percentage < battery_low_status &&
|
||||
battery_state.state == BATTERY_DISCHARGING &&
|
||||
if (battery_state.percentage < battery_low_status && battery_state.state == BATTERY_DISCHARGING &&
|
||||
!battery_low_cmd_sent) {
|
||||
tint_exec(battery_low_cmd);
|
||||
battery_low_cmd_sent = 1;
|
||||
}
|
||||
if (battery_state.percentage > battery_low_status &&
|
||||
battery_state.state == BATTERY_CHARGING &&
|
||||
if (battery_state.percentage > battery_low_status && battery_state.state == BATTERY_CHARGING &&
|
||||
battery_low_cmd_sent) {
|
||||
battery_low_cmd_sent = 0;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < nb_panel; i++) {
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
if (!battery_found) {
|
||||
if (panel1[i].battery.area.on_screen == 1) {
|
||||
hide(&panel1[i].battery.area);
|
||||
panel_refresh = 1;
|
||||
if (panels[i].battery.area.on_screen) {
|
||||
hide(&panels[i].battery.area);
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
} else {
|
||||
if (battery_state.percentage >= percentage_hide) {
|
||||
if (panel1[i].battery.area.on_screen == 1) {
|
||||
hide(&panel1[i].battery.area);
|
||||
panel_refresh = 1;
|
||||
if (panels[i].battery.area.on_screen) {
|
||||
hide(&panels[i].battery.area);
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
} else {
|
||||
if (panel1[i].battery.area.on_screen == 0) {
|
||||
show(&panel1[i].battery.area);
|
||||
panel_refresh = 1;
|
||||
if (panels[i].battery.area.on_screen == 0) {
|
||||
show(&panels[i].battery.area);
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (panel1[i].battery.area.on_screen == 1) {
|
||||
panel1[i].battery.area.resize_needed = 1;
|
||||
panel_refresh = 1;
|
||||
if (panels[i].battery.area.on_screen) {
|
||||
panels[i].battery.area.resize_needed = 1;
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,7 +196,8 @@ void init_battery()
|
||||
update_battery();
|
||||
}
|
||||
|
||||
char* battery_get_tooltip(void* obj) {
|
||||
char *battery_get_tooltip(void *obj)
|
||||
{
|
||||
return battery_os_tooltip();
|
||||
}
|
||||
|
||||
@@ -217,7 +214,7 @@ void init_battery_panel(void *p)
|
||||
if (!bat2_font_desc)
|
||||
bat2_font_desc = pango_font_description_from_string(DEFAULT_FONT);
|
||||
|
||||
if (battery->area.bg == 0)
|
||||
if (!battery->area.bg)
|
||||
battery->area.bg = &g_array_index(backgrounds, Background, 0);
|
||||
|
||||
battery->area.parent = p;
|
||||
@@ -225,20 +222,17 @@ void init_battery_panel(void *p)
|
||||
battery->area._draw_foreground = draw_battery;
|
||||
battery->area.size_mode = LAYOUT_FIXED;
|
||||
battery->area._resize = resize_battery;
|
||||
battery->area.on_screen = 1;
|
||||
battery->area.on_screen = TRUE;
|
||||
battery->area.resize_needed = 1;
|
||||
battery->area.has_mouse_over_effect = battery_lclick_command ||
|
||||
battery_mclick_command ||
|
||||
battery_rclick_command ||
|
||||
battery_uwheel_command ||
|
||||
battery_dwheel_command;
|
||||
battery->area.has_mouse_over_effect = battery_lclick_command || battery_mclick_command || battery_rclick_command ||
|
||||
battery_uwheel_command || battery_dwheel_command;
|
||||
battery->area.has_mouse_press_effect = battery->area.has_mouse_over_effect;
|
||||
if (battery_tooltip_enabled)
|
||||
battery->area._get_tooltip_text = battery_get_tooltip;
|
||||
}
|
||||
|
||||
|
||||
int update_battery() {
|
||||
int update_battery()
|
||||
{
|
||||
int err;
|
||||
|
||||
/* reset */
|
||||
@@ -257,7 +251,6 @@ int update_battery() {
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
void draw_battery(void *obj, cairo_t *c)
|
||||
{
|
||||
Battery *battery = obj;
|
||||
@@ -292,8 +285,7 @@ void draw_battery (void *obj, cairo_t *c)
|
||||
g_object_unref(layout);
|
||||
}
|
||||
|
||||
|
||||
int resize_battery(void *obj)
|
||||
gboolean resize_battery(void *obj)
|
||||
{
|
||||
Battery *battery = obj;
|
||||
Panel *panel = battery->area.panel;
|
||||
@@ -301,7 +293,7 @@ int resize_battery(void *obj)
|
||||
int bat_time_height, bat_time_width, bat_time_height_ink;
|
||||
int ret = 0;
|
||||
|
||||
battery->area.redraw_needed = 1;
|
||||
battery->area.redraw_needed = TRUE;
|
||||
|
||||
snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage);
|
||||
if (battery_state.state == BATTERY_FULL) {
|
||||
@@ -309,20 +301,31 @@ int resize_battery(void *obj)
|
||||
} else {
|
||||
snprintf(buf_bat_time, sizeof(buf_bat_time), "%02d:%02d", battery_state.time.hours, battery_state.time.minutes);
|
||||
}
|
||||
get_text_size2(bat1_font_desc, &bat_percentage_height_ink, &bat_percentage_height, &bat_percentage_width,
|
||||
panel->area.height, panel->area.width, buf_bat_percentage, strlen(buf_bat_percentage),
|
||||
get_text_size2(bat1_font_desc,
|
||||
&bat_percentage_height_ink,
|
||||
&bat_percentage_height,
|
||||
&bat_percentage_width,
|
||||
panel->area.height,
|
||||
panel->area.width,
|
||||
buf_bat_percentage,
|
||||
strlen(buf_bat_percentage),
|
||||
PANGO_WRAP_WORD_CHAR,
|
||||
PANGO_ELLIPSIZE_NONE);
|
||||
get_text_size2(bat2_font_desc, &bat_time_height_ink, &bat_time_height, &bat_time_width,
|
||||
panel->area.height, panel->area.width, buf_bat_time, strlen(buf_bat_time),
|
||||
get_text_size2(bat2_font_desc,
|
||||
&bat_time_height_ink,
|
||||
&bat_time_height,
|
||||
&bat_time_width,
|
||||
panel->area.height,
|
||||
panel->area.width,
|
||||
buf_bat_time,
|
||||
strlen(buf_bat_time),
|
||||
PANGO_WRAP_WORD_CHAR,
|
||||
PANGO_ELLIPSIZE_NONE);
|
||||
|
||||
if (panel_horizontal) {
|
||||
int new_size = (bat_percentage_width > bat_time_width) ? bat_percentage_width : bat_time_width;
|
||||
new_size += 2 * battery->area.paddingxlr + 2 * battery->area.bg->border.width;
|
||||
if (new_size > battery->area.width ||
|
||||
new_size < battery->area.width - 2) {
|
||||
if (new_size > battery->area.width || new_size < battery->area.width - 2) {
|
||||
// we try to limit the number of resize
|
||||
battery->area.width = new_size;
|
||||
battery->bat1_posy = (battery->area.height - bat_percentage_height - bat_time_height) / 2;
|
||||
@@ -330,10 +333,9 @@ int resize_battery(void *obj)
|
||||
ret = 1;
|
||||
}
|
||||
} else {
|
||||
int new_size = bat_percentage_height + bat_time_height +
|
||||
(2 * (battery->area.paddingxlr + battery->area.bg->border.width));
|
||||
if (new_size > battery->area.height ||
|
||||
new_size < battery->area.height - 2) {
|
||||
int new_size =
|
||||
bat_percentage_height + bat_time_height + (2 * (battery->area.paddingxlr + battery->area.bg->border.width));
|
||||
if (new_size > battery->area.height || new_size < battery->area.height - 2) {
|
||||
battery->area.height = new_size;
|
||||
battery->bat1_posy = (battery->area.height - bat_percentage_height - bat_time_height - 2) / 2;
|
||||
battery->bat2_posy = battery->bat1_posy + bat_percentage_height + 2;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "common.h"
|
||||
#include "area.h"
|
||||
|
||||
|
||||
// battery drawing parameter (per panel)
|
||||
typedef struct Battery {
|
||||
// always start with area
|
||||
@@ -27,12 +26,7 @@ typedef struct Battery {
|
||||
int bat2_posy;
|
||||
} Battery;
|
||||
|
||||
enum chargestate {
|
||||
BATTERY_UNKNOWN,
|
||||
BATTERY_CHARGING,
|
||||
BATTERY_DISCHARGING,
|
||||
BATTERY_FULL
|
||||
};
|
||||
enum chargestate { BATTERY_UNKNOWN, BATTERY_CHARGING, BATTERY_DISCHARGING, BATTERY_FULL };
|
||||
|
||||
typedef struct battime {
|
||||
int16_t hours;
|
||||
@@ -50,8 +44,8 @@ typedef struct batstate {
|
||||
extern struct batstate battery_state;
|
||||
extern PangoFontDescription *bat1_font_desc;
|
||||
extern PangoFontDescription *bat2_font_desc;
|
||||
extern int battery_enabled;
|
||||
extern int battery_tooltip_enabled;
|
||||
extern gboolean battery_enabled;
|
||||
extern gboolean battery_tooltip_enabled;
|
||||
extern int percentage_hide;
|
||||
|
||||
extern int8_t battery_low_status;
|
||||
@@ -66,7 +60,8 @@ extern char *battery_rclick_command;
|
||||
extern char *battery_uwheel_command;
|
||||
extern char *battery_dwheel_command;
|
||||
|
||||
static inline gchar* chargestate2str(enum chargestate state) {
|
||||
static inline gchar *chargestate2str(enum chargestate state)
|
||||
{
|
||||
switch (state) {
|
||||
case BATTERY_CHARGING:
|
||||
return "Charging";
|
||||
@@ -80,7 +75,8 @@ static inline gchar* chargestate2str(enum chargestate state) {
|
||||
};
|
||||
}
|
||||
|
||||
static inline void batstate_set_time(struct batstate *state, int seconds) {
|
||||
static inline void batstate_set_time(struct batstate *state, int seconds)
|
||||
{
|
||||
state->time.hours = seconds / 3600;
|
||||
seconds -= 3600 * state->time.hours;
|
||||
state->time.minutes = seconds / 60;
|
||||
@@ -103,7 +99,7 @@ void init_battery_panel(void *panel);
|
||||
void reinit_battery();
|
||||
void draw_battery(void *obj, cairo_t *c);
|
||||
|
||||
int resize_battery(void *obj);
|
||||
gboolean resize_battery(void *obj);
|
||||
|
||||
void battery_action(int button);
|
||||
|
||||
|
||||
@@ -23,18 +23,22 @@
|
||||
|
||||
#warning tint2 has no battery support for this operating system!
|
||||
|
||||
gboolean battery_os_init() {
|
||||
gboolean battery_os_init()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void battery_os_free() {
|
||||
void battery_os_free()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int battery_os_update(struct batstate *state) {
|
||||
int battery_os_update(struct batstate *state)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* battery_os_tooltip() {
|
||||
char *battery_os_tooltip()
|
||||
{
|
||||
return strdup("Operating System not supported");
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
#include "common.h"
|
||||
#include "battery.h"
|
||||
|
||||
gboolean battery_os_init() {
|
||||
gboolean battery_os_init()
|
||||
{
|
||||
int sysctl_out = 0;
|
||||
size_t len = sizeof(sysctl_out);
|
||||
|
||||
@@ -33,11 +34,13 @@ gboolean battery_os_init() {
|
||||
(sysctlbyname("hw.acpi.battery.life", &sysctl_out, &len, NULL, 0) == 0);
|
||||
}
|
||||
|
||||
void battery_os_free() {
|
||||
void battery_os_free()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int battery_os_update(struct batstate *state) {
|
||||
int battery_os_update(struct batstate *state)
|
||||
{
|
||||
int sysctl_out = 0;
|
||||
size_t len = sizeof(sysctl_out);
|
||||
gboolean err = 0;
|
||||
@@ -75,7 +78,8 @@ int battery_os_update(struct batstate *state) {
|
||||
return err;
|
||||
}
|
||||
|
||||
char* battery_os_tooltip() {
|
||||
char *battery_os_tooltip()
|
||||
{
|
||||
GString *tooltip = g_string_new("");
|
||||
gchar *result;
|
||||
|
||||
|
||||
@@ -61,37 +61,35 @@ struct psy_mains {
|
||||
gboolean online;
|
||||
};
|
||||
|
||||
static void uevent_battery_update() {
|
||||
static void uevent_battery_update()
|
||||
{
|
||||
update_battery_tick(NULL);
|
||||
}
|
||||
static struct uevent_notify psy_change = {
|
||||
UEVENT_CHANGE,
|
||||
"power_supply",
|
||||
NULL,
|
||||
uevent_battery_update
|
||||
};
|
||||
static struct uevent_notify psy_change = {UEVENT_CHANGE, "power_supply", NULL, uevent_battery_update};
|
||||
|
||||
static void uevent_battery_plug() {
|
||||
static void uevent_battery_plug()
|
||||
{
|
||||
printf("reinitialize batteries after HW change\n");
|
||||
reinit_battery();
|
||||
}
|
||||
static struct uevent_notify psy_plug = {
|
||||
UEVENT_ADD | UEVENT_REMOVE,
|
||||
"power_supply",
|
||||
NULL,
|
||||
uevent_battery_plug
|
||||
};
|
||||
static struct uevent_notify psy_plug = {UEVENT_ADD | UEVENT_REMOVE, "power_supply", NULL, uevent_battery_plug};
|
||||
|
||||
#define RETURN_ON_ERROR(err) if (error) { g_error_free(err); return FALSE; }
|
||||
#define RETURN_ON_ERROR(err) \
|
||||
if (error) { \
|
||||
g_error_free(err); \
|
||||
return FALSE; \
|
||||
}
|
||||
|
||||
static GList *batteries = NULL;
|
||||
static GList *mains = NULL;
|
||||
|
||||
static guint8 energy_to_percent(gint energy_now, gint energy_full) {
|
||||
static guint8 energy_to_percent(gint energy_now, gint energy_full)
|
||||
{
|
||||
return 0.5 + ((energy_now <= energy_full ? energy_now : energy_full) * 100.0) / energy_full;
|
||||
}
|
||||
|
||||
static enum psy_type power_supply_get_type(const gchar *entryname) {
|
||||
static enum psy_type power_supply_get_type(const gchar *entryname)
|
||||
{
|
||||
gchar *path_type = g_build_filename("/sys/class/power_supply", entryname, "type", NULL);
|
||||
GError *error = NULL;
|
||||
gchar *type;
|
||||
@@ -119,7 +117,8 @@ static enum psy_type power_supply_get_type(const gchar *entryname) {
|
||||
return PSY_UNKNOWN;
|
||||
}
|
||||
|
||||
static gboolean init_linux_battery(struct psy_battery *bat) {
|
||||
static gboolean init_linux_battery(struct psy_battery *bat)
|
||||
{
|
||||
const gchar *entryname = bat->name;
|
||||
|
||||
bat->energy_in_uamp = FALSE;
|
||||
@@ -181,7 +180,8 @@ err0:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean init_linux_mains(struct psy_mains *ac) {
|
||||
static gboolean init_linux_mains(struct psy_mains *ac)
|
||||
{
|
||||
const gchar *entryname = ac->name;
|
||||
|
||||
ac->path_online = g_build_filename("/sys/class/power_supply", entryname, "online", NULL);
|
||||
@@ -193,7 +193,8 @@ static gboolean init_linux_mains(struct psy_mains *ac) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void psy_battery_free(gpointer data) {
|
||||
static void psy_battery_free(gpointer data)
|
||||
{
|
||||
struct psy_battery *bat = data;
|
||||
g_free(bat->name);
|
||||
g_free(bat->path_status);
|
||||
@@ -204,14 +205,16 @@ static void psy_battery_free(gpointer data) {
|
||||
g_free(bat);
|
||||
}
|
||||
|
||||
static void psy_mains_free(gpointer data) {
|
||||
static void psy_mains_free(gpointer data)
|
||||
{
|
||||
struct psy_mains *ac = data;
|
||||
g_free(ac->name);
|
||||
g_free(ac->path_online);
|
||||
g_free(ac);
|
||||
}
|
||||
|
||||
void battery_os_free() {
|
||||
void battery_os_free()
|
||||
{
|
||||
uevent_unregister_notifier(&psy_change);
|
||||
uevent_unregister_notifier(&psy_plug);
|
||||
|
||||
@@ -221,7 +224,8 @@ void battery_os_free() {
|
||||
mains = NULL;
|
||||
}
|
||||
|
||||
static void add_battery(const char *entryname) {
|
||||
static void add_battery(const char *entryname)
|
||||
{
|
||||
struct psy_battery *bat = g_malloc0(sizeof(*bat));
|
||||
bat->name = g_strdup(entryname);
|
||||
|
||||
@@ -234,7 +238,8 @@ static void add_battery(const char *entryname) {
|
||||
}
|
||||
}
|
||||
|
||||
static void add_mains(const char *entryname) {
|
||||
static void add_mains(const char *entryname)
|
||||
{
|
||||
struct psy_mains *ac = g_malloc0(sizeof(*ac));
|
||||
ac->name = g_strdup(entryname);
|
||||
|
||||
@@ -247,7 +252,8 @@ static void add_mains(const char *entryname) {
|
||||
}
|
||||
}
|
||||
|
||||
gboolean battery_os_init() {
|
||||
gboolean battery_os_init()
|
||||
{
|
||||
GDir *directory = 0;
|
||||
GError *error = NULL;
|
||||
const char *entryname;
|
||||
@@ -280,7 +286,8 @@ gboolean battery_os_init() {
|
||||
return batteries != NULL;
|
||||
}
|
||||
|
||||
static gint estimate_power_usage(struct psy_battery *bat, gint old_energy_now, gint64 old_timestamp) {
|
||||
static gint estimate_power_usage(struct psy_battery *bat, gint old_energy_now, gint64 old_timestamp)
|
||||
{
|
||||
gint64 diff_power = ABS(bat->energy_now - old_energy_now);
|
||||
gint64 diff_time = bat->timestamp - old_timestamp;
|
||||
|
||||
@@ -290,7 +297,8 @@ static gint estimate_power_usage(struct psy_battery *bat, gint old_energy_now, g
|
||||
return power;
|
||||
}
|
||||
|
||||
static gboolean update_linux_battery(struct psy_battery *bat) {
|
||||
static gboolean update_linux_battery(struct psy_battery *bat)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *data;
|
||||
gsize datalen;
|
||||
@@ -358,8 +366,8 @@ static gboolean update_linux_battery(struct psy_battery *bat) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean update_linux_mains(struct psy_mains *ac) {
|
||||
static gboolean update_linux_mains(struct psy_mains *ac)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *data;
|
||||
gsize datalen;
|
||||
@@ -374,7 +382,8 @@ static gboolean update_linux_mains(struct psy_mains *ac) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int battery_os_update(struct batstate *state) {
|
||||
int battery_os_update(struct batstate *state)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
gint64 total_energy_now = 0;
|
||||
@@ -432,27 +441,33 @@ int battery_os_update(struct batstate *state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gchar* energy_human_readable(struct psy_battery *bat) {
|
||||
static gchar *energy_human_readable(struct psy_battery *bat)
|
||||
{
|
||||
gint now = bat->energy_now;
|
||||
gint full = bat->energy_full;
|
||||
gchar unit = bat->energy_in_uamp ? 'A' : 'W';
|
||||
|
||||
if (full >= 1000000) {
|
||||
return g_strdup_printf("%d.%d / %d.%d %ch",
|
||||
now / 1000000, (now % 1000000) / 100000,
|
||||
full / 1000000, (full % 1000000) / 100000,
|
||||
now / 1000000,
|
||||
(now % 1000000) / 100000,
|
||||
full / 1000000,
|
||||
(full % 1000000) / 100000,
|
||||
unit);
|
||||
} else if (full >= 1000) {
|
||||
return g_strdup_printf("%d.%d / %d.%d m%ch",
|
||||
now / 1000, (now % 1000) / 100,
|
||||
full / 1000, (full % 1000) / 100,
|
||||
now / 1000,
|
||||
(now % 1000) / 100,
|
||||
full / 1000,
|
||||
(full % 1000) / 100,
|
||||
unit);
|
||||
} else {
|
||||
return g_strdup_printf("%d / %d µ%ch", now, full, unit);
|
||||
}
|
||||
}
|
||||
|
||||
static gchar* power_human_readable(struct psy_battery *bat) {
|
||||
static gchar *power_human_readable(struct psy_battery *bat)
|
||||
{
|
||||
gint power = bat->power_now;
|
||||
gchar unit = bat->power_in_uamp ? 'A' : 'W';
|
||||
|
||||
@@ -467,7 +482,8 @@ static gchar* power_human_readable(struct psy_battery *bat) {
|
||||
}
|
||||
}
|
||||
|
||||
char* battery_os_tooltip() {
|
||||
char *battery_os_tooltip()
|
||||
{
|
||||
GList *l;
|
||||
GString *tooltip = g_string_new("");
|
||||
gchar *result;
|
||||
@@ -491,8 +507,7 @@ char* battery_os_tooltip() {
|
||||
|
||||
guint8 percentage = energy_to_percent(bat->energy_now, bat->energy_full);
|
||||
|
||||
g_string_append_printf(tooltip, "\t%s: %s (%u %%)\n\tPower: %s",
|
||||
state, energy, percentage, power);
|
||||
g_string_append_printf(tooltip, "\t%s: %s (%u %%)\n\tPower: %s", state, energy, percentage, power);
|
||||
|
||||
g_free(power);
|
||||
g_free(energy);
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
|
||||
int apm_fd = -1;
|
||||
|
||||
gboolean battery_os_init() {
|
||||
gboolean battery_os_init()
|
||||
{
|
||||
if (apm_fd > 0)
|
||||
close(apm_fd);
|
||||
|
||||
@@ -43,13 +44,15 @@ gboolean battery_os_init() {
|
||||
}
|
||||
}
|
||||
|
||||
void battery_os_free() {
|
||||
void battery_os_free()
|
||||
{
|
||||
if ((apm_fd != -1) && (close(apm_fd) == -1))
|
||||
warn("cannot close /dev/apm");
|
||||
apm_fd = -1;
|
||||
}
|
||||
|
||||
int battery_os_update(struct batstate *state) {
|
||||
int battery_os_update(struct batstate *state)
|
||||
{
|
||||
struct apm_power_info info;
|
||||
|
||||
if (apm_fd > 0 && ioctl(apm_fd, APM_IOC_GETPOWER, &(info)) == 0) {
|
||||
@@ -81,7 +84,8 @@ int battery_os_update(struct batstate *state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* battery_os_tooltip() {
|
||||
char *battery_os_tooltip()
|
||||
{
|
||||
GString *tooltip = g_string_new("");
|
||||
gchar *result;
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "timer.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
char *time1_format;
|
||||
char *time1_timezone;
|
||||
char *time2_format;
|
||||
@@ -52,7 +51,6 @@ static char buf_tooltip[512];
|
||||
int clock_enabled;
|
||||
static timeout *clock_timeout;
|
||||
|
||||
|
||||
void default_clock()
|
||||
{
|
||||
clock_enabled = 0;
|
||||
@@ -104,16 +102,15 @@ void cleanup_clock()
|
||||
clock_timeout = NULL;
|
||||
}
|
||||
|
||||
|
||||
void update_clocks_sec(void *arg)
|
||||
{
|
||||
gettimeofday(&time_clock, 0);
|
||||
int i;
|
||||
if (time1_format) {
|
||||
for (i=0 ; i < nb_panel ; i++)
|
||||
panel1[i].clock.area.resize_needed = 1;
|
||||
for (i = 0; i < num_panels; i++)
|
||||
panels[i].clock.area.resize_needed = 1;
|
||||
}
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
|
||||
void update_clocks_min(void *arg)
|
||||
@@ -125,23 +122,26 @@ void update_clocks_min(void* arg)
|
||||
if (time_clock.tv_sec % 60 == 0 || time_clock.tv_sec - old_sec > 60) {
|
||||
int i;
|
||||
if (time1_format) {
|
||||
for (i=0 ; i < nb_panel ; i++)
|
||||
panel1[i].clock.area.resize_needed = 1;
|
||||
for (i = 0; i < num_panels; i++)
|
||||
panels[i].clock.area.resize_needed = 1;
|
||||
}
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
struct tm* clock_gettime_for_tz(const char* timezone) {
|
||||
struct tm *clock_gettime_for_tz(const char *timezone)
|
||||
{
|
||||
if (timezone) {
|
||||
const char *old_tz = getenv("TZ");
|
||||
setenv("TZ", timezone, 1);
|
||||
struct tm *result = localtime(&time_clock.tv_sec);
|
||||
if (old_tz) setenv("TZ", old_tz, 1);
|
||||
else unsetenv("TZ");
|
||||
if (old_tz)
|
||||
setenv("TZ", old_tz, 1);
|
||||
else
|
||||
unsetenv("TZ");
|
||||
return result;
|
||||
}
|
||||
else return localtime(&time_clock.tv_sec);
|
||||
} else
|
||||
return localtime(&time_clock.tv_sec);
|
||||
}
|
||||
|
||||
char *clock_get_tooltip(void *obj)
|
||||
@@ -162,8 +162,7 @@ int time_format_needs_sec_ticks(char *time_format)
|
||||
void init_clock()
|
||||
{
|
||||
if (!clock_timeout) {
|
||||
if (time_format_needs_sec_ticks(time1_format) ||
|
||||
time_format_needs_sec_ticks(time2_format)) {
|
||||
if (time_format_needs_sec_ticks(time1_format) || time_format_needs_sec_ticks(time2_format)) {
|
||||
clock_timeout = add_timeout(10, 1000, update_clocks_sec, 0, &clock_timeout);
|
||||
} else {
|
||||
clock_timeout = add_timeout(10, 1000, update_clocks_min, 0, &clock_timeout);
|
||||
@@ -171,7 +170,6 @@ void init_clock()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void init_clock_panel(void *p)
|
||||
{
|
||||
Panel *panel = (Panel *)p;
|
||||
@@ -185,10 +183,8 @@ void init_clock_panel(void *p)
|
||||
clock->area.bg = &g_array_index(backgrounds, Background, 0);
|
||||
clock->area.parent = p;
|
||||
clock->area.panel = p;
|
||||
clock->area.has_mouse_press_effect = clock->area.has_mouse_over_effect = clock_lclick_command ||
|
||||
clock_mclick_command ||
|
||||
clock_rclick_command ||
|
||||
clock_uwheel_command ||
|
||||
clock->area.has_mouse_press_effect = clock->area.has_mouse_over_effect =
|
||||
clock_lclick_command || clock_mclick_command || clock_rclick_command || clock_uwheel_command ||
|
||||
clock_dwheel_command;
|
||||
clock->area._draw_foreground = draw_clock;
|
||||
clock->area.size_mode = LAYOUT_FIXED;
|
||||
@@ -198,7 +194,7 @@ void init_clock_panel(void *p)
|
||||
return;
|
||||
|
||||
clock->area.resize_needed = 1;
|
||||
clock->area.on_screen = 1;
|
||||
clock->area.on_screen = TRUE;
|
||||
|
||||
if (time_tooltip_format) {
|
||||
clock->area._get_tooltip_text = clock_get_tooltip;
|
||||
@@ -206,7 +202,6 @@ void init_clock_panel(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw_clock(void *obj, cairo_t *c)
|
||||
{
|
||||
Clock *clock = obj;
|
||||
@@ -240,23 +235,36 @@ void draw_clock (void *obj, cairo_t *c)
|
||||
g_object_unref(layout);
|
||||
}
|
||||
|
||||
|
||||
int resize_clock (void *obj)
|
||||
gboolean resize_clock(void *obj)
|
||||
{
|
||||
Clock *clock = obj;
|
||||
Panel *panel = clock->area.panel;
|
||||
int time_height_ink, time_height, time_width, date_height_ink, date_height, date_width, ret = 0;
|
||||
|
||||
clock->area.redraw_needed = 1;
|
||||
clock->area.redraw_needed = TRUE;
|
||||
|
||||
date_height = date_width = 0;
|
||||
strftime(buf_time, sizeof(buf_time), time1_format, clock_gettime_for_tz(time1_timezone));
|
||||
get_text_size2(time1_font_desc, &time_height_ink, &time_height, &time_width, panel->area.height, panel->area.width, buf_time, strlen(buf_time),
|
||||
get_text_size2(time1_font_desc,
|
||||
&time_height_ink,
|
||||
&time_height,
|
||||
&time_width,
|
||||
panel->area.height,
|
||||
panel->area.width,
|
||||
buf_time,
|
||||
strlen(buf_time),
|
||||
PANGO_WRAP_WORD_CHAR,
|
||||
PANGO_ELLIPSIZE_NONE);
|
||||
if (time2_format) {
|
||||
strftime(buf_date, sizeof(buf_date), time2_format, clock_gettime_for_tz(time2_timezone));
|
||||
get_text_size2(time2_font_desc, &date_height_ink, &date_height, &date_width, panel->area.height, panel->area.width, buf_date, strlen(buf_date),
|
||||
get_text_size2(time2_font_desc,
|
||||
&date_height_ink,
|
||||
&date_height,
|
||||
&date_width,
|
||||
panel->area.height,
|
||||
panel->area.width,
|
||||
buf_date,
|
||||
strlen(buf_date),
|
||||
PANGO_WRAP_WORD_CHAR,
|
||||
PANGO_ELLIPSIZE_NONE);
|
||||
}
|
||||
@@ -274,8 +282,7 @@ int resize_clock (void *obj)
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
int new_size = time_height + date_height + (2 * (clock->area.paddingxlr + clock->area.bg->border.width));
|
||||
if (new_size != clock->area.height) {
|
||||
// we try to limit the number of resizes
|
||||
@@ -292,7 +299,6 @@ int resize_clock (void *obj)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void clock_action(int button)
|
||||
{
|
||||
char *command = 0;
|
||||
@@ -315,4 +321,3 @@ void clock_action(int button)
|
||||
}
|
||||
tint_exec(command);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "common.h"
|
||||
#include "area.h"
|
||||
|
||||
|
||||
typedef struct Clock {
|
||||
// always start with area
|
||||
Area area;
|
||||
@@ -23,7 +22,6 @@ typedef struct Clock {
|
||||
int time2_posy;
|
||||
} Clock;
|
||||
|
||||
|
||||
extern char *time1_format;
|
||||
extern char *time1_timezone;
|
||||
extern char *time2_format;
|
||||
@@ -39,7 +37,6 @@ extern char *clock_uwheel_command;
|
||||
extern char *clock_dwheel_command;
|
||||
extern int clock_enabled;
|
||||
|
||||
|
||||
// default global data
|
||||
void default_clock();
|
||||
|
||||
@@ -52,7 +49,7 @@ void init_clock_panel(void *panel);
|
||||
|
||||
void draw_clock(void *obj, cairo_t *c);
|
||||
|
||||
int resize_clock (void *obj);
|
||||
gboolean resize_clock(void *obj);
|
||||
|
||||
void clock_action(int button);
|
||||
|
||||
|
||||
579
src/config.c
579
src/config.c
@@ -75,7 +75,6 @@ static int read_border_color_hover;
|
||||
static int read_bg_color_press;
|
||||
static int read_border_color_press;
|
||||
|
||||
|
||||
void default_config()
|
||||
{
|
||||
config_path = NULL;
|
||||
@@ -91,8 +90,7 @@ void cleanup_config()
|
||||
snapshot_path = NULL;
|
||||
}
|
||||
|
||||
|
||||
void get_action (char *event, int *action)
|
||||
void get_action(char *event, MouseAction *action)
|
||||
{
|
||||
if (strcmp(event, "none") == 0)
|
||||
*action = NONE;
|
||||
@@ -120,7 +118,6 @@ void get_action (char *event, int *action)
|
||||
fprintf(stderr, "Error: unrecognized action '%s'. Please fix your config file.\n", event);
|
||||
}
|
||||
|
||||
|
||||
int get_task_status(char *status)
|
||||
{
|
||||
if (strcmp(status, "active") == 0)
|
||||
@@ -132,7 +129,6 @@ int get_task_status(char* status)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int config_get_monitor(char *monitor)
|
||||
{
|
||||
if (strcmp(monitor, "all") != 0) {
|
||||
@@ -143,7 +139,7 @@ int config_get_monitor(char* monitor)
|
||||
else {
|
||||
// monitor specified by name, not by index
|
||||
int i, j;
|
||||
for (i=0; i<server.nb_monitor; ++i) {
|
||||
for (i = 0; i < server.num_monitors; ++i) {
|
||||
if (server.monitor[i].names == 0)
|
||||
// xrandr can't identify monitors
|
||||
continue;
|
||||
@@ -229,84 +225,87 @@ void add_entry (char *key, char *value)
|
||||
read_border_color_hover = 0;
|
||||
read_bg_color_press = 0;
|
||||
read_border_color_press = 0;
|
||||
}
|
||||
else if (strcmp (key, "border_width") == 0) {
|
||||
} else if (strcmp(key, "border_width") == 0) {
|
||||
g_array_index(backgrounds, Background, backgrounds->len - 1).border.width = atoi(value);
|
||||
}
|
||||
else if (strcmp (key, "background_color") == 0) {
|
||||
} else if (strcmp(key, "background_color") == 0) {
|
||||
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1);
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, bg->fill_color.rgb);
|
||||
if (value2) bg->fill_color.alpha = (atoi (value2) / 100.0);
|
||||
else bg->fill_color.alpha = 0.5;
|
||||
}
|
||||
else if (strcmp (key, "border_color") == 0) {
|
||||
if (value2)
|
||||
bg->fill_color.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
bg->fill_color.alpha = 0.5;
|
||||
} else if (strcmp(key, "border_color") == 0) {
|
||||
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1);
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, bg->border.color.rgb);
|
||||
if (value2) bg->border.color.alpha = (atoi (value2) / 100.0);
|
||||
else bg->border.color.alpha = 0.5;
|
||||
}
|
||||
else if (strcmp (key, "background_color_hover") == 0) {
|
||||
if (value2)
|
||||
bg->border.color.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
bg->border.color.alpha = 0.5;
|
||||
} else if (strcmp(key, "background_color_hover") == 0) {
|
||||
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1);
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, bg->fill_color_hover.rgb);
|
||||
if (value2) bg->fill_color_hover.alpha = (atoi (value2) / 100.0);
|
||||
else bg->fill_color_hover.alpha = 0.5;
|
||||
if (value2)
|
||||
bg->fill_color_hover.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
bg->fill_color_hover.alpha = 0.5;
|
||||
read_bg_color_hover = 1;
|
||||
}
|
||||
else if (strcmp (key, "border_color_hover") == 0) {
|
||||
} else if (strcmp(key, "border_color_hover") == 0) {
|
||||
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1);
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, bg->border_color_hover.rgb);
|
||||
if (value2) bg->border_color_hover.alpha = (atoi (value2) / 100.0);
|
||||
else bg->border_color_hover.alpha = 0.5;
|
||||
if (value2)
|
||||
bg->border_color_hover.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
bg->border_color_hover.alpha = 0.5;
|
||||
read_border_color_hover = 1;
|
||||
}
|
||||
else if (strcmp (key, "background_color_pressed") == 0) {
|
||||
} else if (strcmp(key, "background_color_pressed") == 0) {
|
||||
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1);
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, bg->fill_color_pressed.rgb);
|
||||
if (value2) bg->fill_color_pressed.alpha = (atoi (value2) / 100.0);
|
||||
else bg->fill_color_pressed.alpha = 0.5;
|
||||
if (value2)
|
||||
bg->fill_color_pressed.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
bg->fill_color_pressed.alpha = 0.5;
|
||||
read_bg_color_press = 1;
|
||||
}
|
||||
else if (strcmp (key, "border_color_pressed") == 0) {
|
||||
} else if (strcmp(key, "border_color_pressed") == 0) {
|
||||
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1);
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, bg->border_color_pressed.rgb);
|
||||
if (value2) bg->border_color_pressed.alpha = (atoi (value2) / 100.0);
|
||||
else bg->border_color_pressed.alpha = 0.5;
|
||||
if (value2)
|
||||
bg->border_color_pressed.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
bg->border_color_pressed.alpha = 0.5;
|
||||
read_border_color_press = 1;
|
||||
}
|
||||
|
||||
/* Panel */
|
||||
else if (strcmp(key, "panel_monitor") == 0) {
|
||||
panel_config.monitor = config_get_monitor(value);
|
||||
}
|
||||
else if (strcmp (key, "panel_size") == 0) {
|
||||
} else if (strcmp(key, "panel_size") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
|
||||
char *b;
|
||||
if ((b = strchr(value1, '%'))) {
|
||||
b[0] = '\0';
|
||||
panel_config.pourcentx = 1;
|
||||
panel_config.fractional_width = 1;
|
||||
}
|
||||
panel_config.area.width = atoi(value1);
|
||||
if (panel_config.area.width == 0) {
|
||||
// full width mode
|
||||
panel_config.area.width = 100;
|
||||
panel_config.pourcentx = 1;
|
||||
panel_config.fractional_width = 1;
|
||||
}
|
||||
if (value2) {
|
||||
if ((b = strchr(value2, '%'))) {
|
||||
b[0] = '\0';
|
||||
panel_config.pourcenty = 1;
|
||||
panel_config.fractional_height = 1;
|
||||
}
|
||||
panel_config.area.height = atoi(value2);
|
||||
}
|
||||
}
|
||||
else if (strcmp (key, "panel_items") == 0) {
|
||||
} else if (strcmp(key, "panel_items") == 0) {
|
||||
new_config_file = 1;
|
||||
panel_items_order = strdup(value);
|
||||
int j;
|
||||
@@ -337,48 +336,56 @@ void add_entry (char *key, char *value)
|
||||
if (panel_items_order[j] == 'C')
|
||||
clock_enabled = 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp (key, "panel_margin") == 0) {
|
||||
} else if (strcmp(key, "panel_margin") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
panel_config.marginx = atoi(value1);
|
||||
if (value2) panel_config.marginy = atoi (value2);
|
||||
}
|
||||
else if (strcmp (key, "panel_padding") == 0) {
|
||||
if (value2)
|
||||
panel_config.marginy = atoi(value2);
|
||||
} else if (strcmp(key, "panel_padding") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
panel_config.area.paddingxlr = panel_config.area.paddingx = atoi(value1);
|
||||
if (value2) panel_config.area.paddingy = atoi (value2);
|
||||
if (value3) panel_config.area.paddingx = atoi (value3);
|
||||
}
|
||||
else if (strcmp (key, "panel_position") == 0) {
|
||||
if (value2)
|
||||
panel_config.area.paddingy = atoi(value2);
|
||||
if (value3)
|
||||
panel_config.area.paddingx = atoi(value3);
|
||||
} else if (strcmp(key, "panel_position") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
if (strcmp (value1, "top") == 0) panel_position = TOP;
|
||||
if (strcmp(value1, "top") == 0)
|
||||
panel_position = TOP;
|
||||
else {
|
||||
if (strcmp (value1, "bottom") == 0) panel_position = BOTTOM;
|
||||
else panel_position = CENTER;
|
||||
if (strcmp(value1, "bottom") == 0)
|
||||
panel_position = BOTTOM;
|
||||
else
|
||||
panel_position = CENTER;
|
||||
}
|
||||
|
||||
if (!value2) panel_position |= CENTER;
|
||||
if (!value2)
|
||||
panel_position |= CENTER;
|
||||
else {
|
||||
if (strcmp (value2, "left") == 0) panel_position |= LEFT;
|
||||
if (strcmp(value2, "left") == 0)
|
||||
panel_position |= LEFT;
|
||||
else {
|
||||
if (strcmp (value2, "right") == 0) panel_position |= RIGHT;
|
||||
else panel_position |= CENTER;
|
||||
if (strcmp(value2, "right") == 0)
|
||||
panel_position |= RIGHT;
|
||||
else
|
||||
panel_position |= CENTER;
|
||||
}
|
||||
}
|
||||
if (!value3) panel_horizontal = 1;
|
||||
if (!value3)
|
||||
panel_horizontal = 1;
|
||||
else {
|
||||
if (strcmp (value3, "vertical") == 0) panel_horizontal = 0;
|
||||
else panel_horizontal = 1;
|
||||
if (strcmp(value3, "vertical") == 0)
|
||||
panel_horizontal = 0;
|
||||
else
|
||||
panel_horizontal = 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp (key, "font_shadow") == 0)
|
||||
} else if (strcmp(key, "font_shadow") == 0)
|
||||
panel_config.font_shadow = atoi(value);
|
||||
else if (strcmp(key, "panel_background_id") == 0) {
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
panel_config.area.bg = &g_array_index(backgrounds, Background, id);
|
||||
}
|
||||
else if (strcmp (key, "wm_menu") == 0)
|
||||
} else if (strcmp(key, "wm_menu") == 0)
|
||||
wm_menu = atoi(value);
|
||||
else if (strcmp(key, "panel_dock") == 0)
|
||||
panel_dock = atoi(value);
|
||||
@@ -391,11 +398,9 @@ void add_entry (char *key, char *value)
|
||||
panel_layer = TOP_LAYER;
|
||||
else
|
||||
panel_layer = NORMAL_LAYER;
|
||||
}
|
||||
else if (strcmp (key, "disable_transparency") == 0) {
|
||||
} else if (strcmp(key, "disable_transparency") == 0) {
|
||||
server.disable_transparency = atoi(value);
|
||||
}
|
||||
else if (strcmp (key, "panel_window_name") == 0) {
|
||||
} else if (strcmp(key, "panel_window_name") == 0) {
|
||||
if (strlen(value) > 0) {
|
||||
free(panel_window_name);
|
||||
panel_window_name = strdup(value);
|
||||
@@ -409,96 +414,85 @@ void add_entry (char *key, char *value)
|
||||
if (battery_low_status < 0 || battery_low_status > 100)
|
||||
battery_low_status = 0;
|
||||
#endif
|
||||
}
|
||||
else if (strcmp(key, "battery_lclick_command") == 0) {
|
||||
} else if (strcmp(key, "battery_lclick_command") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
battery_lclick_command = strdup(value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp(key, "battery_mclick_command") == 0) {
|
||||
} else if (strcmp(key, "battery_mclick_command") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
battery_mclick_command = strdup(value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp(key, "battery_rclick_command") == 0) {
|
||||
} else if (strcmp(key, "battery_rclick_command") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
battery_rclick_command = strdup(value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp(key, "battery_uwheel_command") == 0) {
|
||||
} else if (strcmp(key, "battery_uwheel_command") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
battery_uwheel_command = strdup(value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp(key, "battery_dwheel_command") == 0) {
|
||||
} else if (strcmp(key, "battery_dwheel_command") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
battery_dwheel_command = strdup(value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "battery_low_cmd") == 0) {
|
||||
} else if (strcmp(key, "battery_low_cmd") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
battery_low_cmd = strdup(value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "ac_connected_cmd") == 0) {
|
||||
} else if (strcmp(key, "ac_connected_cmd") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
ac_connected_cmd = strdup(value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "ac_disconnected_cmd") == 0) {
|
||||
} else if (strcmp(key, "ac_disconnected_cmd") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
ac_disconnected_cmd = strdup(value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "bat1_font") == 0) {
|
||||
} else if (strcmp(key, "bat1_font") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
bat1_font_desc = pango_font_description_from_string(value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "bat2_font") == 0) {
|
||||
} else if (strcmp(key, "bat2_font") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
bat2_font_desc = pango_font_description_from_string(value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "battery_font_color") == 0) {
|
||||
} else if (strcmp(key, "battery_font_color") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, panel_config.battery.font.rgb);
|
||||
if (value2) panel_config.battery.font.alpha = (atoi (value2) / 100.0);
|
||||
else panel_config.battery.font.alpha = 0.5;
|
||||
if (value2)
|
||||
panel_config.battery.font.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
panel_config.battery.font.alpha = 0.5;
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "battery_padding") == 0) {
|
||||
} else if (strcmp(key, "battery_padding") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
panel_config.battery.area.paddingxlr = panel_config.battery.area.paddingx = atoi(value1);
|
||||
if (value2) panel_config.battery.area.paddingy = atoi (value2);
|
||||
if (value3) panel_config.battery.area.paddingx = atoi (value3);
|
||||
if (value2)
|
||||
panel_config.battery.area.paddingy = atoi(value2);
|
||||
if (value3)
|
||||
panel_config.battery.area.paddingx = atoi(value3);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "battery_background_id") == 0) {
|
||||
} else if (strcmp(key, "battery_background_id") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
panel_config.battery.area.bg = &g_array_index(backgrounds, Background, id);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "battery_hide") == 0) {
|
||||
} else if (strcmp(key, "battery_hide") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
percentage_hide = atoi(value);
|
||||
if (percentage_hide == 0)
|
||||
percentage_hide = 101;
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "battery_tooltip") == 0) {
|
||||
} else if (strcmp(key, "battery_tooltip") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
battery_tooltip_enabled = atoi(value);
|
||||
#endif
|
||||
@@ -513,147 +507,131 @@ void add_entry (char *key, char *value)
|
||||
free(panel_items_order);
|
||||
panel_items_order = strdup(tmp);
|
||||
g_free(tmp);
|
||||
}
|
||||
else
|
||||
} else
|
||||
panel_items_order = strdup("C");
|
||||
}
|
||||
if (strlen(value) > 0) {
|
||||
time1_format = strdup(value);
|
||||
clock_enabled = 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp (key, "time2_format") == 0) {
|
||||
} else if (strcmp(key, "time2_format") == 0) {
|
||||
if (strlen(value) > 0)
|
||||
time2_format = strdup(value);
|
||||
}
|
||||
else if (strcmp (key, "time1_font") == 0) {
|
||||
} else if (strcmp(key, "time1_font") == 0) {
|
||||
time1_font_desc = pango_font_description_from_string(value);
|
||||
}
|
||||
else if (strcmp(key, "time1_timezone") == 0) {
|
||||
} else if (strcmp(key, "time1_timezone") == 0) {
|
||||
if (strlen(value) > 0)
|
||||
time1_timezone = strdup(value);
|
||||
}
|
||||
else if (strcmp(key, "time2_timezone") == 0) {
|
||||
} else if (strcmp(key, "time2_timezone") == 0) {
|
||||
if (strlen(value) > 0)
|
||||
time2_timezone = strdup(value);
|
||||
}
|
||||
else if (strcmp (key, "time2_font") == 0) {
|
||||
} else if (strcmp(key, "time2_font") == 0) {
|
||||
time2_font_desc = pango_font_description_from_string(value);
|
||||
}
|
||||
else if (strcmp (key, "clock_font_color") == 0) {
|
||||
} else if (strcmp(key, "clock_font_color") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, panel_config.clock.font.rgb);
|
||||
if (value2) panel_config.clock.font.alpha = (atoi (value2) / 100.0);
|
||||
else panel_config.clock.font.alpha = 0.5;
|
||||
}
|
||||
else if (strcmp (key, "clock_padding") == 0) {
|
||||
if (value2)
|
||||
panel_config.clock.font.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
panel_config.clock.font.alpha = 0.5;
|
||||
} else if (strcmp(key, "clock_padding") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
panel_config.clock.area.paddingxlr = panel_config.clock.area.paddingx = atoi(value1);
|
||||
if (value2) panel_config.clock.area.paddingy = atoi (value2);
|
||||
if (value3) panel_config.clock.area.paddingx = atoi (value3);
|
||||
}
|
||||
else if (strcmp (key, "clock_background_id") == 0) {
|
||||
if (value2)
|
||||
panel_config.clock.area.paddingy = atoi(value2);
|
||||
if (value3)
|
||||
panel_config.clock.area.paddingx = atoi(value3);
|
||||
} else if (strcmp(key, "clock_background_id") == 0) {
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
panel_config.clock.area.bg = &g_array_index(backgrounds, Background, id);
|
||||
}
|
||||
else if (strcmp(key, "clock_tooltip") == 0) {
|
||||
} else if (strcmp(key, "clock_tooltip") == 0) {
|
||||
if (strlen(value) > 0)
|
||||
time_tooltip_format = strdup(value);
|
||||
}
|
||||
else if (strcmp(key, "clock_tooltip_timezone") == 0) {
|
||||
} else if (strcmp(key, "clock_tooltip_timezone") == 0) {
|
||||
if (strlen(value) > 0)
|
||||
time_tooltip_timezone = strdup(value);
|
||||
}
|
||||
else if (strcmp(key, "clock_lclick_command") == 0) {
|
||||
} else if (strcmp(key, "clock_lclick_command") == 0) {
|
||||
if (strlen(value) > 0)
|
||||
clock_lclick_command = strdup(value);
|
||||
}
|
||||
else if (strcmp(key, "clock_mclick_command") == 0) {
|
||||
} else if (strcmp(key, "clock_mclick_command") == 0) {
|
||||
if (strlen(value) > 0)
|
||||
clock_mclick_command = strdup(value);
|
||||
}
|
||||
else if (strcmp(key, "clock_rclick_command") == 0) {
|
||||
} else if (strcmp(key, "clock_rclick_command") == 0) {
|
||||
if (strlen(value) > 0)
|
||||
clock_rclick_command = strdup(value);
|
||||
}
|
||||
else if (strcmp(key, "clock_uwheel_command") == 0) {
|
||||
} else if (strcmp(key, "clock_uwheel_command") == 0) {
|
||||
if (strlen(value) > 0)
|
||||
clock_uwheel_command = strdup(value);
|
||||
}
|
||||
else if (strcmp(key, "clock_dwheel_command") == 0) {
|
||||
} else if (strcmp(key, "clock_dwheel_command") == 0) {
|
||||
if (strlen(value) > 0)
|
||||
clock_dwheel_command = strdup(value);
|
||||
}
|
||||
|
||||
/* Taskbar */
|
||||
else if (strcmp(key, "taskbar_mode") == 0) {
|
||||
if (strcmp (value, "multi_desktop") == 0) panel_mode = MULTI_DESKTOP;
|
||||
else panel_mode = SINGLE_DESKTOP;
|
||||
}
|
||||
else if (strcmp (key, "taskbar_distribute_size") == 0) {
|
||||
if (strcmp(value, "multi_desktop") == 0)
|
||||
taskbar_mode = MULTI_DESKTOP;
|
||||
else
|
||||
taskbar_mode = SINGLE_DESKTOP;
|
||||
} else if (strcmp(key, "taskbar_distribute_size") == 0) {
|
||||
taskbar_distribute_size = atoi(value);
|
||||
}
|
||||
else if (strcmp (key, "taskbar_padding") == 0) {
|
||||
} else if (strcmp(key, "taskbar_padding") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
panel_config.g_taskbar.area.paddingxlr = panel_config.g_taskbar.area.paddingx = atoi(value1);
|
||||
if (value2) panel_config.g_taskbar.area.paddingy = atoi (value2);
|
||||
if (value3) panel_config.g_taskbar.area.paddingx = atoi (value3);
|
||||
}
|
||||
else if (strcmp (key, "taskbar_background_id") == 0) {
|
||||
if (value2)
|
||||
panel_config.g_taskbar.area.paddingy = atoi(value2);
|
||||
if (value3)
|
||||
panel_config.g_taskbar.area.paddingx = atoi(value3);
|
||||
} else if (strcmp(key, "taskbar_background_id") == 0) {
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
panel_config.g_taskbar.background[TASKBAR_NORMAL] = &g_array_index(backgrounds, Background, id);
|
||||
if (panel_config.g_taskbar.background[TASKBAR_ACTIVE] == 0)
|
||||
panel_config.g_taskbar.background[TASKBAR_ACTIVE] = panel_config.g_taskbar.background[TASKBAR_NORMAL];
|
||||
}
|
||||
else if (strcmp (key, "taskbar_active_background_id") == 0) {
|
||||
} else if (strcmp(key, "taskbar_active_background_id") == 0) {
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
panel_config.g_taskbar.background[TASKBAR_ACTIVE] = &g_array_index(backgrounds, Background, id);
|
||||
}
|
||||
else if (strcmp (key, "taskbar_name") == 0) {
|
||||
} else if (strcmp(key, "taskbar_name") == 0) {
|
||||
taskbarname_enabled = atoi(value);
|
||||
}
|
||||
else if (strcmp (key, "taskbar_name_padding") == 0) {
|
||||
} else if (strcmp(key, "taskbar_name_padding") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
panel_config.g_taskbar.area_name.paddingxlr = panel_config.g_taskbar.area_name.paddingx = atoi(value1);
|
||||
if (value2) panel_config.g_taskbar.area_name.paddingy = atoi (value2);
|
||||
}
|
||||
else if (strcmp (key, "taskbar_name_background_id") == 0) {
|
||||
if (value2)
|
||||
panel_config.g_taskbar.area_name.paddingy = atoi(value2);
|
||||
} else if (strcmp(key, "taskbar_name_background_id") == 0) {
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
panel_config.g_taskbar.background_name[TASKBAR_NORMAL] = &g_array_index(backgrounds, Background, id);
|
||||
if (panel_config.g_taskbar.background_name[TASKBAR_ACTIVE] == 0)
|
||||
panel_config.g_taskbar.background_name[TASKBAR_ACTIVE] = panel_config.g_taskbar.background_name[TASKBAR_NORMAL];
|
||||
}
|
||||
else if (strcmp (key, "taskbar_name_active_background_id") == 0) {
|
||||
panel_config.g_taskbar.background_name[TASKBAR_ACTIVE] =
|
||||
panel_config.g_taskbar.background_name[TASKBAR_NORMAL];
|
||||
} else if (strcmp(key, "taskbar_name_active_background_id") == 0) {
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
panel_config.g_taskbar.background_name[TASKBAR_ACTIVE] = &g_array_index(backgrounds, Background, id);
|
||||
}
|
||||
else if (strcmp (key, "taskbar_name_font") == 0) {
|
||||
} else if (strcmp(key, "taskbar_name_font") == 0) {
|
||||
panel_config.taskbarname_font_desc = pango_font_description_from_string(value);
|
||||
}
|
||||
else if (strcmp (key, "taskbar_name_font_color") == 0) {
|
||||
} else if (strcmp(key, "taskbar_name_font_color") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, taskbarname_font.rgb);
|
||||
if (value2) taskbarname_font.alpha = (atoi (value2) / 100.0);
|
||||
else taskbarname_font.alpha = 0.5;
|
||||
}
|
||||
else if (strcmp (key, "taskbar_name_active_font_color") == 0) {
|
||||
if (value2)
|
||||
taskbarname_font.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
taskbarname_font.alpha = 0.5;
|
||||
} else if (strcmp(key, "taskbar_name_active_font_color") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, taskbarname_active_font.rgb);
|
||||
if (value2) taskbarname_active_font.alpha = (atoi (value2) / 100.0);
|
||||
else taskbarname_active_font.alpha = 0.5;
|
||||
}
|
||||
else if (strcmp (key, "taskbar_hide_inactive_tasks") == 0) {
|
||||
if (value2)
|
||||
taskbarname_active_font.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
taskbarname_active_font.alpha = 0.5;
|
||||
} else if (strcmp(key, "taskbar_hide_inactive_tasks") == 0) {
|
||||
hide_inactive_tasks = atoi(value);
|
||||
}
|
||||
else if (strcmp (key, "taskbar_hide_different_monitor") == 0) {
|
||||
} else if (strcmp(key, "taskbar_hide_different_monitor") == 0) {
|
||||
hide_task_diff_monitor = atoi(value);
|
||||
}
|
||||
else if (strcmp (key, "taskbar_sort_order") == 0) {
|
||||
} else if (strcmp(key, "taskbar_sort_order") == 0) {
|
||||
if (strcmp(value, "center") == 0) {
|
||||
taskbar_sort_method = TASKBAR_SORT_CENTER;
|
||||
} else if (strcmp(value, "title") == 0) {
|
||||
@@ -661,8 +639,7 @@ void add_entry (char *key, char *value)
|
||||
} else {
|
||||
taskbar_sort_method = TASKBAR_NOSORT;
|
||||
}
|
||||
}
|
||||
else if (strcmp (key, "task_align") == 0) {
|
||||
} else if (strcmp(key, "task_align") == 0) {
|
||||
if (strcmp(value, "center") == 0) {
|
||||
taskbar_alignment = ALIGN_CENTER;
|
||||
} else if (strcmp(value, "right") == 0) {
|
||||
@@ -683,37 +660,35 @@ void add_entry (char *key, char *value)
|
||||
// old parameter : just for backward compatibility
|
||||
panel_config.g_task.maximum_width = atoi(value);
|
||||
panel_config.g_task.maximum_height = 30;
|
||||
}
|
||||
else if (strcmp (key, "task_maximum_size") == 0) {
|
||||
} else if (strcmp(key, "task_maximum_size") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
panel_config.g_task.maximum_width = atoi(value1);
|
||||
panel_config.g_task.maximum_height = 30;
|
||||
if (value2)
|
||||
panel_config.g_task.maximum_height = atoi(value2);
|
||||
}
|
||||
else if (strcmp (key, "task_padding") == 0) {
|
||||
} else if (strcmp(key, "task_padding") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
panel_config.g_task.area.paddingxlr = panel_config.g_task.area.paddingx = atoi(value1);
|
||||
if (value2) panel_config.g_task.area.paddingy = atoi (value2);
|
||||
if (value3) panel_config.g_task.area.paddingx = atoi (value3);
|
||||
}
|
||||
else if (strcmp (key, "task_font") == 0) {
|
||||
if (value2)
|
||||
panel_config.g_task.area.paddingy = atoi(value2);
|
||||
if (value3)
|
||||
panel_config.g_task.area.paddingx = atoi(value3);
|
||||
} else if (strcmp(key, "task_font") == 0) {
|
||||
panel_config.g_task.font_desc = pango_font_description_from_string(value);
|
||||
}
|
||||
else if (g_regex_match_simple("task.*_font_color", key, 0, 0)) {
|
||||
} else if (g_regex_match_simple("task.*_font_color", key, 0, 0)) {
|
||||
gchar **split = g_regex_split_simple("_", key, 0, 0);
|
||||
int status = g_strv_length(split) == 3 ? TASK_NORMAL : get_task_status(split[1]);
|
||||
g_strfreev(split);
|
||||
if (status >= 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
float alpha = 1;
|
||||
if (value2) alpha = (atoi (value2) / 100.0);
|
||||
if (value2)
|
||||
alpha = (atoi(value2) / 100.0);
|
||||
get_color(value1, panel_config.g_task.font[status].rgb);
|
||||
panel_config.g_task.font[status].alpha = alpha;
|
||||
panel_config.g_task.config_font_mask |= (1 << status);
|
||||
}
|
||||
}
|
||||
else if (g_regex_match_simple("task.*_icon_asb", key, 0, 0)) {
|
||||
} else if (g_regex_match_simple("task.*_icon_asb", key, 0, 0)) {
|
||||
gchar **split = g_regex_split_simple("_", key, 0, 0);
|
||||
int status = g_strv_length(split) == 3 ? TASK_NORMAL : get_task_status(split[1]);
|
||||
g_strfreev(split);
|
||||
@@ -724,8 +699,7 @@ void add_entry (char *key, char *value)
|
||||
panel_config.g_task.brightness[status] = atoi(value3);
|
||||
panel_config.g_task.config_asb_mask |= (1 << status);
|
||||
}
|
||||
}
|
||||
else if (g_regex_match_simple("task.*_background_id", key, 0, 0)) {
|
||||
} else if (g_regex_match_simple("task.*_background_id", key, 0, 0)) {
|
||||
gchar **split = g_regex_split_simple("_", key, 0, 0);
|
||||
int status = g_strv_length(split) == 3 ? TASK_NORMAL : get_task_status(split[1]);
|
||||
g_strfreev(split);
|
||||
@@ -734,7 +708,8 @@ void add_entry (char *key, char *value)
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
panel_config.g_task.background[status] = &g_array_index(backgrounds, Background, id);
|
||||
panel_config.g_task.config_background_mask |= (1 << status);
|
||||
if (status == TASK_NORMAL) panel_config.g_task.area.bg = panel_config.g_task.background[TASK_NORMAL];
|
||||
if (status == TASK_NORMAL)
|
||||
panel_config.g_task.area.bg = panel_config.g_task.background[TASK_NORMAL];
|
||||
}
|
||||
}
|
||||
// "tooltip" is deprecated but here for backwards compatibility
|
||||
@@ -750,21 +725,20 @@ void add_entry (char *key, char *value)
|
||||
free(panel_items_order);
|
||||
panel_items_order = strdup(tmp);
|
||||
g_free(tmp);
|
||||
}
|
||||
else
|
||||
} else
|
||||
panel_items_order = strdup("S");
|
||||
}
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
systray.area.paddingxlr = systray.area.paddingx = atoi(value1);
|
||||
if (value2) systray.area.paddingy = atoi (value2);
|
||||
if (value3) systray.area.paddingx = atoi (value3);
|
||||
}
|
||||
else if (strcmp (key, "systray_background_id") == 0) {
|
||||
if (value2)
|
||||
systray.area.paddingy = atoi(value2);
|
||||
if (value3)
|
||||
systray.area.paddingx = atoi(value3);
|
||||
} else if (strcmp(key, "systray_background_id") == 0) {
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
systray.area.bg = &g_array_index(backgrounds, Background, id);
|
||||
}
|
||||
else if (strcmp(key, "systray_sort") == 0) {
|
||||
} else if (strcmp(key, "systray_sort") == 0) {
|
||||
if (strcmp(value, "descending") == 0)
|
||||
systray.sort = SYSTRAY_SORT_DESCENDING;
|
||||
else if (strcmp(value, "ascending") == 0)
|
||||
@@ -773,17 +747,14 @@ void add_entry (char *key, char *value)
|
||||
systray.sort = SYSTRAY_SORT_LEFT2RIGHT;
|
||||
else if (strcmp(value, "right2left") == 0)
|
||||
systray.sort = SYSTRAY_SORT_RIGHT2LEFT;
|
||||
}
|
||||
else if (strcmp(key, "systray_icon_size") == 0) {
|
||||
} else if (strcmp(key, "systray_icon_size") == 0) {
|
||||
systray_max_icon_size = atoi(value);
|
||||
}
|
||||
else if (strcmp(key, "systray_icon_asb") == 0) {
|
||||
} else if (strcmp(key, "systray_icon_asb") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
systray.alpha = atoi(value1);
|
||||
systray.saturation = atoi(value2);
|
||||
systray.brightness = atoi(value3);
|
||||
}
|
||||
else if (strcmp(key, "systray_monitor") == 0) {
|
||||
} else if (strcmp(key, "systray_monitor") == 0) {
|
||||
systray_monitor = atoi(value) - 1;
|
||||
}
|
||||
|
||||
@@ -791,50 +762,42 @@ void add_entry (char *key, char *value)
|
||||
else if (strcmp(key, "launcher_padding") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
panel_config.launcher.area.paddingxlr = panel_config.launcher.area.paddingx = atoi(value1);
|
||||
if (value2) panel_config.launcher.area.paddingy = atoi (value2);
|
||||
if (value3) panel_config.launcher.area.paddingx = atoi (value3);
|
||||
}
|
||||
else if (strcmp (key, "launcher_background_id") == 0) {
|
||||
if (value2)
|
||||
panel_config.launcher.area.paddingy = atoi(value2);
|
||||
if (value3)
|
||||
panel_config.launcher.area.paddingx = atoi(value3);
|
||||
} else if (strcmp(key, "launcher_background_id") == 0) {
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
panel_config.launcher.area.bg = &g_array_index(backgrounds, Background, id);
|
||||
}
|
||||
else if (strcmp (key, "launcher_icon_background_id") == 0) {
|
||||
} else if (strcmp(key, "launcher_icon_background_id") == 0) {
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
launcher_icon_bg = &g_array_index(backgrounds, Background, id);
|
||||
}
|
||||
else if (strcmp(key, "launcher_icon_size") == 0) {
|
||||
} else if (strcmp(key, "launcher_icon_size") == 0) {
|
||||
launcher_max_icon_size = atoi(value);
|
||||
}
|
||||
else if (strcmp(key, "launcher_item_app") == 0) {
|
||||
} else if (strcmp(key, "launcher_item_app") == 0) {
|
||||
char *app = expand_tilde(value);
|
||||
panel_config.launcher.list_apps = g_slist_append(panel_config.launcher.list_apps, app);
|
||||
}
|
||||
else if (strcmp(key, "launcher_apps_dir") == 0) {
|
||||
} else if (strcmp(key, "launcher_apps_dir") == 0) {
|
||||
char *path = expand_tilde(value);
|
||||
load_launcher_app_dir(path);
|
||||
free(path);
|
||||
}
|
||||
else if (strcmp(key, "launcher_icon_theme") == 0) {
|
||||
} else if (strcmp(key, "launcher_icon_theme") == 0) {
|
||||
// if XSETTINGS manager running, tint2 use it.
|
||||
if (icon_theme_name_config)
|
||||
free(icon_theme_name_config);
|
||||
icon_theme_name_config = strdup(value);
|
||||
}
|
||||
else if (strcmp(key, "launcher_icon_theme_override") == 0) {
|
||||
} else if (strcmp(key, "launcher_icon_theme_override") == 0) {
|
||||
launcher_icon_theme_override = atoi(value);
|
||||
}
|
||||
else if (strcmp(key, "launcher_icon_asb") == 0) {
|
||||
} else if (strcmp(key, "launcher_icon_asb") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
launcher_alpha = atoi(value1);
|
||||
launcher_saturation = atoi(value2);
|
||||
launcher_brightness = atoi(value3);
|
||||
}
|
||||
else if (strcmp(key, "launcher_tooltip") == 0) {
|
||||
} else if (strcmp(key, "launcher_tooltip") == 0) {
|
||||
launcher_tooltip_enabled = atoi(value);
|
||||
}
|
||||
else if (strcmp(key, "startup_notifications") == 0) {
|
||||
} else if (strcmp(key, "startup_notifications") == 0) {
|
||||
startup_notifications = atoi(value);
|
||||
}
|
||||
|
||||
@@ -842,28 +805,27 @@ void add_entry (char *key, char *value)
|
||||
else if (strcmp(key, "tooltip_show_timeout") == 0) {
|
||||
int timeout_msec = 1000 * atof(value);
|
||||
g_tooltip.show_timeout_msec = timeout_msec;
|
||||
}
|
||||
else if (strcmp (key, "tooltip_hide_timeout") == 0) {
|
||||
} else if (strcmp(key, "tooltip_hide_timeout") == 0) {
|
||||
int timeout_msec = 1000 * atof(value);
|
||||
g_tooltip.hide_timeout_msec = timeout_msec;
|
||||
}
|
||||
else if (strcmp (key, "tooltip_padding") == 0) {
|
||||
} else if (strcmp(key, "tooltip_padding") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
if (value1) g_tooltip.paddingx = atoi(value1);
|
||||
if (value2) g_tooltip.paddingy = atoi(value2);
|
||||
}
|
||||
else if (strcmp (key, "tooltip_background_id") == 0) {
|
||||
if (value1)
|
||||
g_tooltip.paddingx = atoi(value1);
|
||||
if (value2)
|
||||
g_tooltip.paddingy = atoi(value2);
|
||||
} else if (strcmp(key, "tooltip_background_id") == 0) {
|
||||
int id = atoi(value);
|
||||
id = (id < backgrounds->len && id >= 0) ? id : 0;
|
||||
g_tooltip.bg = &g_array_index(backgrounds, Background, id);
|
||||
}
|
||||
else if (strcmp (key, "tooltip_font_color") == 0) {
|
||||
} else if (strcmp(key, "tooltip_font_color") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
get_color(value1, g_tooltip.font_color.rgb);
|
||||
if (value2) g_tooltip.font_color.alpha = (atoi (value2) / 100.0);
|
||||
else g_tooltip.font_color.alpha = 0.1;
|
||||
}
|
||||
else if (strcmp (key, "tooltip_font") == 0) {
|
||||
if (value2)
|
||||
g_tooltip.font_color.alpha = (atoi(value2) / 100.0);
|
||||
else
|
||||
g_tooltip.font_color.alpha = 0.1;
|
||||
} else if (strcmp(key, "tooltip_font") == 0) {
|
||||
g_tooltip.font_desc = pango_font_description_from_string(value);
|
||||
}
|
||||
|
||||
@@ -885,15 +847,13 @@ void add_entry (char *key, char *value)
|
||||
panel_config.mouse_over_alpha = atoi(value1);
|
||||
panel_config.mouse_over_saturation = atoi(value2);
|
||||
panel_config.mouse_over_brightness = atoi(value3);
|
||||
}
|
||||
else if (strcmp(key, "mouse_pressed_icon_asb") == 0) {
|
||||
} else if (strcmp(key, "mouse_pressed_icon_asb") == 0) {
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
panel_config.mouse_pressed_alpha = atoi(value1);
|
||||
panel_config.mouse_pressed_saturation = atoi(value2);
|
||||
panel_config.mouse_pressed_brightness = atoi(value3);
|
||||
}
|
||||
|
||||
|
||||
/* autohide options */
|
||||
else if (strcmp(key, "autohide") == 0)
|
||||
panel_autohide = atoi(value);
|
||||
@@ -908,8 +868,7 @@ void add_entry (char *key, char *value)
|
||||
panel_strut_policy = STRUT_NONE;
|
||||
else
|
||||
panel_strut_policy = STRUT_MINIMUM;
|
||||
}
|
||||
else if (strcmp(key, "autohide_height") == 0) {
|
||||
} else if (strcmp(key, "autohide_height") == 0) {
|
||||
panel_autohide_height = atoi(value);
|
||||
if (panel_autohide_height == 0) {
|
||||
// autohide need height > 0
|
||||
@@ -927,8 +886,7 @@ void add_entry (char *key, char *value)
|
||||
free(panel_items_order);
|
||||
panel_items_order = strdup(tmp);
|
||||
g_free(tmp);
|
||||
}
|
||||
else
|
||||
} else
|
||||
panel_items_order = strdup("S");
|
||||
}
|
||||
}
|
||||
@@ -943,8 +901,7 @@ void add_entry (char *key, char *value)
|
||||
free(panel_items_order);
|
||||
panel_items_order = strdup(tmp);
|
||||
g_free(tmp);
|
||||
}
|
||||
else
|
||||
} else
|
||||
panel_items_order = strdup("B");
|
||||
}
|
||||
}
|
||||
@@ -953,66 +910,22 @@ void add_entry (char *key, char *value)
|
||||
else
|
||||
fprintf(stderr, "tint2 : invalid option \"%s\",\n upgrade tint2 or correct your config file\n", key);
|
||||
|
||||
if (value1) free (value1);
|
||||
if (value2) free (value2);
|
||||
if (value3) free (value3);
|
||||
if (value1)
|
||||
free(value1);
|
||||
if (value2)
|
||||
free(value2);
|
||||
if (value3)
|
||||
free(value3);
|
||||
}
|
||||
|
||||
|
||||
int config_read ()
|
||||
{
|
||||
const gchar * const * system_dirs;
|
||||
gchar *path1;
|
||||
gint i;
|
||||
|
||||
// follow XDG specification
|
||||
// check tint2rc in user directory
|
||||
path1 = g_build_filename (g_get_user_config_dir(), "tint2", "tint2rc", NULL);
|
||||
if (g_file_test (path1, G_FILE_TEST_EXISTS)) {
|
||||
i = config_read_file (path1);
|
||||
config_path = strdup(path1);
|
||||
g_free(path1);
|
||||
return i;
|
||||
}
|
||||
g_free(path1);
|
||||
|
||||
// copy tint2rc from system directory to user directory
|
||||
gchar *path2 = 0;
|
||||
system_dirs = g_get_system_config_dirs();
|
||||
for (i = 0; system_dirs[i]; i++) {
|
||||
path2 = g_build_filename(system_dirs[i], "tint2", "tint2rc", NULL);
|
||||
|
||||
if (g_file_test(path2, G_FILE_TEST_EXISTS)) break;
|
||||
g_free(path2);
|
||||
path2 = 0;
|
||||
}
|
||||
|
||||
if (path2) {
|
||||
// copy file in user directory (path1)
|
||||
gchar *dir = g_build_filename (g_get_user_config_dir(), "tint2", NULL);
|
||||
if (!g_file_test (dir, G_FILE_TEST_IS_DIR)) g_mkdir(dir, 0777);
|
||||
g_free(dir);
|
||||
|
||||
path1 = g_build_filename (g_get_user_config_dir(), "tint2", "tint2rc", NULL);
|
||||
copy_file(path2, path1);
|
||||
g_free(path2);
|
||||
|
||||
i = config_read_file (path1);
|
||||
config_path = strdup(path1);
|
||||
g_free(path1);
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int config_read_file (const char *path)
|
||||
gboolean config_read_file(const char *path)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[512];
|
||||
char *key, *value;
|
||||
|
||||
if ((fp = fopen(path, "r")) == NULL) return 0;
|
||||
if ((fp = fopen(path, "r")) == NULL)
|
||||
return 0;
|
||||
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
if (parse_line(line, &key, &value)) {
|
||||
@@ -1031,8 +944,7 @@ int config_read_file (const char *path)
|
||||
free(panel_items_order);
|
||||
panel_items_order = strdup(tmp);
|
||||
g_free(tmp);
|
||||
}
|
||||
else
|
||||
} else
|
||||
panel_items_order = strdup("T");
|
||||
}
|
||||
|
||||
@@ -1051,5 +963,58 @@ int config_read_file (const char *path)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
gboolean config_read_default_path()
|
||||
{
|
||||
const gchar *const *system_dirs;
|
||||
gchar *path1;
|
||||
|
||||
// follow XDG specification
|
||||
// check tint2rc in user directory
|
||||
path1 = g_build_filename(g_get_user_config_dir(), "tint2", "tint2rc", NULL);
|
||||
if (g_file_test(path1, G_FILE_TEST_EXISTS)) {
|
||||
gboolean result = config_read_file(path1);
|
||||
config_path = strdup(path1);
|
||||
g_free(path1);
|
||||
return result;
|
||||
}
|
||||
g_free(path1);
|
||||
|
||||
// copy tint2rc from system directory to user directory
|
||||
gchar *path2 = 0;
|
||||
system_dirs = g_get_system_config_dirs();
|
||||
for (int i = 0; system_dirs[i]; i++) {
|
||||
path2 = g_build_filename(system_dirs[i], "tint2", "tint2rc", NULL);
|
||||
|
||||
if (g_file_test(path2, G_FILE_TEST_EXISTS))
|
||||
break;
|
||||
g_free(path2);
|
||||
path2 = 0;
|
||||
}
|
||||
|
||||
if (path2) {
|
||||
// copy file in user directory (path1)
|
||||
gchar *dir = g_build_filename(g_get_user_config_dir(), "tint2", NULL);
|
||||
if (!g_file_test(dir, G_FILE_TEST_IS_DIR))
|
||||
g_mkdir(dir, 0777);
|
||||
g_free(dir);
|
||||
|
||||
path1 = g_build_filename(g_get_user_config_dir(), "tint2", "tint2rc", NULL);
|
||||
copy_file(path2, path1);
|
||||
g_free(path2);
|
||||
|
||||
gboolean result = config_read_file(path1);
|
||||
config_path = strdup(path1);
|
||||
g_free(path1);
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean config_read()
|
||||
{
|
||||
if (config_path)
|
||||
return config_read_file(config_path);
|
||||
return config_read_default_path();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
extern char *config_path;
|
||||
extern char *snapshot_path;
|
||||
|
||||
@@ -18,8 +20,6 @@ void default_config();
|
||||
// freed memory
|
||||
void cleanup_config();
|
||||
|
||||
int config_read_file (const char *path);
|
||||
int config_read ();
|
||||
gboolean config_read();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <cairo.h>
|
||||
@@ -36,17 +35,18 @@ void init_freespace_panel(void *p)
|
||||
Panel *panel = (Panel *)p;
|
||||
FreeSpace *freespace = &panel->freespace;
|
||||
|
||||
if (freespace->area.bg == 0)
|
||||
if (!freespace->area.bg)
|
||||
freespace->area.bg = &g_array_index(backgrounds, Background, 0);
|
||||
freespace->area.parent = p;
|
||||
freespace->area.panel = p;
|
||||
freespace->area.size_mode = LAYOUT_FIXED;
|
||||
freespace->area.resize_needed = 1;
|
||||
freespace->area.on_screen = 1;
|
||||
freespace->area.on_screen = TRUE;
|
||||
freespace->area._resize = resize_freespace;
|
||||
}
|
||||
|
||||
int freespace_get_max_size(Panel *p) {
|
||||
int freespace_get_max_size(Panel *p)
|
||||
{
|
||||
// Get space used by every element except the freespace
|
||||
GList *walk;
|
||||
int size = 0;
|
||||
@@ -70,7 +70,8 @@ int freespace_get_max_size(Panel *p) {
|
||||
return size;
|
||||
}
|
||||
|
||||
int resize_freespace(void *obj) {
|
||||
gboolean resize_freespace(void *obj)
|
||||
{
|
||||
FreeSpace *freespace = (FreeSpace *)obj;
|
||||
Panel *panel = (Panel *)freespace->area.panel;
|
||||
if (!freespace->area.on_screen)
|
||||
@@ -87,7 +88,7 @@ int resize_freespace(void *obj) {
|
||||
freespace->area.height = size;
|
||||
}
|
||||
|
||||
freespace->area.redraw_needed = 1;
|
||||
panel_refresh = 1;
|
||||
freespace->area.redraw_needed = TRUE;
|
||||
panel_refresh = TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,6 @@ typedef struct FreeSpace {
|
||||
void cleanup_freespace();
|
||||
void init_freespace_panel(void *panel);
|
||||
|
||||
int resize_freespace(void *obj);
|
||||
gboolean resize_freespace(void *obj);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -52,7 +52,9 @@ void expand_exec(DesktopEntry *entry, const char *path)
|
||||
// %c -> Name
|
||||
// %k -> path
|
||||
if (entry->exec) {
|
||||
char *exec2 = calloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) + (entry->icon ? strlen(entry->icon) : 1) + 100, 1);
|
||||
char *exec2 = calloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) +
|
||||
(entry->icon ? strlen(entry->icon) : 1) + 100,
|
||||
1);
|
||||
char *p, *q;
|
||||
// p will never point to an escaped char
|
||||
for (p = entry->exec, q = exec2; *p; p++, q++) {
|
||||
@@ -63,12 +65,14 @@ void expand_exec(DesktopEntry *entry, const char *path)
|
||||
if (*p == '%') // For % we delete the backslash, i.e. write % over it
|
||||
q--;
|
||||
*q = *p;
|
||||
if (!*p) break;
|
||||
if (!*p)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (*p == '%') {
|
||||
p++;
|
||||
if (!*p) break;
|
||||
if (!*p)
|
||||
break;
|
||||
if (*p == 'i' && entry->icon != NULL) {
|
||||
sprintf(q, "--icon '%s'", entry->icon);
|
||||
q += strlen("--icon ''");
|
||||
@@ -113,16 +117,19 @@ int read_desktop_file(const char *path, DesktopEntry *entry)
|
||||
return 0;
|
||||
}
|
||||
|
||||
gchar **languages = (gchar **)g_get_language_names();
|
||||
const gchar **languages = (const gchar **)g_get_language_names();
|
||||
// lang_index is the index of the language for the best Name key in the language vector
|
||||
// lang_index_default is a constant that encodes the Name key without a language
|
||||
int lang_index, lang_index_default;
|
||||
#define LANG_DBG 0
|
||||
if (LANG_DBG) printf("Languages:");
|
||||
if (LANG_DBG)
|
||||
printf("Languages:");
|
||||
for (i = 0; languages[i]; i++) {
|
||||
if (LANG_DBG) printf(" %s", languages[i]);
|
||||
if (LANG_DBG)
|
||||
printf(" %s", languages[i]);
|
||||
}
|
||||
if (LANG_DBG) printf("\n");
|
||||
if (LANG_DBG)
|
||||
printf("\n");
|
||||
lang_index_default = i;
|
||||
// we currently do not know about any Name key at all, so use an invalid index
|
||||
lang_index = lang_index_default + 1;
|
||||
|
||||
@@ -38,7 +38,6 @@ typedef struct IconThemeDir {
|
||||
int threshold;
|
||||
} IconThemeDir;
|
||||
|
||||
|
||||
int parse_theme_line(char *line, char **key, char **value)
|
||||
{
|
||||
return parse_dektop_line(line, key, value);
|
||||
@@ -67,7 +66,7 @@ const GSList *get_icon_locations()
|
||||
return icon_locations;
|
||||
}
|
||||
|
||||
IconTheme *make_theme(char *name)
|
||||
IconTheme *make_theme(const char *name)
|
||||
{
|
||||
IconTheme *theme = calloc(1, sizeof(IconTheme));
|
||||
theme->name = strdup(name);
|
||||
@@ -77,7 +76,7 @@ IconTheme *make_theme(char *name)
|
||||
}
|
||||
|
||||
// TODO Use UTF8 when parsing the file
|
||||
IconTheme *load_theme_from_index(char *file_name, char *name)
|
||||
IconTheme *load_theme_from_index(const char *file_name, const char *name)
|
||||
{
|
||||
IconTheme *theme;
|
||||
FILE *f;
|
||||
@@ -169,8 +168,7 @@ IconTheme *load_theme_from_index(char *file_name, char *name)
|
||||
line[line_len - 1] = '\0';
|
||||
char *dir_name = line + 1;
|
||||
GSList *dir_item = theme->list_directories;
|
||||
while (dir_item != NULL)
|
||||
{
|
||||
while (dir_item != NULL) {
|
||||
IconThemeDir *dir = dir_item->data;
|
||||
if (strcmp(dir->name, dir_name) == 0) {
|
||||
current_dir = dir;
|
||||
@@ -186,7 +184,7 @@ IconTheme *load_theme_from_index(char *file_name, char *name)
|
||||
return theme;
|
||||
}
|
||||
|
||||
void load_theme_from_fs_dir(IconTheme *theme, char *dir_name)
|
||||
void load_theme_from_fs_dir(IconTheme *theme, const char *dir_name)
|
||||
{
|
||||
gchar *file_name = g_build_filename(dir_name, "index.theme", NULL);
|
||||
if (g_file_test(file_name, G_FILE_TEST_EXISTS)) {
|
||||
@@ -226,11 +224,10 @@ void load_theme_from_fs_dir(IconTheme *theme, char *dir_name)
|
||||
}
|
||||
}
|
||||
|
||||
IconTheme *load_theme_from_fs(char *name, IconTheme *theme)
|
||||
IconTheme *load_theme_from_fs(const char *name, IconTheme *theme)
|
||||
{
|
||||
gchar *dir_name = NULL;
|
||||
const GSList *location;
|
||||
for (location = get_icon_locations(); location; location = g_slist_next(location)) {
|
||||
for (const GSList *location = get_icon_locations(); location; location = g_slist_next(location)) {
|
||||
gchar *path = (gchar *)location->data;
|
||||
dir_name = g_build_filename(path, name, NULL);
|
||||
if (g_file_test(dir_name, G_FILE_TEST_IS_DIR)) {
|
||||
@@ -246,7 +243,7 @@ IconTheme *load_theme_from_fs(char *name, IconTheme *theme)
|
||||
return theme;
|
||||
}
|
||||
|
||||
IconTheme *load_theme(char *name)
|
||||
IconTheme *load_theme(const char *name)
|
||||
{
|
||||
// Look for name/index.theme in $HOME/.icons, /usr/share/icons, /usr/share/pixmaps (stop at the first found)
|
||||
// Parse index.theme -> list of IconThemeDir with attributes
|
||||
@@ -256,8 +253,7 @@ IconTheme *load_theme(char *name)
|
||||
return NULL;
|
||||
|
||||
gchar *file_name = NULL;
|
||||
const GSList *location;
|
||||
for (location = get_icon_locations(); location; location = g_slist_next(location)) {
|
||||
for (const GSList *location = get_icon_locations(); location; location = g_slist_next(location)) {
|
||||
gchar *path = (gchar *)location->data;
|
||||
file_name = g_build_filename(path, name, "index.theme", NULL);
|
||||
if (!g_file_test(file_name, G_FILE_TEST_EXISTS)) {
|
||||
@@ -283,14 +279,12 @@ void free_icon_theme(IconTheme *theme)
|
||||
return;
|
||||
free(theme->name);
|
||||
theme->name = NULL;
|
||||
GSList *l_inherits;
|
||||
for (l_inherits = theme->list_inherits; l_inherits ; l_inherits = l_inherits->next) {
|
||||
for (GSList *l_inherits = theme->list_inherits; l_inherits; l_inherits = l_inherits->next) {
|
||||
free(l_inherits->data);
|
||||
}
|
||||
g_slist_free(theme->list_inherits);
|
||||
theme->list_inherits = NULL;
|
||||
GSList *l_dir;
|
||||
for (l_dir = theme->list_directories; l_dir ; l_dir = l_dir->next) {
|
||||
for (GSList *l_dir = theme->list_directories; l_dir; l_dir = l_dir->next) {
|
||||
IconThemeDir *dir = (IconThemeDir *)l_dir->data;
|
||||
free(dir->name);
|
||||
free(l_dir->data);
|
||||
@@ -303,14 +297,13 @@ void free_themes(IconThemeWrapper *themes)
|
||||
{
|
||||
if (!themes)
|
||||
return;
|
||||
GSList *l;
|
||||
for (l = themes->themes; l ; l = l->next) {
|
||||
for (GSList *l = themes->themes; l; l = l->next) {
|
||||
IconTheme *theme = (IconTheme *)l->data;
|
||||
free_icon_theme(theme);
|
||||
free(theme);
|
||||
}
|
||||
g_slist_free(themes->themes);
|
||||
for (l = themes->themes_fallback; l ; l = l->next) {
|
||||
for (GSList *l = themes->themes_fallback; l; l = l->next) {
|
||||
IconTheme *theme = (IconTheme *)l->data;
|
||||
free_icon_theme(theme);
|
||||
free(theme);
|
||||
@@ -329,20 +322,23 @@ void test_launcher_read_theme_file()
|
||||
}
|
||||
printf("Loaded theme: %s\n", theme->name);
|
||||
GSList *item = theme->list_inherits;
|
||||
while (item != NULL)
|
||||
{
|
||||
while (item != NULL) {
|
||||
printf("Inherits:%s\n", (char *)item->data);
|
||||
item = g_slist_next(item);
|
||||
}
|
||||
item = theme->list_directories;
|
||||
while (item != NULL)
|
||||
{
|
||||
while (item != NULL) {
|
||||
IconThemeDir *dir = item->data;
|
||||
printf("Dir:%s Size=%d MinSize=%d MaxSize=%d Threshold=%d Type=%s\n",
|
||||
dir->name, dir->size, dir->min_size, dir->max_size, dir->threshold,
|
||||
dir->type == ICON_DIR_TYPE_FIXED ? "Fixed" :
|
||||
dir->type == ICON_DIR_TYPE_SCALABLE ? "Scalable" :
|
||||
dir->type == ICON_DIR_TYPE_THRESHOLD ? "Threshold" : "?????");
|
||||
dir->name,
|
||||
dir->size,
|
||||
dir->min_size,
|
||||
dir->max_size,
|
||||
dir->threshold,
|
||||
dir->type == ICON_DIR_TYPE_FIXED ? "Fixed" : dir->type == ICON_DIR_TYPE_SCALABLE
|
||||
? "Scalable"
|
||||
: dir->type == ICON_DIR_TYPE_THRESHOLD ? "Threshold"
|
||||
: "?????");
|
||||
item = g_slist_next(item);
|
||||
}
|
||||
fprintf(stdout, "\033[0m");
|
||||
@@ -369,18 +365,17 @@ void load_themes_helper(const char *name, GSList **themes, GSList **queued)
|
||||
|
||||
// Load wrapper->themes
|
||||
while (queue) {
|
||||
char *name = queue->data;
|
||||
queue = g_slist_remove(queue, name);
|
||||
char *queued_name = queue->data;
|
||||
queue = g_slist_remove(queue, queued_name);
|
||||
|
||||
fprintf(stderr, " '%s',", name);
|
||||
IconTheme *theme = load_theme(name);
|
||||
fprintf(stderr, " '%s',", queued_name);
|
||||
IconTheme *theme = load_theme(queued_name);
|
||||
if (theme != NULL) {
|
||||
*themes = g_slist_append(*themes, theme);
|
||||
|
||||
GSList *item = theme->list_inherits;
|
||||
int pos = 0;
|
||||
while (item != NULL)
|
||||
{
|
||||
while (item != NULL) {
|
||||
char *parent = item->data;
|
||||
if (!str_list_contains(*queued, parent)) {
|
||||
queue = g_slist_insert(queue, strdup(parent), pos);
|
||||
@@ -391,7 +386,7 @@ void load_themes_helper(const char *name, GSList **themes, GSList **queued)
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
free(queued_name);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
@@ -426,8 +421,7 @@ IconThemeWrapper *load_themes(const char *icon_theme_name)
|
||||
const gchar *name;
|
||||
while ((name = g_dir_read_name(d))) {
|
||||
gchar *file_name = g_build_filename(path, name, "index.theme", NULL);
|
||||
if (g_file_test(file_name, G_FILE_TEST_EXISTS) &&
|
||||
!g_file_test(file_name, G_FILE_TEST_IS_DIR)) {
|
||||
if (g_file_test(file_name, G_FILE_TEST_EXISTS) && !g_file_test(file_name, G_FILE_TEST_IS_DIR)) {
|
||||
load_themes_helper(name, &wrapper->themes_fallback, &queued);
|
||||
}
|
||||
g_free(file_name);
|
||||
@@ -509,8 +503,7 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
||||
extensions = g_slist_append(extensions, ".svg");
|
||||
#endif
|
||||
// if the icon name already contains one of the extensions (e.g. vlc.png instead of vlc) add a special entry
|
||||
GSList *ext;
|
||||
for (ext = extensions; ext; ext = g_slist_next(ext)) {
|
||||
for (GSList *ext = extensions; ext; ext = g_slist_next(ext)) {
|
||||
char *extension = (char *)ext->data;
|
||||
if (strlen(icon_name) > strlen(extension) &&
|
||||
strcmp(extension, icon_name + strlen(icon_name) - strlen(extension)) == 0) {
|
||||
@@ -540,7 +533,8 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
||||
char *file_name = calloc(file_name_size, 1);
|
||||
|
||||
for (theme = themes; theme; theme = g_slist_next(theme)) {
|
||||
((IconTheme*)theme->data)->list_directories = g_slist_sort_with_data(((IconTheme*)theme->data)->list_directories,
|
||||
((IconTheme *)theme->data)->list_directories =
|
||||
g_slist_sort_with_data(((IconTheme *)theme->data)->list_directories,
|
||||
compare_theme_directories,
|
||||
GINT_TO_POINTER(size));
|
||||
GSList *dir;
|
||||
@@ -549,24 +543,23 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
||||
gboolean possible = directory_size_distance((IconThemeDir *)dir->data, size) < minimal_size &&
|
||||
(!best_file_theme ? TRUE : theme == best_file_theme);
|
||||
// Next larger match
|
||||
possible = possible ||
|
||||
(((IconThemeDir*)dir->data)->size >= size &&
|
||||
possible = possible || (((IconThemeDir *)dir->data)->size >= size &&
|
||||
(next_larger_size == -1 || ((IconThemeDir *)dir->data)->size < next_larger_size) &&
|
||||
(!next_larger_theme ? 1 : theme == next_larger_theme));
|
||||
if (!possible)
|
||||
continue;
|
||||
const GSList *base;
|
||||
for (base = basenames; base; base = g_slist_next(base)) {
|
||||
GSList *ext;
|
||||
for (ext = extensions; ext; ext = g_slist_next(ext)) {
|
||||
for (GSList *ext = extensions; ext; ext = g_slist_next(ext)) {
|
||||
char *base_name = (char *)base->data;
|
||||
char *theme_name = ((IconTheme *)theme->data)->name;
|
||||
char *dir_name = ((IconThemeDir *)dir->data)->name;
|
||||
char *extension = (char *)ext->data;
|
||||
if (strlen(base_name) + strlen(theme_name) +
|
||||
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100 > file_name_size) {
|
||||
file_name_size = strlen(base_name) + strlen(theme_name) +
|
||||
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100;
|
||||
if (strlen(base_name) + strlen(theme_name) + strlen(dir_name) + strlen(icon_name) +
|
||||
strlen(extension) + 100 >
|
||||
file_name_size) {
|
||||
file_name_size = strlen(base_name) + strlen(theme_name) + strlen(dir_name) + strlen(icon_name) +
|
||||
strlen(extension) + 100;
|
||||
file_name = realloc(file_name, file_name_size);
|
||||
}
|
||||
file_name[0] = 0;
|
||||
@@ -578,7 +571,8 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
||||
if (DEBUG_ICON_SEARCH)
|
||||
printf("found: %s\n", file_name);
|
||||
// Closest match
|
||||
if (directory_size_distance((IconThemeDir*)dir->data, size) < minimal_size && (!best_file_theme ? 1 : theme == best_file_theme)) {
|
||||
if (directory_size_distance((IconThemeDir *)dir->data, size) < minimal_size &&
|
||||
(!best_file_theme ? 1 : theme == best_file_theme)) {
|
||||
if (best_file_name) {
|
||||
free(best_file_name);
|
||||
best_file_name = NULL;
|
||||
@@ -622,14 +616,11 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
||||
|
||||
// Look in unthemed icons
|
||||
{
|
||||
const GSList *base;
|
||||
for (base = basenames; base; base = g_slist_next(base)) {
|
||||
GSList *ext;
|
||||
for (ext = extensions; ext; ext = g_slist_next(ext)) {
|
||||
for (const GSList *base = basenames; base; base = g_slist_next(base)) {
|
||||
for (GSList *ext = extensions; ext; ext = g_slist_next(ext)) {
|
||||
char *base_name = (char *)base->data;
|
||||
char *extension = (char *)ext->data;
|
||||
char *file_name = calloc(strlen(base_name) + strlen(icon_name) +
|
||||
strlen(extension) + 100, 1);
|
||||
file_name = calloc(strlen(base_name) + strlen(icon_name) + strlen(extension) + 100, 1);
|
||||
// filename = directory/iconname.extension
|
||||
sprintf(file_name, "%s/%s%s", base_name, icon_name, extension);
|
||||
if (DEBUG_ICON_SEARCH)
|
||||
|
||||
@@ -74,7 +74,6 @@ void default_launcher()
|
||||
launcher_icon_bg = NULL;
|
||||
}
|
||||
|
||||
|
||||
void init_launcher()
|
||||
{
|
||||
if (launcher_enabled) {
|
||||
@@ -83,7 +82,6 @@ void init_launcher()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void init_launcher_panel(void *p)
|
||||
{
|
||||
Panel *panel = (Panel *)p;
|
||||
@@ -95,7 +93,7 @@ void init_launcher_panel(void *p)
|
||||
launcher->area.size_mode = LAYOUT_FIXED;
|
||||
launcher->area._resize = resize_launcher;
|
||||
launcher->area.resize_needed = 1;
|
||||
launcher->area.redraw_needed = 1;
|
||||
launcher->area.redraw_needed = TRUE;
|
||||
if (!launcher->area.bg)
|
||||
launcher->area.bg = &g_array_index(backgrounds, Background, 0);
|
||||
|
||||
@@ -106,14 +104,13 @@ void init_launcher_panel(void *p)
|
||||
if (launcher->list_apps == NULL)
|
||||
return;
|
||||
|
||||
launcher->area.on_screen = 1;
|
||||
panel_refresh = 1;
|
||||
launcher->area.on_screen = TRUE;
|
||||
panel_refresh = TRUE;
|
||||
|
||||
launcher_load_themes(launcher);
|
||||
launcher_load_icons(launcher);
|
||||
}
|
||||
|
||||
|
||||
void cleanup_launcher()
|
||||
{
|
||||
int i;
|
||||
@@ -123,8 +120,8 @@ void cleanup_launcher()
|
||||
xsettings_client_destroy(xsettings_client);
|
||||
xsettings_client = NULL;
|
||||
|
||||
for (i = 0; i < nb_panel; i++) {
|
||||
Panel *panel = &panel1[i];
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
Panel *panel = &panels[i];
|
||||
Launcher *launcher = &panel->launcher;
|
||||
cleanup_launcher_theme(launcher);
|
||||
}
|
||||
@@ -144,7 +141,6 @@ void cleanup_launcher()
|
||||
launcher_enabled = 0;
|
||||
}
|
||||
|
||||
|
||||
void cleanup_launcher_theme(Launcher *launcher)
|
||||
{
|
||||
free_area(&launcher->area);
|
||||
@@ -169,13 +165,12 @@ void cleanup_launcher_theme(Launcher *launcher)
|
||||
launcher->list_themes = NULL;
|
||||
}
|
||||
|
||||
|
||||
int resize_launcher(void *obj)
|
||||
gboolean resize_launcher(void *obj)
|
||||
{
|
||||
Launcher *launcher = obj;
|
||||
GSList *l;
|
||||
int count, icon_size;
|
||||
int icons_per_column=1, icons_per_row=1, marging=0;
|
||||
int icons_per_column = 1, icons_per_row = 1, margin = 0;
|
||||
|
||||
if (panel_horizontal) {
|
||||
icon_size = launcher->area.height;
|
||||
@@ -195,7 +190,8 @@ int resize_launcher(void *obj)
|
||||
launcherIcon->area.height = launcherIcon->icon_size;
|
||||
|
||||
// Get the path for an icon file with the new size
|
||||
char *new_icon_path = get_icon_path(launcher->list_themes, launcherIcon->icon_name, launcherIcon->icon_size);
|
||||
char *new_icon_path =
|
||||
get_icon_path(launcher->list_themes, launcherIcon->icon_name, launcherIcon->icon_size);
|
||||
if (!new_icon_path) {
|
||||
// Draw a blank icon
|
||||
free_icon(launcherIcon->image);
|
||||
@@ -234,8 +230,14 @@ int resize_launcher(void *obj)
|
||||
}
|
||||
|
||||
if (panel_config.mouse_effects) {
|
||||
launcherIcon->image_hover = adjust_icon(launcherIcon->image, panel_config.mouse_over_alpha, panel_config.mouse_over_saturation, panel_config.mouse_over_brightness);
|
||||
launcherIcon->image_pressed = adjust_icon(launcherIcon->image, panel_config.mouse_pressed_alpha, panel_config.mouse_pressed_saturation, panel_config.mouse_pressed_brightness);
|
||||
launcherIcon->image_hover = adjust_icon(launcherIcon->image,
|
||||
panel_config.mouse_over_alpha,
|
||||
panel_config.mouse_over_saturation,
|
||||
panel_config.mouse_over_brightness);
|
||||
launcherIcon->image_pressed = adjust_icon(launcherIcon->image,
|
||||
panel_config.mouse_pressed_alpha,
|
||||
panel_config.mouse_pressed_saturation,
|
||||
panel_config.mouse_pressed_brightness);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,32 +250,27 @@ int resize_launcher(void *obj)
|
||||
int height = launcher->area.height - 2 * launcher->area.bg->border.width - 2 * launcher->area.paddingy;
|
||||
// here icons_per_column always higher than 0
|
||||
icons_per_column = (height + launcher->area.paddingx) / (icon_size + launcher->area.paddingx);
|
||||
marging = height - (icons_per_column-1)*(icon_size+launcher->area.paddingx) - icon_size;
|
||||
margin = height - (icons_per_column - 1) * (icon_size + launcher->area.paddingx) - icon_size;
|
||||
icons_per_row = count / icons_per_column + (count % icons_per_column != 0);
|
||||
launcher->area.width = (2 * launcher->area.bg->border.width) +
|
||||
(2 * launcher->area.paddingxlr) +
|
||||
(icon_size * icons_per_row) +
|
||||
((icons_per_row-1) * launcher->area.paddingx);
|
||||
launcher->area.width = (2 * launcher->area.bg->border.width) + (2 * launcher->area.paddingxlr) +
|
||||
(icon_size * icons_per_row) + ((icons_per_row - 1) * launcher->area.paddingx);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (!count) {
|
||||
launcher->area.height = 0;
|
||||
} else {
|
||||
int width = launcher->area.width - 2 * launcher->area.bg->border.width - 2 * launcher->area.paddingy;
|
||||
// here icons_per_row always higher than 0
|
||||
icons_per_row = (width + launcher->area.paddingx) / (icon_size + launcher->area.paddingx);
|
||||
marging = width - (icons_per_row-1)*(icon_size+launcher->area.paddingx) - icon_size;
|
||||
margin = width - (icons_per_row - 1) * (icon_size + launcher->area.paddingx) - icon_size;
|
||||
icons_per_column = count / icons_per_row + (count % icons_per_row != 0);
|
||||
launcher->area.height = (2 * launcher->area.bg->border.width) +
|
||||
(2 * launcher->area.paddingxlr) +
|
||||
(icon_size * icons_per_column) +
|
||||
((icons_per_column-1) * launcher->area.paddingx);
|
||||
launcher->area.height = (2 * launcher->area.bg->border.width) + (2 * launcher->area.paddingxlr) +
|
||||
(icon_size * icons_per_column) + ((icons_per_column - 1) * launcher->area.paddingx);
|
||||
}
|
||||
}
|
||||
|
||||
int i, posx, posy;
|
||||
int start = launcher->area.bg->border.width + launcher->area.paddingy + marging/2;
|
||||
int start = launcher->area.bg->border.width + launcher->area.paddingy + margin / 2;
|
||||
if (panel_horizontal) {
|
||||
posy = start;
|
||||
posx = launcher->area.bg->border.width + launcher->area.paddingxlr;
|
||||
@@ -354,12 +351,18 @@ Imlib_Image scale_icon(Imlib_Image original, int icon_size)
|
||||
Imlib_Image icon_scaled;
|
||||
if (original) {
|
||||
imlib_context_set_image(original);
|
||||
icon_scaled = imlib_create_cropped_scaled_image(0, 0, imlib_image_get_width(), imlib_image_get_height(), icon_size, icon_size);
|
||||
icon_scaled =
|
||||
imlib_create_cropped_scaled_image(0, 0, imlib_image_get_width(), imlib_image_get_height(), icon_size, icon_size);
|
||||
|
||||
imlib_context_set_image(icon_scaled);
|
||||
imlib_image_set_has_alpha(1);
|
||||
DATA32 *data = imlib_image_get_data();
|
||||
adjust_asb(data, icon_size, icon_size, launcher_alpha, (float)launcher_saturation/100, (float)launcher_brightness/100);
|
||||
adjust_asb(data,
|
||||
icon_size,
|
||||
icon_size,
|
||||
launcher_alpha,
|
||||
(float)launcher_saturation / 100,
|
||||
(float)launcher_brightness / 100);
|
||||
imlib_image_put_back_data(data);
|
||||
|
||||
imlib_context_set_image(icon_scaled);
|
||||
@@ -451,11 +454,11 @@ void launcher_load_icons(Launcher *launcher)
|
||||
launcherIcon->area.size_mode = LAYOUT_FIXED;
|
||||
launcherIcon->area._resize = NULL;
|
||||
launcherIcon->area.resize_needed = 0;
|
||||
launcherIcon->area.redraw_needed = 1;
|
||||
launcherIcon->area.redraw_needed = TRUE;
|
||||
launcherIcon->area.has_mouse_over_effect = 1;
|
||||
launcherIcon->area.has_mouse_press_effect = 1;
|
||||
launcherIcon->area.bg = launcher_icon_bg;
|
||||
launcherIcon->area.on_screen = 1;
|
||||
launcherIcon->area.on_screen = TRUE;
|
||||
launcherIcon->area._on_change_layout = launcher_icon_on_change_layout;
|
||||
if (launcher_tooltip_enabled) {
|
||||
launcherIcon->area._get_tooltip_text = launcher_icon_get_tooltip_text;
|
||||
@@ -475,19 +478,13 @@ void launcher_load_icons(Launcher *launcher)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Populates the list_themes list
|
||||
void launcher_load_themes(Launcher *launcher)
|
||||
{
|
||||
launcher->list_themes = load_themes(launcher_icon_theme_override
|
||||
? (icon_theme_name_config
|
||||
? icon_theme_name_config
|
||||
: icon_theme_name_xsettings
|
||||
? icon_theme_name_xsettings
|
||||
: "hicolor")
|
||||
: (icon_theme_name_xsettings
|
||||
? icon_theme_name_xsettings
|
||||
: icon_theme_name_config
|
||||
? icon_theme_name_config
|
||||
: "hicolor"));
|
||||
launcher->list_themes =
|
||||
load_themes(launcher_icon_theme_override
|
||||
? (icon_theme_name_config ? icon_theme_name_config
|
||||
: icon_theme_name_xsettings ? icon_theme_name_xsettings : "hicolor")
|
||||
: (icon_theme_name_xsettings ? icon_theme_name_xsettings
|
||||
: icon_theme_name_config ? icon_theme_name_config : "hicolor"));
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ void init_launcher_panel(void *panel);
|
||||
void cleanup_launcher();
|
||||
void cleanup_launcher_theme(Launcher *launcher);
|
||||
|
||||
int resize_launcher(void *obj);
|
||||
gboolean resize_launcher(void *obj);
|
||||
void draw_launcher(void *obj, cairo_t *c);
|
||||
|
||||
// Populates the list_icons list
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
#include "panel.h"
|
||||
#include "launcher.h"
|
||||
|
||||
struct _XSettingsClient
|
||||
{
|
||||
struct _XSettingsClient {
|
||||
Display *display;
|
||||
int screen;
|
||||
XSettingsNotifyFunc notify;
|
||||
@@ -45,7 +44,6 @@ struct _XSettingsClient
|
||||
XSettingsList *settings;
|
||||
};
|
||||
|
||||
|
||||
void xsettings_notify_cb(const char *name, XSettingsAction action, XSettingsSetting *setting, void *data)
|
||||
{
|
||||
// printf("xsettings_notify_cb\n");
|
||||
@@ -59,8 +57,8 @@ void xsettings_notify_cb (const char *name, XSettingsAction action, XSettingsSet
|
||||
icon_theme_name_xsettings = strdup(setting->data.v_string);
|
||||
|
||||
int i;
|
||||
for (i = 0 ; i < nb_panel ; i++) {
|
||||
Launcher *launcher = &panel1[i].launcher;
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
Launcher *launcher = &panels[i].launcher;
|
||||
cleanup_launcher_theme(launcher);
|
||||
launcher_load_themes(launcher);
|
||||
launcher_load_icons(launcher);
|
||||
@@ -70,7 +68,6 @@ void xsettings_notify_cb (const char *name, XSettingsAction action, XSettingsSet
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void notify_changes(XSettingsClient *client, XSettingsList *old_list)
|
||||
{
|
||||
XSettingsList *old_iter = old_list;
|
||||
@@ -91,12 +88,10 @@ static void notify_changes (XSettingsClient *client, XSettingsList *old_list)
|
||||
|
||||
if (cmp < 0) {
|
||||
client->notify(old_iter->setting->name, XSETTINGS_ACTION_DELETED, NULL, client->cb_data);
|
||||
}
|
||||
else if (cmp == 0) {
|
||||
} else if (cmp == 0) {
|
||||
if (!xsettings_setting_equal(old_iter->setting, new_iter->setting))
|
||||
client->notify(old_iter->setting->name, XSETTINGS_ACTION_CHANGED, new_iter->setting, client->cb_data);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
client->notify(new_iter->setting->name, XSETTINGS_ACTION_NEW, new_iter->setting, client->cb_data);
|
||||
}
|
||||
|
||||
@@ -107,7 +102,6 @@ static void notify_changes (XSettingsClient *client, XSettingsList *old_list)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int ignore_errors(Display *display, XErrorEvent *event)
|
||||
{
|
||||
return True;
|
||||
@@ -135,7 +129,6 @@ static XSettingsResult fetch_card16 (XSettingsBuffer *buffer, CARD16 *result)
|
||||
return XSETTINGS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static XSettingsResult fetch_ushort(XSettingsBuffer *buffer, unsigned short *result)
|
||||
{
|
||||
CARD16 x;
|
||||
@@ -148,7 +141,6 @@ static XSettingsResult fetch_ushort (XSettingsBuffer *buffer, unsigned short *r
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static XSettingsResult fetch_card32(XSettingsBuffer *buffer, CARD32 *result)
|
||||
{
|
||||
CARD32 x;
|
||||
@@ -342,7 +334,6 @@ static XSettingsList *parse_settings (unsigned char *data, size_t len)
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
static void read_settings(XSettingsClient *client)
|
||||
{
|
||||
Atom type;
|
||||
@@ -358,14 +349,24 @@ static void read_settings (XSettingsClient *client)
|
||||
client->settings = NULL;
|
||||
|
||||
old_handler = XSetErrorHandler(ignore_errors);
|
||||
result = XGetWindowProperty (client->display, client->manager_window, server.atom._XSETTINGS_SETTINGS, 0, LONG_MAX, False, server.atom._XSETTINGS_SETTINGS, &type, &format, &n_items, &bytes_after, &data);
|
||||
result = XGetWindowProperty(client->display,
|
||||
client->manager_window,
|
||||
server.atom._XSETTINGS_SETTINGS,
|
||||
0,
|
||||
LONG_MAX,
|
||||
False,
|
||||
server.atom._XSETTINGS_SETTINGS,
|
||||
&type,
|
||||
&format,
|
||||
&n_items,
|
||||
&bytes_after,
|
||||
&data);
|
||||
XSetErrorHandler(old_handler);
|
||||
|
||||
if (result == Success && type == server.atom._XSETTINGS_SETTINGS) {
|
||||
if (format != 8) {
|
||||
fprintf(stderr, "Invalid format for XSETTINGS property %d", format);
|
||||
}
|
||||
else
|
||||
} else
|
||||
client->settings = parse_settings(data, n_items);
|
||||
XFree(data);
|
||||
}
|
||||
@@ -374,7 +375,6 @@ static void read_settings (XSettingsClient *client)
|
||||
xsettings_list_free(old_list);
|
||||
}
|
||||
|
||||
|
||||
static void check_manager_window(XSettingsClient *client)
|
||||
{
|
||||
if (client->manager_window && client->watch)
|
||||
@@ -395,8 +395,11 @@ static void check_manager_window (XSettingsClient *client)
|
||||
read_settings(client);
|
||||
}
|
||||
|
||||
|
||||
XSettingsClient *xsettings_client_new (Display *display, int screen, XSettingsNotifyFunc notify, XSettingsWatchFunc watch, void *cb_data)
|
||||
XSettingsClient *xsettings_client_new(Display *display,
|
||||
int screen,
|
||||
XSettingsNotifyFunc notify,
|
||||
XSettingsWatchFunc watch,
|
||||
void *cb_data)
|
||||
{
|
||||
XSettingsClient *client;
|
||||
|
||||
@@ -422,12 +425,10 @@ XSettingsClient *xsettings_client_new (Display *display, int screen, XSettingsNo
|
||||
printf("NO XSETTINGS manager, tint2 use config 'launcher_icon_theme'.\n");
|
||||
free(client);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
void xsettings_client_destroy(XSettingsClient *client)
|
||||
{
|
||||
if (client->watch)
|
||||
@@ -439,19 +440,16 @@ void xsettings_client_destroy (XSettingsClient *client)
|
||||
free(client);
|
||||
}
|
||||
|
||||
|
||||
XSettingsResult xsettings_client_get_setting(XSettingsClient *client, const char *name, XSettingsSetting **setting)
|
||||
{
|
||||
XSettingsSetting *search = xsettings_list_lookup(client->settings, name);
|
||||
if (search) {
|
||||
*setting = xsettings_setting_copy(search);
|
||||
return *setting ? XSETTINGS_SUCCESS : XSETTINGS_NO_MEM;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return XSETTINGS_NO_ENTRY;
|
||||
}
|
||||
|
||||
|
||||
Bool xsettings_client_process_event(XSettingsClient *client, XEvent *xev)
|
||||
{
|
||||
/* The checks here will not unlikely cause us to reread
|
||||
@@ -464,13 +462,11 @@ Bool xsettings_client_process_event (XSettingsClient *client, XEvent *xev)
|
||||
check_manager_window(client);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
else if (xev->xany.window == client->manager_window) {
|
||||
} else if (xev->xany.window == client->manager_window) {
|
||||
if (xev->xany.type == DestroyNotify) {
|
||||
check_manager_window(client);
|
||||
return True;
|
||||
}
|
||||
else if (xev->xany.type == PropertyNotify) {
|
||||
} else if (xev->xany.type == PropertyNotify) {
|
||||
read_settings(client);
|
||||
return True;
|
||||
}
|
||||
@@ -478,4 +474,3 @@ Bool xsettings_client_process_event (XSettingsClient *client, XEvent *xev)
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,17 +32,16 @@ extern "C" {
|
||||
|
||||
typedef struct _XSettingsClient XSettingsClient;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
XSETTINGS_ACTION_NEW,
|
||||
XSETTINGS_ACTION_CHANGED,
|
||||
XSETTINGS_ACTION_DELETED
|
||||
} XSettingsAction;
|
||||
typedef enum { XSETTINGS_ACTION_NEW, XSETTINGS_ACTION_CHANGED, XSETTINGS_ACTION_DELETED } XSettingsAction;
|
||||
|
||||
typedef void (*XSettingsNotifyFunc)(const char *name, XSettingsAction action, XSettingsSetting *setting, void *cb_data);
|
||||
typedef void (*XSettingsWatchFunc)(Window window, Bool is_start, long mask, void *cb_data);
|
||||
|
||||
XSettingsClient *xsettings_client_new (Display *display, int screen, XSettingsNotifyFunc notify, XSettingsWatchFunc watch, void *cb_data);
|
||||
XSettingsClient *xsettings_client_new(Display *display,
|
||||
int screen,
|
||||
XSettingsNotifyFunc notify,
|
||||
XSettingsWatchFunc watch,
|
||||
void *cb_data);
|
||||
void xsettings_client_destroy(XSettingsClient *client);
|
||||
Bool xsettings_client_process_event(XSettingsClient *client, XEvent *xev);
|
||||
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
|
||||
#include "xsettings-common.h"
|
||||
|
||||
XSettingsSetting *
|
||||
xsettings_setting_copy (XSettingsSetting *setting)
|
||||
XSettingsSetting *xsettings_setting_copy(XSettingsSetting *setting)
|
||||
{
|
||||
XSettingsSetting *result;
|
||||
size_t str_len;
|
||||
@@ -47,8 +46,7 @@ xsettings_setting_copy (XSettingsSetting *setting)
|
||||
|
||||
result->type = setting->type;
|
||||
|
||||
switch (setting->type)
|
||||
{
|
||||
switch (setting->type) {
|
||||
case XSETTINGS_TYPE_INT:
|
||||
result->data.v_int = setting->data.v_int;
|
||||
break;
|
||||
@@ -79,15 +77,13 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XSettingsList *
|
||||
xsettings_list_copy (XSettingsList *list)
|
||||
XSettingsList *xsettings_list_copy(XSettingsList *list)
|
||||
{
|
||||
XSettingsList *new = NULL;
|
||||
XSettingsList *old_iter = list;
|
||||
XSettingsList *new_iter = NULL;
|
||||
|
||||
while (old_iter)
|
||||
{
|
||||
while (old_iter) {
|
||||
XSettingsList *new_node;
|
||||
|
||||
new_node = calloc(1, sizeof *new_node);
|
||||
@@ -95,8 +91,7 @@ xsettings_list_copy (XSettingsList *list)
|
||||
goto error;
|
||||
|
||||
new_node->setting = xsettings_setting_copy(old_iter->setting);
|
||||
if (!new_node->setting)
|
||||
{
|
||||
if (!new_node->setting) {
|
||||
free(new_node);
|
||||
goto error;
|
||||
}
|
||||
@@ -118,9 +113,7 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
xsettings_setting_equal (XSettingsSetting *setting_a,
|
||||
XSettingsSetting *setting_b)
|
||||
int xsettings_setting_equal(XSettingsSetting *setting_a, XSettingsSetting *setting_b)
|
||||
{
|
||||
if (setting_a->type != setting_b->type)
|
||||
return 0;
|
||||
@@ -128,8 +121,7 @@ xsettings_setting_equal (XSettingsSetting *setting_a,
|
||||
if (strcmp(setting_a->name, setting_b->name) != 0)
|
||||
return 0;
|
||||
|
||||
switch (setting_a->type)
|
||||
{
|
||||
switch (setting_a->type) {
|
||||
case XSETTINGS_TYPE_INT:
|
||||
return setting_a->data.v_int == setting_b->data.v_int;
|
||||
case XSETTINGS_TYPE_COLOR:
|
||||
@@ -146,8 +138,7 @@ xsettings_setting_equal (XSettingsSetting *setting_a,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
xsettings_setting_free (XSettingsSetting *setting)
|
||||
void xsettings_setting_free(XSettingsSetting *setting)
|
||||
{
|
||||
if (setting->type == XSETTINGS_TYPE_STRING)
|
||||
free(setting->data.v_string);
|
||||
@@ -158,11 +149,9 @@ xsettings_setting_free (XSettingsSetting *setting)
|
||||
free(setting);
|
||||
}
|
||||
|
||||
void
|
||||
xsettings_list_free (XSettingsList *list)
|
||||
{
|
||||
while (list)
|
||||
void xsettings_list_free(XSettingsList *list)
|
||||
{
|
||||
while (list) {
|
||||
XSettingsList *next = list->next;
|
||||
|
||||
xsettings_setting_free(list->setting);
|
||||
@@ -172,9 +161,7 @@ xsettings_list_free (XSettingsList *list)
|
||||
}
|
||||
}
|
||||
|
||||
XSettingsResult
|
||||
xsettings_list_insert (XSettingsList **list,
|
||||
XSettingsSetting *setting)
|
||||
XSettingsResult xsettings_list_insert(XSettingsList **list, XSettingsSetting *setting)
|
||||
{
|
||||
XSettingsList *node;
|
||||
XSettingsList *iter;
|
||||
@@ -186,14 +173,12 @@ xsettings_list_insert (XSettingsList **list,
|
||||
node->setting = setting;
|
||||
|
||||
iter = *list;
|
||||
while (iter)
|
||||
{
|
||||
while (iter) {
|
||||
int cmp = strcmp(setting->name, iter->setting->name);
|
||||
|
||||
if (cmp < 0)
|
||||
break;
|
||||
else if (cmp == 0)
|
||||
{
|
||||
else if (cmp == 0) {
|
||||
free(node);
|
||||
return XSETTINGS_DUPLICATE_ENTRY;
|
||||
}
|
||||
@@ -212,18 +197,14 @@ xsettings_list_insert (XSettingsList **list,
|
||||
return XSETTINGS_SUCCESS;
|
||||
}
|
||||
|
||||
XSettingsResult
|
||||
xsettings_list_delete (XSettingsList **list,
|
||||
const char *name)
|
||||
XSettingsResult xsettings_list_delete(XSettingsList **list, const char *name)
|
||||
{
|
||||
XSettingsList *iter;
|
||||
XSettingsList *last = NULL;
|
||||
|
||||
iter = *list;
|
||||
while (iter)
|
||||
{
|
||||
if (strcmp (name, iter->setting->name) == 0)
|
||||
{
|
||||
while (iter) {
|
||||
if (strcmp(name, iter->setting->name) == 0) {
|
||||
if (last)
|
||||
last->next = iter->next;
|
||||
else
|
||||
@@ -242,15 +223,12 @@ xsettings_list_delete (XSettingsList **list,
|
||||
return XSETTINGS_FAILED;
|
||||
}
|
||||
|
||||
XSettingsSetting *
|
||||
xsettings_list_lookup (XSettingsList *list,
|
||||
const char *name)
|
||||
XSettingsSetting *xsettings_list_lookup(XSettingsList *list, const char *name)
|
||||
{
|
||||
XSettingsList *iter;
|
||||
|
||||
iter = list;
|
||||
while (iter)
|
||||
{
|
||||
while (iter) {
|
||||
if (strcmp(name, iter->setting->name) == 0)
|
||||
return iter->setting;
|
||||
|
||||
@@ -260,8 +238,7 @@ xsettings_list_lookup (XSettingsList *list,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char
|
||||
xsettings_byte_order (void)
|
||||
char xsettings_byte_order(void)
|
||||
{
|
||||
CARD32 myint = 0x01020304;
|
||||
return (*(char *)&myint == 1) ? MSBFirst : LSBFirst;
|
||||
|
||||
@@ -35,16 +35,14 @@ typedef struct _XSettingsSetting XSettingsSetting;
|
||||
/* Types of settings possible. Enum values correspond to
|
||||
* protocol values.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
XSETTINGS_TYPE_INT = 0,
|
||||
XSETTINGS_TYPE_STRING = 1,
|
||||
XSETTINGS_TYPE_COLOR = 2,
|
||||
XSETTINGS_TYPE_NONE = 0xff
|
||||
} XSettingsType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
XSETTINGS_SUCCESS,
|
||||
XSETTINGS_NO_MEM,
|
||||
XSETTINGS_ACCESS,
|
||||
@@ -53,27 +51,23 @@ typedef enum
|
||||
XSETTINGS_DUPLICATE_ENTRY
|
||||
} XSettingsResult;
|
||||
|
||||
struct _XSettingsBuffer
|
||||
{
|
||||
struct _XSettingsBuffer {
|
||||
char byte_order;
|
||||
size_t len;
|
||||
unsigned char *data;
|
||||
unsigned char *pos;
|
||||
};
|
||||
|
||||
struct _XSettingsColor
|
||||
{
|
||||
struct _XSettingsColor {
|
||||
unsigned short red, green, blue, alpha;
|
||||
};
|
||||
|
||||
struct _XSettingsList
|
||||
{
|
||||
struct _XSettingsList {
|
||||
XSettingsSetting *setting;
|
||||
XSettingsList *next;
|
||||
};
|
||||
|
||||
struct _XSettingsSetting
|
||||
{
|
||||
struct _XSettingsSetting {
|
||||
char *name;
|
||||
XSettingsType type;
|
||||
|
||||
@@ -88,17 +82,13 @@ struct _XSettingsSetting
|
||||
|
||||
XSettingsSetting *xsettings_setting_copy(XSettingsSetting *setting);
|
||||
void xsettings_setting_free(XSettingsSetting *setting);
|
||||
int xsettings_setting_equal (XSettingsSetting *setting_a,
|
||||
XSettingsSetting *setting_b);
|
||||
int xsettings_setting_equal(XSettingsSetting *setting_a, XSettingsSetting *setting_b);
|
||||
|
||||
void xsettings_list_free(XSettingsList *list);
|
||||
XSettingsList *xsettings_list_copy(XSettingsList *list);
|
||||
XSettingsResult xsettings_list_insert (XSettingsList **list,
|
||||
XSettingsSetting *setting);
|
||||
XSettingsSetting *xsettings_list_lookup (XSettingsList *list,
|
||||
const char *name);
|
||||
XSettingsResult xsettings_list_delete (XSettingsList **list,
|
||||
const char *name);
|
||||
XSettingsResult xsettings_list_insert(XSettingsList **list, XSettingsSetting *setting);
|
||||
XSettingsSetting *xsettings_list_lookup(XSettingsList *list, const char *name);
|
||||
XSettingsResult xsettings_list_delete(XSettingsList **list, const char *name);
|
||||
|
||||
char xsettings_byte_order(void);
|
||||
|
||||
|
||||
563
src/panel.c
563
src/panel.c
File diff suppressed because it is too large
Load Diff
118
src/panel.h
118
src/panel.h
@@ -26,72 +26,78 @@
|
||||
#include "battery.h"
|
||||
#endif
|
||||
|
||||
|
||||
extern int signal_pending;
|
||||
// --------------------------------------------------
|
||||
// mouse events
|
||||
extern int mouse_left;
|
||||
extern int mouse_middle;
|
||||
extern int mouse_right;
|
||||
extern int mouse_scroll_up;
|
||||
extern int mouse_scroll_down;
|
||||
extern int mouse_tilt_left;
|
||||
extern int mouse_tilt_right;
|
||||
extern MouseAction mouse_left;
|
||||
extern MouseAction mouse_middle;
|
||||
extern MouseAction mouse_right;
|
||||
extern MouseAction mouse_scroll_up;
|
||||
extern MouseAction mouse_scroll_down;
|
||||
extern MouseAction mouse_tilt_left;
|
||||
extern MouseAction mouse_tilt_right;
|
||||
|
||||
// panel mode
|
||||
enum { SINGLE_DESKTOP=0, MULTI_DESKTOP };
|
||||
enum { BOTTOM_LAYER, NORMAL_LAYER, TOP_LAYER };
|
||||
extern int panel_mode;
|
||||
extern int wm_menu;
|
||||
extern int panel_dock;
|
||||
extern int panel_layer;
|
||||
extern char *panel_window_name;
|
||||
typedef enum TaskbarMode {
|
||||
SINGLE_DESKTOP = 0,
|
||||
MULTI_DESKTOP,
|
||||
} TaskbarMode;
|
||||
|
||||
typedef enum Layer {
|
||||
BOTTOM_LAYER,
|
||||
NORMAL_LAYER,
|
||||
TOP_LAYER,
|
||||
} Layer;
|
||||
|
||||
// panel position
|
||||
enum { LEFT=0x01, RIGHT=0x02, CENTER=0X04, TOP=0X08, BOTTOM=0x10 };
|
||||
extern int panel_position;
|
||||
extern int panel_horizontal;
|
||||
typedef enum PanelPosition {
|
||||
LEFT = 0x01,
|
||||
RIGHT = 0x02,
|
||||
CENTER = 0X04,
|
||||
TOP = 0X08,
|
||||
BOTTOM = 0x10,
|
||||
} PanelPosition;
|
||||
|
||||
extern int panel_refresh;
|
||||
extern int task_dragged;
|
||||
typedef enum Strut {
|
||||
STRUT_MINIMUM,
|
||||
STRUT_FOLLOW_SIZE,
|
||||
STRUT_NONE,
|
||||
} Strut;
|
||||
|
||||
//panel autohide
|
||||
enum { STRUT_MINIMUM, STRUT_FOLLOW_SIZE, STRUT_NONE };
|
||||
extern int panel_autohide;
|
||||
extern TaskbarMode taskbar_mode;
|
||||
extern gboolean wm_menu;
|
||||
extern gboolean panel_dock;
|
||||
extern Layer panel_layer;
|
||||
extern char *panel_window_name;
|
||||
extern PanelPosition panel_position;
|
||||
extern gboolean panel_horizontal;
|
||||
extern gboolean panel_refresh;
|
||||
extern gboolean task_dragged;
|
||||
extern gboolean panel_autohide;
|
||||
extern int panel_autohide_show_timeout;
|
||||
extern int panel_autohide_hide_timeout;
|
||||
extern int panel_autohide_height; // for vertical panels this is of course the width
|
||||
extern int panel_strut_policy;
|
||||
extern Strut panel_strut_policy;
|
||||
extern char *panel_items_order;
|
||||
|
||||
extern int max_tick_urgent;
|
||||
|
||||
extern GArray *backgrounds;
|
||||
|
||||
extern Imlib_Image default_icon;
|
||||
// TODO maybe this should be a config option
|
||||
#define DEFAULT_FONT "sans 10"
|
||||
|
||||
|
||||
// tint2 use one panel per monitor and one taskbar per desktop.
|
||||
typedef struct {
|
||||
// always start with area
|
||||
// area.list own all objects of the panel according to config file
|
||||
typedef struct Panel {
|
||||
Area area;
|
||||
|
||||
// --------------------------------------------------
|
||||
// panel
|
||||
Window main_win;
|
||||
Pixmap temp_pmap;
|
||||
|
||||
// position relative to root window
|
||||
int posx, posy;
|
||||
int marginx, marginy;
|
||||
int pourcentx, pourcenty;
|
||||
// location of the panel (monitor number)
|
||||
int fractional_width, fractional_height;
|
||||
int monitor;
|
||||
int font_shadow;
|
||||
int mouse_effects;
|
||||
gboolean mouse_effects;
|
||||
// Mouse effects for icons
|
||||
int mouse_over_alpha;
|
||||
int mouse_over_saturation;
|
||||
@@ -100,46 +106,34 @@ typedef struct {
|
||||
int mouse_pressed_saturation;
|
||||
int mouse_pressed_brightness;
|
||||
|
||||
// --------------------------------------------------
|
||||
// task and taskbar parameter per panel
|
||||
Global_taskbar g_taskbar;
|
||||
Global_task g_task;
|
||||
// Per-panel parameters and states for Taskbar and Task
|
||||
GlobalTaskbar g_taskbar;
|
||||
GlobalTask g_task;
|
||||
|
||||
// --------------------------------------------------
|
||||
// taskbar point to the first taskbar in panel.area.list.
|
||||
// number of tasbar == nb_desktop. taskbar[i] is for desktop(i).
|
||||
// taskbar[i] is used to loop over taskbar,
|
||||
// while panel->area.list is used to loop over all panel's objects
|
||||
// Array of Taskbar, with num_desktops items
|
||||
Taskbar *taskbar;
|
||||
int nb_desktop;
|
||||
int num_desktops;
|
||||
PangoFontDescription *taskbarname_font_desc;
|
||||
|
||||
// --------------------------------------------------
|
||||
// clock
|
||||
Clock clock;
|
||||
|
||||
// --------------------------------------------------
|
||||
// battery
|
||||
#ifdef ENABLE_BATTERY
|
||||
Battery battery;
|
||||
#endif
|
||||
|
||||
Launcher launcher;
|
||||
|
||||
FreeSpace freespace;
|
||||
|
||||
// autohide
|
||||
int is_hidden;
|
||||
// Autohide
|
||||
gboolean is_hidden;
|
||||
int hidden_width, hidden_height;
|
||||
Pixmap hidden_pixmap;
|
||||
timeout *autohide_timeout;
|
||||
} Panel;
|
||||
|
||||
|
||||
extern Panel panel_config;
|
||||
extern Panel *panel1;
|
||||
extern int nb_panel;
|
||||
|
||||
extern Panel *panels;
|
||||
extern int num_panels;
|
||||
|
||||
// default global data
|
||||
void default_panel();
|
||||
@@ -152,7 +146,7 @@ void cleanup_panel();
|
||||
void init_panel();
|
||||
|
||||
void init_panel_size_and_position(Panel *panel);
|
||||
int resize_panel(void *obj);
|
||||
gboolean resize_panel(void *obj);
|
||||
void render_panel(Panel *panel);
|
||||
|
||||
void set_panel_items_order(Panel *p);
|
||||
@@ -168,11 +162,11 @@ Taskbar *click_taskbar (Panel *panel, int x, int y);
|
||||
Task *click_task(Panel *panel, int x, int y);
|
||||
Launcher *click_launcher(Panel *panel, int x, int y);
|
||||
LauncherIcon *click_launcher_icon(Panel *panel, int x, int y);
|
||||
int click_padding(Panel *panel, int x, int y);
|
||||
int click_clock(Panel *panel, int x, int y);
|
||||
gboolean click_padding(Panel *panel, int x, int y);
|
||||
gboolean click_clock(Panel *panel, int x, int y);
|
||||
|
||||
#ifdef ENABLE_BATTERY
|
||||
int click_battery(Panel *panel, int x, int y);
|
||||
gboolean click_battery(Panel *panel, int x, int y);
|
||||
#endif
|
||||
|
||||
Area *click_area(Panel *panel, int x, int y);
|
||||
|
||||
177
src/server.c
177
src/server.c
@@ -21,7 +21,6 @@
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -32,7 +31,9 @@
|
||||
|
||||
Server_global server;
|
||||
|
||||
void server_catch_error (Display *d, XErrorEvent *ev){}
|
||||
void server_catch_error(Display *d, XErrorEvent *ev)
|
||||
{
|
||||
}
|
||||
|
||||
void server_init_atoms()
|
||||
{
|
||||
@@ -116,7 +117,6 @@ void server_init_atoms ()
|
||||
server.atom.TARGETS = XInternAtom(server.dsp, "TARGETS", False);
|
||||
}
|
||||
|
||||
|
||||
void cleanup_server()
|
||||
{
|
||||
if (server.colormap)
|
||||
@@ -126,8 +126,7 @@ void cleanup_server()
|
||||
XFreeColormap(server.dsp, server.colormap32);
|
||||
server.colormap32 = 0;
|
||||
if (server.monitor) {
|
||||
int i;
|
||||
for (i = 0; i < server.nb_monitor; ++i) {
|
||||
for (int i = 0; i < server.num_monitors; ++i) {
|
||||
g_strfreev(server.monitor[i].names);
|
||||
server.monitor[i].names = NULL;
|
||||
}
|
||||
@@ -140,7 +139,6 @@ void cleanup_server()
|
||||
server.disable_transparency = 0;
|
||||
}
|
||||
|
||||
|
||||
void send_event32(Window win, Atom at, long data1, long data2, long data3)
|
||||
{
|
||||
XEvent event;
|
||||
@@ -162,7 +160,6 @@ void send_event32 (Window win, Atom at, long data1, long data2, long data3)
|
||||
XSendEvent(server.dsp, server.root_win, False, SubstructureRedirectMask | SubstructureNotifyMask, &event);
|
||||
}
|
||||
|
||||
|
||||
int get_property32(Window win, Atom at, Atom type)
|
||||
{
|
||||
Atom type_ret;
|
||||
@@ -172,9 +169,21 @@ int get_property32 (Window win, Atom at, Atom type)
|
||||
unsigned char *prop_value = 0;
|
||||
int result;
|
||||
|
||||
if (!win) return 0;
|
||||
if (!win)
|
||||
return 0;
|
||||
|
||||
result = XGetWindowProperty(server.dsp, win, at, 0, 0x7fffffff, False, type, &type_ret, &format_ret, &nitems_ret, &bafter_ret, &prop_value);
|
||||
result = XGetWindowProperty(server.dsp,
|
||||
win,
|
||||
at,
|
||||
0,
|
||||
0x7fffffff,
|
||||
False,
|
||||
type,
|
||||
&type_ret,
|
||||
&format_ret,
|
||||
&nitems_ret,
|
||||
&bafter_ret,
|
||||
&prop_value);
|
||||
|
||||
if (result == Success && prop_value) {
|
||||
data = ((gulong *)prop_value)[0];
|
||||
@@ -183,7 +192,6 @@ int get_property32 (Window win, Atom at, Atom type)
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void *server_get_property(Window win, Atom at, Atom type, int *num_results)
|
||||
{
|
||||
Atom type_ret;
|
||||
@@ -191,30 +199,40 @@ void *server_get_property (Window win, Atom at, Atom type, int *num_results)
|
||||
unsigned long nitems_ret = 0;
|
||||
unsigned long bafter_ret = 0;
|
||||
unsigned char *prop_value;
|
||||
int result;
|
||||
|
||||
if (!win) return 0;
|
||||
if (!win)
|
||||
return NULL;
|
||||
|
||||
result = XGetWindowProperty(server.dsp, win, at, 0, 0x7fffffff, False, type, &type_ret, &format_ret, &nitems_ret, &bafter_ret, &prop_value);
|
||||
int result = XGetWindowProperty(server.dsp,
|
||||
win,
|
||||
at,
|
||||
0,
|
||||
0x7fffffff,
|
||||
False,
|
||||
type,
|
||||
&type_ret,
|
||||
&format_ret,
|
||||
&nitems_ret,
|
||||
&bafter_ret,
|
||||
&prop_value);
|
||||
|
||||
// Send fill_color resultcount
|
||||
if (num_results) *num_results = (int)nitems_ret;
|
||||
if (num_results)
|
||||
*num_results = (int)nitems_ret;
|
||||
|
||||
if (result == Success && prop_value) return prop_value;
|
||||
else return 0;
|
||||
if (result == Success && prop_value)
|
||||
return prop_value;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void get_root_pixmap()
|
||||
{
|
||||
Pixmap ret = None;
|
||||
|
||||
unsigned long *res;
|
||||
Atom pixmap_atoms[] = {server.atom._XROOTPMAP_ID, server.atom._XROOTMAP_ID};
|
||||
int i;
|
||||
|
||||
for (i=0; i<sizeof(pixmap_atoms)/sizeof(Atom); ++i) {
|
||||
res = server_get_property (server.root_win, pixmap_atoms[i], XA_PIXMAP, 0);
|
||||
for (int i = 0; i < sizeof(pixmap_atoms) / sizeof(Atom); ++i) {
|
||||
unsigned long *res = (unsigned long *)server_get_property(server.root_win, pixmap_atoms[i], XA_PIXMAP, NULL);
|
||||
if (res) {
|
||||
ret = *((Pixmap *)res);
|
||||
XFree(res);
|
||||
@@ -223,9 +241,9 @@ void get_root_pixmap()
|
||||
}
|
||||
server.root_pmap = ret;
|
||||
|
||||
if (server.root_pmap == None)
|
||||
if (server.root_pmap == None) {
|
||||
fprintf(stderr, "tint2 : pixmap background detection failed\n");
|
||||
else {
|
||||
} else {
|
||||
XGCValues gcv;
|
||||
gcv.ts_x_origin = 0;
|
||||
gcv.ts_y_origin = 0;
|
||||
@@ -237,53 +255,46 @@ void get_root_pixmap()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int compareMonitorPos(const void *monitor1, const void *monitor2)
|
||||
int compare_monitor_pos(const void *monitor1, const void *monitor2)
|
||||
{
|
||||
Monitor *m1 = (Monitor*)monitor1;
|
||||
Monitor *m2 = (Monitor*)monitor2;
|
||||
const Monitor *m1 = (const Monitor *)monitor1;
|
||||
const Monitor *m2 = (const Monitor *)monitor2;
|
||||
|
||||
if (m1->x < m2->x) {
|
||||
return -1;
|
||||
}
|
||||
else if (m1->x > m2->x) {
|
||||
} else if (m1->x > m2->x) {
|
||||
return 1;
|
||||
}
|
||||
else if (m1->y < m2->y) {
|
||||
} else if (m1->y < m2->y) {
|
||||
return -1;
|
||||
}
|
||||
else if (m1->y > m2->y) {
|
||||
} else if (m1->y > m2->y) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int compareMonitorIncluded(const void *monitor1, const void *monitor2)
|
||||
int monitor_includes_monitor(const void *monitor1, const void *monitor2)
|
||||
{
|
||||
Monitor *m1 = (Monitor*)monitor1;
|
||||
Monitor *m2 = (Monitor*)monitor2;
|
||||
const Monitor *m1 = (const Monitor *)monitor1;
|
||||
const Monitor *m2 = (const Monitor *)monitor2;
|
||||
|
||||
if (m1->x >= m2->x && m1->y >= m2->y && (m1->x+m1->width) <= (m2->x+m2->width) && (m1->y+m1->height) <= (m2->y+m2->height)) {
|
||||
if (m1->x >= m2->x && m1->y >= m2->y && (m1->x + m1->width) <= (m2->x + m2->width) &&
|
||||
(m1->y + m1->height) <= (m2->y + m2->height)) {
|
||||
// m1 included inside m2
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void get_monitors()
|
||||
{
|
||||
int i, j, nbmonitor;
|
||||
if (XineramaIsActive(server.dsp)) {
|
||||
XineramaScreenInfo *info = XineramaQueryScreens(server.dsp, &nbmonitor);
|
||||
int num_monitors;
|
||||
XineramaScreenInfo *info = XineramaQueryScreens(server.dsp, &num_monitors);
|
||||
XRRScreenResources *res = XRRGetScreenResourcesCurrent(server.dsp, server.root_win);
|
||||
|
||||
if (res && res->ncrtc >= nbmonitor) {
|
||||
if (res && res->ncrtc >= num_monitors) {
|
||||
// use xrandr to identify monitors (does not work with proprietery nvidia drivers)
|
||||
|
||||
// Workaround for issue https://gitlab.com/o9000/tint2/issues/353
|
||||
@@ -299,27 +310,26 @@ void get_monitors()
|
||||
|
||||
printf("xRandr: Found crtc's: %d\n", res->ncrtc);
|
||||
server.monitor = calloc(res->ncrtc, sizeof(Monitor));
|
||||
for (i=0; i<res->ncrtc; ++i) {
|
||||
for (int i = 0; i < res->ncrtc; ++i) {
|
||||
XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(server.dsp, res, res->crtcs[i]);
|
||||
server.monitor[i].x = crtc_info->x;
|
||||
server.monitor[i].y = crtc_info->y;
|
||||
server.monitor[i].width = crtc_info->width;
|
||||
server.monitor[i].height = crtc_info->height;
|
||||
server.monitor[i].names = calloc((crtc_info->noutput + 1), sizeof(gchar *));
|
||||
for (j=0; j<crtc_info->noutput; ++j) {
|
||||
for (int j = 0; j < crtc_info->noutput; ++j) {
|
||||
XRROutputInfo *output_info = XRRGetOutputInfo(server.dsp, res, crtc_info->outputs[j]);
|
||||
printf("xRandr: Linking output %s with crtc %d\n", output_info->name, i);
|
||||
server.monitor[i].names[j] = g_strdup(output_info->name);
|
||||
XRRFreeOutputInfo(output_info);
|
||||
}
|
||||
server.monitor[i].names[j] = 0;
|
||||
server.monitor[i].names[crtc_info->noutput] = NULL;
|
||||
XRRFreeCrtcInfo(crtc_info);
|
||||
}
|
||||
nbmonitor = res->ncrtc;
|
||||
}
|
||||
else if (info && nbmonitor > 0) {
|
||||
server.monitor = calloc(nbmonitor, sizeof(Monitor));
|
||||
for (i=0 ; i < nbmonitor ; i++) {
|
||||
num_monitors = res->ncrtc;
|
||||
} else if (info && num_monitors > 0) {
|
||||
server.monitor = calloc(num_monitors, sizeof(Monitor));
|
||||
for (int i = 0; i < num_monitors; i++) {
|
||||
server.monitor[i].x = info[i].x_org;
|
||||
server.monitor[i].y = info[i].y_org;
|
||||
server.monitor[i].width = info[i].width;
|
||||
@@ -329,33 +339,33 @@ void get_monitors()
|
||||
}
|
||||
|
||||
// ordered monitor
|
||||
qsort(server.monitor, nbmonitor, sizeof(Monitor), compareMonitorIncluded);
|
||||
qsort(server.monitor, num_monitors, sizeof(Monitor), monitor_includes_monitor);
|
||||
|
||||
// remove monitor included into another one
|
||||
i = 0;
|
||||
while (i < nbmonitor) {
|
||||
for (j=0; j < i ; j++) {
|
||||
if (compareMonitorIncluded(&server.monitor[i], &server.monitor[j]) > 0) {
|
||||
int i = 0;
|
||||
while (i < num_monitors) {
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (monitor_includes_monitor(&server.monitor[i], &server.monitor[j]) > 0) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
next:
|
||||
for (j=i; j<nbmonitor; ++j)
|
||||
for (int j = i; j < num_monitors; ++j)
|
||||
if (server.monitor[j].names)
|
||||
g_strfreev(server.monitor[j].names);
|
||||
server.nb_monitor = i;
|
||||
server.monitor = realloc(server.monitor, server.nb_monitor * sizeof(Monitor));
|
||||
qsort(server.monitor, server.nb_monitor, sizeof(Monitor), compareMonitorPos);
|
||||
server.num_monitors = i;
|
||||
server.monitor = realloc(server.monitor, server.num_monitors * sizeof(Monitor));
|
||||
qsort(server.monitor, server.num_monitors, sizeof(Monitor), compare_monitor_pos);
|
||||
|
||||
if (res)
|
||||
XRRFreeScreenResources(res);
|
||||
XFree(info);
|
||||
}
|
||||
|
||||
if (!server.nb_monitor) {
|
||||
server.nb_monitor = 1;
|
||||
if (!server.num_monitors) {
|
||||
server.num_monitors = 1;
|
||||
server.monitor = calloc(1, sizeof(Monitor));
|
||||
server.monitor[0].x = server.monitor[0].y = 0;
|
||||
server.monitor[0].width = DisplayWidth(server.dsp, server.screen);
|
||||
@@ -366,10 +376,10 @@ next:
|
||||
|
||||
void print_monitors()
|
||||
{
|
||||
fprintf(stderr, "Number of monitors: %d\n", server.nb_monitor);
|
||||
int i;
|
||||
for (i = 0; i < server.nb_monitor; i++) {
|
||||
fprintf(stderr, "Monitor %d: x = %d, y = %d, w = %d, h = %d\n",
|
||||
fprintf(stderr, "Number of monitors: %d\n", server.num_monitors);
|
||||
for (int i = 0; i < server.num_monitors; i++) {
|
||||
fprintf(stderr,
|
||||
"Monitor %d: x = %d, y = %d, w = %d, h = %d\n",
|
||||
i + 1,
|
||||
server.monitor[i].x,
|
||||
server.monitor[i].y,
|
||||
@@ -385,35 +395,31 @@ int server_get_number_of_desktops()
|
||||
|
||||
void get_desktops()
|
||||
{
|
||||
int i;
|
||||
|
||||
// detect number of desktops
|
||||
// wait 15s to leave some time for window manager startup
|
||||
for (i=0 ; i < 15 ; i++) {
|
||||
server.nb_desktop = server_get_number_of_desktops();
|
||||
if (server.nb_desktop > 0) break;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
server.num_desktops = server_get_number_of_desktops();
|
||||
if (server.num_desktops > 0)
|
||||
break;
|
||||
sleep(1);
|
||||
}
|
||||
if (server.nb_desktop == 0) {
|
||||
server.nb_desktop = 1;
|
||||
if (server.num_desktops == 0) {
|
||||
server.num_desktops = 1;
|
||||
fprintf(stderr, "warning : WM doesn't respect NETWM specs. tint2 default to 1 desktop.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void server_init_visual()
|
||||
{
|
||||
// inspired by freedesktops fdclock ;)
|
||||
XVisualInfo *xvi;
|
||||
XVisualInfo templ = {.screen = server.screen, .depth = 32, .class = TrueColor};
|
||||
int nvi;
|
||||
xvi = XGetVisualInfo(server.dsp, VisualScreenMask|VisualDepthMask|VisualClassMask, &templ, &nvi);
|
||||
XVisualInfo *xvi = XGetVisualInfo(server.dsp, VisualScreenMask | VisualDepthMask | VisualClassMask, &templ, &nvi);
|
||||
|
||||
Visual *visual = 0;
|
||||
Visual *visual = NULL;
|
||||
if (xvi) {
|
||||
int i;
|
||||
XRenderPictFormat *format;
|
||||
for (i = 0; i < nvi; i++) {
|
||||
for (int i = 0; i < nvi; i++) {
|
||||
format = XRenderFindVisualFormat(server.dsp, xvi[i].visual);
|
||||
if (format->type == PictTypeDirect && format->direct.alphaMask) {
|
||||
visual = xvi[i].visual;
|
||||
@@ -435,7 +441,7 @@ void server_init_visual()
|
||||
server.colormap32 = XCreateColormap(server.dsp, server.root_win, visual, AllocNone);
|
||||
}
|
||||
|
||||
if (!server.disable_transparency && visual && server.composite_manager != None && snapshot_path == 0) {
|
||||
if (!server.disable_transparency && visual && server.composite_manager != None && !snapshot_path) {
|
||||
XSetWindowAttributes attrs;
|
||||
attrs.event_mask = StructureNotifyMask;
|
||||
XChangeWindowAttributes(server.dsp, server.composite_manager, CWEventMask, &attrs);
|
||||
@@ -445,8 +451,7 @@ void server_init_visual()
|
||||
printf("real transparency on... depth: %d\n", server.depth);
|
||||
server.colormap = XCreateColormap(server.dsp, server.root_win, visual, AllocNone);
|
||||
server.visual = visual;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// no composite manager or snapshot mode => fake transparency
|
||||
server.real_transparency = 0;
|
||||
server.depth = DefaultDepth(server.dsp, server.screen);
|
||||
|
||||
18
src/server.h
18
src/server.h
@@ -18,8 +18,7 @@
|
||||
#endif
|
||||
#include <glib.h>
|
||||
|
||||
typedef struct Global_atom
|
||||
{
|
||||
typedef struct Global_atom {
|
||||
Atom _XROOTPMAP_ID;
|
||||
Atom _XROOTMAP_ID;
|
||||
Atom _NET_CURRENT_DESKTOP;
|
||||
@@ -91,10 +90,7 @@ typedef struct Global_atom
|
||||
Atom TARGETS;
|
||||
} Global_atom;
|
||||
|
||||
|
||||
|
||||
typedef struct Monitor
|
||||
{
|
||||
typedef struct Monitor {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
@@ -102,9 +98,7 @@ typedef struct Monitor
|
||||
gchar **names;
|
||||
} Monitor;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
Display *dsp;
|
||||
Window root_win;
|
||||
Window composite_manager;
|
||||
@@ -114,9 +108,9 @@ typedef struct
|
||||
int desktop;
|
||||
int screen;
|
||||
int depth;
|
||||
int nb_desktop;
|
||||
int num_desktops;
|
||||
// number of monitor (without monitor included into another one)
|
||||
int nb_monitor;
|
||||
int num_monitors;
|
||||
Monitor *monitor;
|
||||
int got_root_win;
|
||||
Visual *visual;
|
||||
@@ -133,10 +127,8 @@ typedef struct
|
||||
#endif // HAVE_SN
|
||||
} Server_global;
|
||||
|
||||
|
||||
extern Server_global server;
|
||||
|
||||
|
||||
// freed memory
|
||||
void cleanup_server();
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
|
||||
#include "systraybar.h"
|
||||
#include "server.h"
|
||||
#include "panel.h"
|
||||
@@ -85,7 +84,7 @@ void cleanup_systray()
|
||||
systray_enabled = 0;
|
||||
systray_max_icon_size = 0;
|
||||
systray_monitor = 0;
|
||||
systray.area.on_screen = 0;
|
||||
systray.area.on_screen = FALSE;
|
||||
free_area(&systray.area);
|
||||
if (render_background) {
|
||||
XFreePixmap(server.dsp, render_background);
|
||||
@@ -108,7 +107,6 @@ void init_systray()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void init_systray_panel(void *p)
|
||||
{
|
||||
Panel *panel = (Panel *)p;
|
||||
@@ -118,13 +116,12 @@ void init_systray_panel(void *p)
|
||||
systray.area.bg = &g_array_index(backgrounds, Background, 0);
|
||||
show(&systray.area);
|
||||
systray.area.resize_needed = 1;
|
||||
systray.area.redraw_needed = 1;
|
||||
systray.area.redraw_needed = TRUE;
|
||||
panel->area.resize_needed = 1;
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
refresh_systray = 1;
|
||||
}
|
||||
|
||||
|
||||
void draw_systray(void *obj, cairo_t *c)
|
||||
{
|
||||
if (systray_profile)
|
||||
@@ -132,15 +129,24 @@ void draw_systray(void *obj, cairo_t *c)
|
||||
if (systray_composited) {
|
||||
if (render_background)
|
||||
XFreePixmap(server.dsp, render_background);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
refresh_systray = 1;
|
||||
}
|
||||
|
||||
|
||||
int resize_systray(void *obj)
|
||||
gboolean resize_systray(void *obj)
|
||||
{
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d\n", profiling_get_time(), __FUNCTION__, __LINE__);
|
||||
@@ -158,7 +164,14 @@ int resize_systray(void *obj)
|
||||
|
||||
if (systray.icon_size > 0) {
|
||||
long icon_size = systray.icon_size;
|
||||
XChangeProperty(server.dsp, net_sel_win, server.atom._NET_SYSTEM_TRAY_ICON_SIZE, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &icon_size, 1);
|
||||
XChangeProperty(server.dsp,
|
||||
net_sel_win,
|
||||
server.atom._NET_SYSTEM_TRAY_ICON_SIZE,
|
||||
XA_CARDINAL,
|
||||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)&icon_size,
|
||||
1);
|
||||
}
|
||||
|
||||
count = 0;
|
||||
@@ -174,16 +187,22 @@ int resize_systray(void *obj)
|
||||
int height = sysbar->area.height - 2 * sysbar->area.bg->border.width - 2 * sysbar->area.paddingy;
|
||||
// here icons_per_column always higher than 0
|
||||
sysbar->icons_per_column = (height + sysbar->area.paddingx) / (sysbar->icon_size + sysbar->area.paddingx);
|
||||
sysbar->marging = height - (sysbar->icons_per_column-1)*(sysbar->icon_size+sysbar->area.paddingx) - sysbar->icon_size;
|
||||
sysbar->margin =
|
||||
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);
|
||||
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 {
|
||||
int width = sysbar->area.width - 2 * sysbar->area.bg->border.width - 2 * sysbar->area.paddingy;
|
||||
// here icons_per_row always higher than 0
|
||||
sysbar->icons_per_row = (width + sysbar->area.paddingx) / (sysbar->icon_size + sysbar->area.paddingx);
|
||||
sysbar->marging = width - (sysbar->icons_per_row-1)*(sysbar->icon_size+sysbar->area.paddingx) - sysbar->icon_size;
|
||||
sysbar->margin =
|
||||
width - (sysbar->icons_per_row - 1) * (sysbar->icon_size + sysbar->area.paddingx) - sysbar->icon_size;
|
||||
sysbar->icons_per_column = count / sysbar->icons_per_row + (count % sysbar->icons_per_row != 0);
|
||||
systray.area.height = (2 * systray.area.bg->border.width) + (2 * systray.area.paddingxlr) + (sysbar->icon_size * sysbar->icons_per_column) + ((sysbar->icons_per_column-1) * systray.area.paddingx);
|
||||
systray.area.height = (2 * systray.area.bg->border.width) + (2 * systray.area.paddingxlr) +
|
||||
(sysbar->icon_size * sysbar->icons_per_column) +
|
||||
((sysbar->icons_per_column - 1) * systray.area.paddingx);
|
||||
}
|
||||
|
||||
if (net_sel_win == None) {
|
||||
@@ -193,7 +212,6 @@ int resize_systray(void *obj)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void on_change_systray(void *obj)
|
||||
{
|
||||
if (systray_profile)
|
||||
@@ -205,7 +223,8 @@ void on_change_systray (void *obj)
|
||||
|
||||
Panel *panel = sysbar->area.panel;
|
||||
int i, posx, posy;
|
||||
int start = panel->area.bg->border.width + panel->area.paddingy + systray.area.bg->border.width + systray.area.paddingy + sysbar->marging/2;
|
||||
int start = panel->area.bg->border.width + panel->area.paddingy + systray.area.bg->border.width +
|
||||
systray.area.paddingy + sysbar->margin / 2;
|
||||
if (panel_horizontal) {
|
||||
posy = start;
|
||||
posx = systray.area.posx + systray.area.bg->border.width + systray.area.paddingxlr;
|
||||
@@ -224,7 +243,15 @@ void on_change_systray (void *obj)
|
||||
traywin->y = posy;
|
||||
traywin->x = posx;
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "%s:%d win = %lu (%s), parent = %lu, x = %d, y = %d\n", __FUNCTION__, __LINE__, traywin->win, traywin->name, traywin->parent, posx, posy);
|
||||
fprintf(stderr,
|
||||
"%s:%d win = %lu (%s), parent = %lu, x = %d, y = %d\n",
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name,
|
||||
traywin->parent,
|
||||
posx,
|
||||
posy);
|
||||
traywin->width = sysbar->icon_size;
|
||||
traywin->height = sysbar->icon_size;
|
||||
if (panel_horizontal) {
|
||||
@@ -253,7 +280,14 @@ void on_change_systray (void *obj)
|
||||
}
|
||||
if (width != traywin->width || height != traywin->height || xpos != traywin->x || ypos != traywin->y) {
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "XMoveResizeWindow(server.dsp, traywin->parent = %ld, traywin->x = %d, traywin->y = %d, traywin->width = %d, traywin->height = %d)\n", traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height);
|
||||
fprintf(stderr,
|
||||
"XMoveResizeWindow(server.dsp, traywin->parent = %ld, traywin->x = %d, traywin->y = %d, "
|
||||
"traywin->width = %d, traywin->height = %d)\n",
|
||||
traywin->parent,
|
||||
traywin->x,
|
||||
traywin->y,
|
||||
traywin->width,
|
||||
traywin->height);
|
||||
XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height);
|
||||
}
|
||||
if (!traywin->reparented)
|
||||
@@ -262,7 +296,6 @@ void on_change_systray (void *obj)
|
||||
refresh_systray = 1;
|
||||
}
|
||||
|
||||
|
||||
// ***********************************************
|
||||
// systray protocol
|
||||
|
||||
@@ -293,7 +326,18 @@ void start_net()
|
||||
int pid;
|
||||
|
||||
_NET_WM_PID = XInternAtom(server.dsp, "_NET_WM_PID", True);
|
||||
int ret = XGetWindowProperty(server.dsp, win, _NET_WM_PID, 0, 1024, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop);
|
||||
int ret = XGetWindowProperty(server.dsp,
|
||||
win,
|
||||
_NET_WM_PID,
|
||||
0,
|
||||
1024,
|
||||
False,
|
||||
AnyPropertyType,
|
||||
&actual_type,
|
||||
&actual_format,
|
||||
&nitems,
|
||||
&bytes_after,
|
||||
&prop);
|
||||
|
||||
fprintf(stderr, RED "tint2 : another systray is running" RESET);
|
||||
if (ret == Success && prop) {
|
||||
@@ -312,20 +356,48 @@ void start_net()
|
||||
// v0.3 trayer specification. tint2 always horizontal.
|
||||
// Vertical panel will draw the systray horizontal.
|
||||
long orientation = 0;
|
||||
XChangeProperty(server.dsp, net_sel_win, server.atom._NET_SYSTEM_TRAY_ORIENTATION, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &orientation, 1);
|
||||
XChangeProperty(server.dsp,
|
||||
net_sel_win,
|
||||
server.atom._NET_SYSTEM_TRAY_ORIENTATION,
|
||||
XA_CARDINAL,
|
||||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)&orientation,
|
||||
1);
|
||||
if (systray.icon_size > 0) {
|
||||
long icon_size = systray.icon_size;
|
||||
XChangeProperty(server.dsp, net_sel_win, server.atom._NET_SYSTEM_TRAY_ICON_SIZE, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &icon_size, 1);
|
||||
XChangeProperty(server.dsp,
|
||||
net_sel_win,
|
||||
server.atom._NET_SYSTEM_TRAY_ICON_SIZE,
|
||||
XA_CARDINAL,
|
||||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)&icon_size,
|
||||
1);
|
||||
}
|
||||
long padding = 0;
|
||||
XChangeProperty(server.dsp, net_sel_win, server.atom._NET_SYSTEM_TRAY_PADDING, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &padding, 1);
|
||||
XChangeProperty(server.dsp,
|
||||
net_sel_win,
|
||||
server.atom._NET_SYSTEM_TRAY_PADDING,
|
||||
XA_CARDINAL,
|
||||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)&padding,
|
||||
1);
|
||||
|
||||
VisualID vid;
|
||||
if (systray_composited)
|
||||
vid = XVisualIDFromVisual(server.visual32);
|
||||
else
|
||||
vid = XVisualIDFromVisual(server.visual);
|
||||
XChangeProperty(server.dsp, net_sel_win, XInternAtom(server.dsp, "_NET_SYSTEM_TRAY_VISUAL", False), XA_VISUALID, 32, PropModeReplace, (unsigned char*)&vid, 1);
|
||||
XChangeProperty(server.dsp,
|
||||
net_sel_win,
|
||||
XInternAtom(server.dsp, "_NET_SYSTEM_TRAY_VISUAL", False),
|
||||
XA_VISUALID,
|
||||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)&vid,
|
||||
1);
|
||||
|
||||
XSetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN, net_sel_win, CurrentTime);
|
||||
if (XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN) != net_sel_win) {
|
||||
@@ -350,7 +422,6 @@ void start_net()
|
||||
XSendEvent(server.dsp, server.root_win, False, StructureNotifyMask, (XEvent *)&ev);
|
||||
}
|
||||
|
||||
|
||||
void net_message(XClientMessageEvent *e)
|
||||
{
|
||||
if (systray_profile)
|
||||
@@ -380,7 +451,6 @@ void net_message(XClientMessageEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stop_net()
|
||||
{
|
||||
if (systray_profile)
|
||||
@@ -400,7 +470,6 @@ void stop_net()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gboolean error;
|
||||
int window_error_handler(Display *d, XErrorEvent *e)
|
||||
{
|
||||
@@ -413,11 +482,10 @@ int window_error_handler(Display *d, XErrorEvent *e)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gint compare_traywindows(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const TrayWindow * traywin_a = (TrayWindow*)a;
|
||||
const TrayWindow * traywin_b = (TrayWindow*)b;
|
||||
const TrayWindow *traywin_a = (const TrayWindow *)a;
|
||||
const TrayWindow *traywin_b = (const TrayWindow *)b;
|
||||
|
||||
#if 0
|
||||
// This breaks pygtk2 StatusIcon with blinking activated
|
||||
@@ -427,22 +495,18 @@ static gint compare_traywindows(gconstpointer a, gconstpointer b)
|
||||
return -1 * (systray.sort == SYSTRAY_SORT_RIGHT2LEFT ? -1 : 1);
|
||||
#endif
|
||||
|
||||
if (systray.sort == SYSTRAY_SORT_ASCENDING ||
|
||||
systray.sort == SYSTRAY_SORT_DESCENDING) {
|
||||
if (systray.sort == SYSTRAY_SORT_ASCENDING || systray.sort == SYSTRAY_SORT_DESCENDING) {
|
||||
return g_ascii_strncasecmp(traywin_a->name, traywin_b->name, -1) *
|
||||
(systray.sort == SYSTRAY_SORT_ASCENDING ? 1 : -1);
|
||||
}
|
||||
|
||||
if (systray.sort == SYSTRAY_SORT_LEFT2RIGHT ||
|
||||
systray.sort == SYSTRAY_SORT_RIGHT2LEFT) {
|
||||
return (traywin_a->chrono - traywin_b->chrono) *
|
||||
(systray.sort == SYSTRAY_SORT_LEFT2RIGHT ? 1 : -1);
|
||||
if (systray.sort == SYSTRAY_SORT_LEFT2RIGHT || systray.sort == SYSTRAY_SORT_RIGHT2LEFT) {
|
||||
return (traywin_a->chrono - traywin_b->chrono) * (systray.sort == SYSTRAY_SORT_LEFT2RIGHT ? 1 : -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
gboolean add_icon(Window win)
|
||||
{
|
||||
XTextProperty xname;
|
||||
@@ -467,7 +531,18 @@ gboolean add_icon(Window win)
|
||||
unsigned long nitems;
|
||||
unsigned long bytes_after;
|
||||
unsigned char *prop = 0;
|
||||
int ret = XGetWindowProperty(server.dsp, win, 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) {
|
||||
pid = prop[1] * 256;
|
||||
pid += prop[0];
|
||||
@@ -492,7 +567,8 @@ gboolean add_icon(Window win)
|
||||
Imlib_Image image = imlib_create_image_from_drawable(0, 0, 0, other->width, other->height, 1);
|
||||
if (image) {
|
||||
imlib_context_set_drawable(panel->temp_pmap);
|
||||
Imlib_Image bg = imlib_create_image_from_drawable(0, other->x, other->y, other->width, other->height, 1);
|
||||
Imlib_Image bg =
|
||||
imlib_create_image_from_drawable(0, other->x, other->y, other->width, other->height, 1);
|
||||
imlib_context_set_image(bg);
|
||||
DATA32 *data_bg = imlib_image_get_data_for_reading_only();
|
||||
imlib_context_set_image(image);
|
||||
@@ -522,7 +598,14 @@ gboolean add_icon(Window win)
|
||||
imlib_context_set_image(bg);
|
||||
imlib_free_image_and_decache();
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s) empty = %d\n", profiling_get_time(), __FUNCTION__, __LINE__, other->win, other->name, other->empty);
|
||||
fprintf(stderr,
|
||||
"[%f] %s:%d win = %lu (%s) empty = %d\n",
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
other->win,
|
||||
other->name,
|
||||
other->empty);
|
||||
}
|
||||
}
|
||||
if (pid && other->pid == pid) {
|
||||
@@ -537,7 +620,12 @@ gboolean add_icon(Window win)
|
||||
for (l = systray.list_icons; l; l = l->next) {
|
||||
if (pid && ((TrayWindow *)l->data)->pid == pid && ((TrayWindow *)l->data)->empty) {
|
||||
num_empty_same_pid++;
|
||||
fprintf(stderr, RED "Removing tray icon %lu (%s) from misbehaving application with pid=%d (too many icons)\n" RESET, ((TrayWindow*)l->data)->win, ((TrayWindow*)l->data)->name, pid);
|
||||
fprintf(stderr,
|
||||
RED
|
||||
"Removing tray icon %lu (%s) from misbehaving application with pid=%d (too many icons)\n" RESET,
|
||||
((TrayWindow *)l->data)->win,
|
||||
((TrayWindow *)l->data)->name,
|
||||
pid);
|
||||
remove_icon((TrayWindow *)l->data);
|
||||
break;
|
||||
}
|
||||
@@ -555,8 +643,17 @@ gboolean add_icon(Window win)
|
||||
unsigned long mask = 0;
|
||||
XSetWindowAttributes set_attr;
|
||||
Visual *visual = server.visual;
|
||||
fprintf(stderr, GREEN "add_icon: %lu (%s), pid %d, %d, visual %p, colormap %lu, depth %d, width %d, height %d\n" RESET,
|
||||
win, name, pid, num_empty_same_pid, attr.visual, attr.colormap, attr.depth, attr.width, attr.height);
|
||||
fprintf(stderr,
|
||||
GREEN "add_icon: %lu (%s), pid %d, %d, visual %p, colormap %lu, depth %d, width %d, height %d\n" RESET,
|
||||
win,
|
||||
name,
|
||||
pid,
|
||||
num_empty_same_pid,
|
||||
attr.visual,
|
||||
attr.colormap,
|
||||
attr.depth,
|
||||
attr.width,
|
||||
attr.height);
|
||||
if (server.disable_transparency) {
|
||||
set_attr.background_pixmap = ParentRelative;
|
||||
mask = CWBackPixmap;
|
||||
@@ -579,7 +676,18 @@ gboolean add_icon(Window win)
|
||||
}
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "XCreateWindow(...)\n");
|
||||
Window parent = XCreateWindow(server.dsp, panel->main_win, 0, 0, systray.icon_size, systray.icon_size, 0, attr.depth, InputOutput, visual, mask, &set_attr);
|
||||
Window parent = XCreateWindow(server.dsp,
|
||||
panel->main_win,
|
||||
0,
|
||||
0,
|
||||
systray.icon_size,
|
||||
systray.icon_size,
|
||||
0,
|
||||
attr.depth,
|
||||
InputOutput,
|
||||
visual,
|
||||
mask,
|
||||
&set_attr);
|
||||
|
||||
// Add the icon to the list
|
||||
TrayWindow *traywin = g_new0(TrayWindow, 1);
|
||||
@@ -616,9 +724,9 @@ gboolean add_icon(Window win)
|
||||
if (systray_profile)
|
||||
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__);
|
||||
systray.area.resize_needed = 1;
|
||||
systray.area.redraw_needed = 1;
|
||||
systray.area.redraw_needed = TRUE;
|
||||
panel->area.resize_needed = 1;
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
refresh_systray = 1;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -626,7 +734,13 @@ gboolean add_icon(Window win)
|
||||
gboolean reparent_icon(TrayWindow *traywin)
|
||||
{
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
"[%f] %s:%d win = %lu (%s)\n",
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
if (traywin->reparented)
|
||||
return TRUE;
|
||||
|
||||
@@ -641,7 +755,11 @@ gboolean reparent_icon(TrayWindow *traywin)
|
||||
XReparentWindow(server.dsp, traywin->win, traywin->parent, 0, 0);
|
||||
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "XMoveResizeWindow(server.dsp, traywin->win = %ld, 0, 0, traywin->width = %d, traywin->height = %d)\n", traywin->win, traywin->width, traywin->height);
|
||||
fprintf(stderr,
|
||||
"XMoveResizeWindow(server.dsp, traywin->win = %ld, 0, 0, traywin->width = %d, traywin->height = %d)\n",
|
||||
traywin->win,
|
||||
traywin->width,
|
||||
traywin->height);
|
||||
XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
|
||||
|
||||
// Embed into parent
|
||||
@@ -666,7 +784,13 @@ gboolean reparent_icon(TrayWindow *traywin)
|
||||
XSync(server.dsp, False);
|
||||
XSetErrorHandler(old);
|
||||
if (error != FALSE) {
|
||||
fprintf(stderr, RED "systray %d: cannot embed icon for window %lu (%s) parent %lu pid %d\n" RESET, __LINE__, traywin->win, traywin->name, traywin->parent, traywin->pid);
|
||||
fprintf(stderr,
|
||||
RED "systray %d: cannot embed icon for window %lu (%s) parent %lu pid %d\n" RESET,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name,
|
||||
traywin->parent,
|
||||
traywin->pid);
|
||||
remove_icon(traywin);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -674,7 +798,13 @@ gboolean reparent_icon(TrayWindow *traywin)
|
||||
traywin->reparented = 1;
|
||||
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
"[%f] %s:%d win = %lu (%s)\n",
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -682,7 +812,13 @@ gboolean reparent_icon(TrayWindow *traywin)
|
||||
gboolean embed_icon(TrayWindow *traywin)
|
||||
{
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
"[%f] %s:%d win = %lu (%s)\n",
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
if (traywin->embedded)
|
||||
return TRUE;
|
||||
|
||||
@@ -700,18 +836,32 @@ gboolean embed_icon(TrayWindow *traywin)
|
||||
int ret;
|
||||
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "XGetWindowProperty(server.dsp, traywin->win, server.atom._XEMBED_INFO, 0, 2, False, server.atom._XEMBED_INFO, &acttype, &actfmt, &nbitem, &bytes, &data)\n");
|
||||
ret = XGetWindowProperty(server.dsp, traywin->win, server.atom._XEMBED_INFO, 0, 2, False, server.atom._XEMBED_INFO, &acttype, &actfmt, &nbitem, &bytes, (unsigned char**)&data);
|
||||
fprintf(stderr, "XGetWindowProperty(server.dsp, traywin->win, server.atom._XEMBED_INFO, 0, 2, False, "
|
||||
"server.atom._XEMBED_INFO, &acttype, &actfmt, &nbitem, &bytes, &data)\n");
|
||||
ret = XGetWindowProperty(server.dsp,
|
||||
traywin->win,
|
||||
server.atom._XEMBED_INFO,
|
||||
0,
|
||||
2,
|
||||
False,
|
||||
server.atom._XEMBED_INFO,
|
||||
&acttype,
|
||||
&actfmt,
|
||||
&nbitem,
|
||||
&bytes,
|
||||
(unsigned char **)&data);
|
||||
if (ret == Success) {
|
||||
if (data) {
|
||||
if (nbitem >= 2) {
|
||||
int hide = ((data[1] & XEMBED_MAPPED) == 0);
|
||||
if (hide) {
|
||||
// In theory we have to check the embedding with this and remove icons that refuse embedding.
|
||||
// In practice we have no idea when the other application processes the event and accepts the embed
|
||||
// In practice we have no idea when the other application processes the event and accepts the
|
||||
// embed
|
||||
// so we cannot check now without a race.
|
||||
// Race can be triggered with PyGtk(2) apps.
|
||||
// We could defer this for later (if we set PropertyChangeMask in XSelectInput we get notified) but
|
||||
// We could defer this for later (if we set PropertyChangeMask in XSelectInput we get notified)
|
||||
// but
|
||||
// for some reason it breaks transparency for Qt icons. So we don't.
|
||||
// fprintf(stderr, RED "tint2: window refused embedding\n" RESET);
|
||||
// remove_icon(traywin);
|
||||
@@ -757,7 +907,13 @@ gboolean embed_icon(TrayWindow *traywin)
|
||||
XSync(server.dsp, False);
|
||||
XSetErrorHandler(old);
|
||||
if (error != FALSE) {
|
||||
fprintf(stderr, RED "systray %d: cannot embed icon for window %lu (%s) parent %lu pid %d\n" RESET, __LINE__, traywin->win, traywin->name, traywin->parent, traywin->pid);
|
||||
fprintf(stderr,
|
||||
RED "systray %d: cannot embed icon for window %lu (%s) parent %lu pid %d\n" RESET,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name,
|
||||
traywin->parent,
|
||||
traywin->pid);
|
||||
remove_icon(traywin);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -765,7 +921,13 @@ gboolean embed_icon(TrayWindow *traywin)
|
||||
traywin->embedded = 1;
|
||||
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
"[%f] %s:%d win = %lu (%s)\n",
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -773,7 +935,13 @@ gboolean embed_icon(TrayWindow *traywin)
|
||||
void remove_icon(TrayWindow *traywin)
|
||||
{
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
"[%f] %s:%d win = %lu (%s)\n",
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
Panel *panel = systray.area.panel;
|
||||
|
||||
// remove from our list
|
||||
@@ -818,9 +986,9 @@ void remove_icon(TrayWindow *traywin)
|
||||
if (systray_profile)
|
||||
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__);
|
||||
systray.area.resize_needed = 1;
|
||||
systray.area.redraw_needed = 1;
|
||||
systray.area.redraw_needed = TRUE;
|
||||
panel->area.resize_needed = 1;
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
refresh_systray = 1;
|
||||
}
|
||||
|
||||
@@ -839,7 +1007,12 @@ void systray_resize_icon(void* t)
|
||||
} else {
|
||||
if (1 || xpos != 0 || ypos != 0 || width != traywin->width || height != traywin->height) {
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "XMoveResizeWindow(server.dsp, traywin->win = %ld, 0, 0, traywin->width = %d, traywin->height = %d)\n", traywin->win, traywin->width, traywin->height);
|
||||
fprintf(stderr,
|
||||
"XMoveResizeWindow(server.dsp, traywin->win = %ld, 0, 0, traywin->width = %d, traywin->height "
|
||||
"= %d)\n",
|
||||
traywin->win,
|
||||
traywin->width,
|
||||
traywin->height);
|
||||
if (0) {
|
||||
XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
|
||||
}
|
||||
@@ -874,13 +1047,20 @@ void systray_resize_icon(void* t)
|
||||
void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
|
||||
{
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "XConfigure event: win = %lu (%s), x = %d, y = %d, w = %d, h = %d\n",
|
||||
traywin->win, traywin->name, e->xconfigure.x, e->xconfigure.y, e->xconfigure.width, e->xconfigure.height);
|
||||
fprintf(stderr,
|
||||
"XConfigure event: win = %lu (%s), x = %d, y = %d, w = %d, h = %d\n",
|
||||
traywin->win,
|
||||
traywin->name,
|
||||
e->xconfigure.x,
|
||||
e->xconfigure.y,
|
||||
e->xconfigure.width,
|
||||
e->xconfigure.height);
|
||||
|
||||
if (!traywin->reparented)
|
||||
return;
|
||||
|
||||
if (e->xconfigure.width != traywin->width || e->xconfigure.height != traywin->height || e->xconfigure.x != 0 || e->xconfigure.y != 0) {
|
||||
if (e->xconfigure.width != traywin->width || e->xconfigure.height != traywin->height || e->xconfigure.x != 0 ||
|
||||
e->xconfigure.y != 0) {
|
||||
if (traywin->bad_size_counter < max_bad_resize_events) {
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
@@ -898,18 +1078,24 @@ void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
|
||||
systray_resize_icon(traywin);
|
||||
} else {
|
||||
if (!traywin->resize_timeout)
|
||||
traywin->resize_timeout = add_timeout(fast_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
||||
traywin->resize_timeout =
|
||||
add_timeout(fast_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
||||
}
|
||||
} else {
|
||||
if (traywin->bad_size_counter == max_bad_resize_events) {
|
||||
traywin->bad_size_counter++;
|
||||
fprintf(stderr, RED "Detected resize loop for tray icon %lu (%s), throttling resize events\n" RESET, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
RED "Detected resize loop for tray icon %lu (%s), throttling resize events\n" RESET,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
}
|
||||
// Delayed resize
|
||||
// FIXME Normally we should force the icon to resize fill_color to the size we resized it to when we embedded it.
|
||||
// FIXME Normally we should force the icon to resize fill_color to the size we resized it to when we
|
||||
// embedded it.
|
||||
// However this triggers a resize loop in new versions of GTK, which we must avoid.
|
||||
if (!traywin->resize_timeout)
|
||||
traywin->resize_timeout = add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
||||
traywin->resize_timeout =
|
||||
add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -920,15 +1106,19 @@ void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
|
||||
// Resize and redraw the systray
|
||||
if (systray_profile)
|
||||
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__);
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
refresh_systray = 1;
|
||||
}
|
||||
|
||||
void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
|
||||
{
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "XResizeRequest event: win = %lu (%s), w = %d, h = %d\n",
|
||||
traywin->win, traywin->name, e->xresizerequest.width, e->xresizerequest.height);
|
||||
fprintf(stderr,
|
||||
"XResizeRequest event: win = %lu (%s), w = %d, h = %d\n",
|
||||
traywin->win,
|
||||
traywin->name,
|
||||
e->xresizerequest.width,
|
||||
e->xresizerequest.height);
|
||||
|
||||
if (!traywin->reparented)
|
||||
return;
|
||||
@@ -951,18 +1141,24 @@ void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
|
||||
systray_resize_icon(traywin);
|
||||
} else {
|
||||
if (!traywin->resize_timeout)
|
||||
traywin->resize_timeout = add_timeout(fast_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
||||
traywin->resize_timeout =
|
||||
add_timeout(fast_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
||||
}
|
||||
} else {
|
||||
if (traywin->bad_size_counter == max_bad_resize_events) {
|
||||
traywin->bad_size_counter++;
|
||||
fprintf(stderr, RED "Detected resize loop for tray icon %lu (%s), throttling resize events\n" RESET, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
RED "Detected resize loop for tray icon %lu (%s), throttling resize events\n" RESET,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
}
|
||||
// Delayed resize
|
||||
// FIXME Normally we should force the icon to resize fill_color to the size we resized it to when we embedded it.
|
||||
// FIXME Normally we should force the icon to resize fill_color to the size we resized it to when we
|
||||
// embedded it.
|
||||
// However this triggers a resize loop in new versions of GTK, which we must avoid.
|
||||
if (!traywin->resize_timeout)
|
||||
traywin->resize_timeout = add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
||||
traywin->resize_timeout =
|
||||
add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -973,27 +1169,50 @@ void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
|
||||
// Resize and redraw the systray
|
||||
if (systray_profile)
|
||||
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__);
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
refresh_systray = 1;
|
||||
}
|
||||
|
||||
void systray_destroy_event(TrayWindow *traywin)
|
||||
{
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
"[%f] %s:%d win = %lu (%s)\n",
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
remove_icon(traywin);
|
||||
}
|
||||
|
||||
|
||||
void systray_render_icon_from_image(TrayWindow *traywin)
|
||||
{
|
||||
Panel *panel = systray.area.panel;
|
||||
if (!traywin->image)
|
||||
return;
|
||||
imlib_context_set_image(traywin->image);
|
||||
XCopyArea(server.dsp, render_background, systray.area.pix, server.gc, traywin->x-systray.area.posx, traywin->y-systray.area.posy, traywin->width, traywin->height, traywin->x-systray.area.posx, traywin->y-systray.area.posy);
|
||||
XCopyArea(server.dsp,
|
||||
render_background,
|
||||
systray.area.pix,
|
||||
server.gc,
|
||||
traywin->x - systray.area.posx,
|
||||
traywin->y - systray.area.posy,
|
||||
traywin->width,
|
||||
traywin->height,
|
||||
traywin->x - systray.area.posx,
|
||||
traywin->y - systray.area.posy);
|
||||
render_image(systray.area.pix, traywin->x - systray.area.posx, traywin->y - systray.area.posy);
|
||||
XCopyArea(server.dsp, systray.area.pix, panel->temp_pmap, server.gc, traywin->x-systray.area.posx, traywin->y-systray.area.posy, traywin->width, traywin->height, traywin->x, traywin->y);
|
||||
XCopyArea(server.dsp,
|
||||
systray.area.pix,
|
||||
panel->temp_pmap,
|
||||
server.gc,
|
||||
traywin->x - systray.area.posx,
|
||||
traywin->y - systray.area.posy,
|
||||
traywin->width,
|
||||
traywin->height,
|
||||
traywin->x,
|
||||
traywin->y);
|
||||
}
|
||||
|
||||
void systray_render_icon_composited(void *t)
|
||||
@@ -1003,7 +1222,13 @@ void systray_render_icon_composited(void* t)
|
||||
TrayWindow *traywin = t;
|
||||
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
"[%f] %s:%d win = %lu (%s)\n",
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
|
||||
// wine tray icons update whenever mouse is over them, so we limit the updates to 50 ms
|
||||
struct timespec now;
|
||||
@@ -1012,9 +1237,16 @@ void systray_render_icon_composited(void* t)
|
||||
if (compare_timespecs(&earliest_render, &now) > 0) {
|
||||
traywin->num_fast_renders++;
|
||||
if (traywin->num_fast_renders > max_fast_refreshes) {
|
||||
traywin->render_timeout = add_timeout(min_refresh_period, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
||||
traywin->render_timeout =
|
||||
add_timeout(min_refresh_period, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
||||
if (systray_profile)
|
||||
fprintf(stderr, YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering\n" RESET,
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -1025,9 +1257,16 @@ void systray_render_icon_composited(void* t)
|
||||
|
||||
if (traywin->width == 0 || traywin->height == 0) {
|
||||
// reschedule rendering since the geometry information has not yet been processed (can happen on slow cpu)
|
||||
traywin->render_timeout = add_timeout(min_refresh_period, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
||||
traywin->render_timeout =
|
||||
add_timeout(min_refresh_period, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
||||
if (systray_profile)
|
||||
fprintf(stderr, YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering\n" RESET,
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1077,14 +1316,27 @@ void systray_render_icon_composited(void* t)
|
||||
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_drawable);
|
||||
// end of the ugly hack and we can continue as before
|
||||
@@ -1115,12 +1367,17 @@ void systray_render_icon_composited(void* t)
|
||||
imlib_image_set_has_alpha(1);
|
||||
DATA32 *data = imlib_image_get_data();
|
||||
if (traywin->depth == 24) {
|
||||
createHeuristicMask(data, traywin->width, traywin->height);
|
||||
create_heuristic_mask(data, traywin->width, traywin->height);
|
||||
}
|
||||
|
||||
int empty = imageEmpty(data, traywin->width, traywin->height);
|
||||
int empty = image_empty(data, traywin->width, traywin->height);
|
||||
if (systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0)
|
||||
adjust_asb(data, traywin->width, traywin->height, systray.alpha, (float)systray.saturation/100, (float)systray.brightness/100);
|
||||
adjust_asb(data,
|
||||
traywin->width,
|
||||
traywin->height,
|
||||
systray.alpha,
|
||||
(float)systray.saturation / 100,
|
||||
(float)systray.brightness / 100);
|
||||
imlib_image_put_back_data(data);
|
||||
|
||||
systray_render_icon_from_image(traywin);
|
||||
@@ -1138,44 +1395,76 @@ void systray_render_icon_composited(void* t)
|
||||
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
|
||||
// Resize and redraw the systray
|
||||
if (systray_profile)
|
||||
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__);
|
||||
fprintf(stderr,
|
||||
BLUE "[%f] %s:%d trigger resize & redraw\n" RESET,
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__);
|
||||
systray.area.resize_needed = 1;
|
||||
systray.area.redraw_needed = 1;
|
||||
systray.area.redraw_needed = TRUE;
|
||||
panel->area.resize_needed = 1;
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
refresh_systray = 1;
|
||||
}
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
"[%f] %s:%d win = %lu (%s)\n",
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
|
||||
return;
|
||||
|
||||
on_error:
|
||||
fprintf(stderr, RED "systray %d: rendering error for icon %lu (%s) pid %d\n" RESET, __LINE__, traywin->win, traywin->name, traywin->pid);
|
||||
fprintf(stderr,
|
||||
RED "systray %d: rendering error for icon %lu (%s) pid %d\n" RESET,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name,
|
||||
traywin->pid);
|
||||
return;
|
||||
|
||||
on_systray_error:
|
||||
fprintf(stderr, RED "systray %d: rendering error for icon %lu (%s) pid %d. "
|
||||
"Disabling compositing and restarting systray...\n" RESET, __LINE__, traywin->win, traywin->name, traywin->pid);
|
||||
fprintf(stderr,
|
||||
RED "systray %d: rendering error for icon %lu (%s) pid %d. "
|
||||
"Disabling compositing and restarting systray...\n" RESET,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name,
|
||||
traywin->pid);
|
||||
systray_composited = 0;
|
||||
stop_net();
|
||||
start_net();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void systray_render_icon(void *t)
|
||||
{
|
||||
TrayWindow *traywin = t;
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
"[%f] %s:%d win = %lu (%s)\n",
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
if (!traywin->reparented || !traywin->embedded) {
|
||||
if (systray_profile)
|
||||
fprintf(stderr, YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering\n" RESET,
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
stop_timeout(traywin->render_timeout);
|
||||
traywin->render_timeout = add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
|
||||
traywin->render_timeout =
|
||||
add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1191,7 +1480,8 @@ void systray_render_icon(void* t)
|
||||
if (!XGetGeometry(server.dsp, traywin->win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) {
|
||||
stop_timeout(traywin->render_timeout);
|
||||
if (!traywin->resize_timeout)
|
||||
traywin->render_timeout = add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
|
||||
traywin->render_timeout =
|
||||
add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
|
||||
systray_render_icon_from_image(traywin);
|
||||
XSetErrorHandler(old);
|
||||
return;
|
||||
@@ -1199,10 +1489,17 @@ void systray_render_icon(void* t)
|
||||
if (xpos != 0 || ypos != 0 || width != traywin->width || height != traywin->height) {
|
||||
stop_timeout(traywin->render_timeout);
|
||||
if (!traywin->resize_timeout)
|
||||
traywin->render_timeout = add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
|
||||
traywin->render_timeout =
|
||||
add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
|
||||
systray_render_icon_from_image(traywin);
|
||||
if (systray_profile)
|
||||
fprintf(stderr, YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
|
||||
fprintf(stderr,
|
||||
YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering\n" RESET,
|
||||
profiling_get_time(),
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
traywin->win,
|
||||
traywin->name);
|
||||
XSetErrorHandler(old);
|
||||
return;
|
||||
}
|
||||
@@ -1218,15 +1515,18 @@ void systray_render_icon(void* t)
|
||||
} else {
|
||||
// Trigger window repaint
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "XClearArea(server.dsp, traywin->parent = %ld, 0, 0, traywin->width, traywin->height, True)\n", traywin->parent);
|
||||
fprintf(stderr,
|
||||
"XClearArea(server.dsp, traywin->parent = %ld, 0, 0, traywin->width, traywin->height, True)\n",
|
||||
traywin->parent);
|
||||
XClearArea(server.dsp, traywin->parent, 0, 0, 0, 0, True);
|
||||
if (systray_profile)
|
||||
fprintf(stderr, "XClearArea(server.dsp, traywin->win = %ld, 0, 0, traywin->width, traywin->height, True)\n", traywin->win);
|
||||
fprintf(stderr,
|
||||
"XClearArea(server.dsp, traywin->win = %ld, 0, 0, traywin->width, traywin->height, True)\n",
|
||||
traywin->win);
|
||||
XClearArea(server.dsp, traywin->win, 0, 0, 0, 0, True);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void refresh_systray_icons()
|
||||
{
|
||||
if (systray_profile)
|
||||
@@ -1241,8 +1541,7 @@ void refresh_systray_icons()
|
||||
}
|
||||
}
|
||||
|
||||
int systray_on_monitor(int i_monitor, int nb_panels)
|
||||
gboolean systray_on_monitor(int i_monitor, int num_panelss)
|
||||
{
|
||||
return (i_monitor == systray_monitor) ||
|
||||
(i_monitor == 0 && (systray_monitor >= nb_panels || systray_monitor < 0));
|
||||
return (i_monitor == systray_monitor) || (i_monitor == 0 && (systray_monitor >= num_panelss || systray_monitor < 0));
|
||||
}
|
||||
|
||||
@@ -20,37 +20,40 @@
|
||||
// Flags for _XEMBED_INFO
|
||||
#define XEMBED_MAPPED (1 << 0)
|
||||
|
||||
enum { SYSTRAY_SORT_ASCENDING, SYSTRAY_SORT_DESCENDING, SYSTRAY_SORT_LEFT2RIGHT, SYSTRAY_SORT_RIGHT2LEFT };
|
||||
typedef enum SystraySortMethod {
|
||||
SYSTRAY_SORT_ASCENDING = 0,
|
||||
SYSTRAY_SORT_DESCENDING,
|
||||
SYSTRAY_SORT_LEFT2RIGHT,
|
||||
SYSTRAY_SORT_RIGHT2LEFT,
|
||||
} SystraySortMethod;
|
||||
|
||||
typedef struct {
|
||||
// always start with area
|
||||
Area area;
|
||||
|
||||
GSList *list_icons;
|
||||
int sort;
|
||||
SystraySortMethod sort;
|
||||
int alpha, saturation, brightness;
|
||||
int icon_size, icons_per_column, icons_per_row, marging;
|
||||
int icon_size, icons_per_column, icons_per_row, margin;
|
||||
} Systraybar;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
Window parent;
|
||||
Window win;
|
||||
int x, y;
|
||||
int width, height;
|
||||
// TODO: manage icon's show/hide
|
||||
int hide;
|
||||
gboolean hide;
|
||||
int depth;
|
||||
Damage damage;
|
||||
timeout *render_timeout;
|
||||
int empty;
|
||||
gboolean empty;
|
||||
int pid;
|
||||
int chrono;
|
||||
struct timespec time_last_render;
|
||||
int num_fast_renders;
|
||||
int reparented;
|
||||
int embedded;
|
||||
gboolean reparented;
|
||||
gboolean embedded;
|
||||
int bad_size_counter;
|
||||
timeout *resize_timeout;
|
||||
struct timespec time_last_resize;
|
||||
@@ -58,15 +61,14 @@ typedef struct
|
||||
Imlib_Image image;
|
||||
} TrayWindow;
|
||||
|
||||
|
||||
// net_sel_win != None when protocol started
|
||||
extern Window net_sel_win;
|
||||
extern Systraybar systray;
|
||||
extern int refresh_systray;
|
||||
extern int systray_enabled;
|
||||
extern gboolean refresh_systray;
|
||||
extern gboolean systray_enabled;
|
||||
extern int systray_max_icon_size;
|
||||
extern int systray_monitor;
|
||||
extern int systray_profile;
|
||||
extern gboolean systray_profile;
|
||||
|
||||
// default global data
|
||||
void default_systray();
|
||||
@@ -79,9 +81,9 @@ void init_systray();
|
||||
void init_systray_panel(void *p);
|
||||
|
||||
void draw_systray(void *obj, cairo_t *c);
|
||||
int resize_systray(void *obj);
|
||||
gboolean resize_systray(void *obj);
|
||||
void on_change_systray(void *obj);
|
||||
int systray_on_monitor(int i_monitor, int nb_panels);
|
||||
gboolean systray_on_monitor(int i_monitor, int num_panelss);
|
||||
|
||||
// systray protocol
|
||||
// many tray icon doesn't manage stop/restart of the systray manager
|
||||
@@ -104,4 +106,3 @@ void systray_destroy_event(TrayWindow *traywin);
|
||||
void kde_update_icons();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -40,175 +40,179 @@ GSList* urgent_list;
|
||||
|
||||
char *task_get_tooltip(void *obj)
|
||||
{
|
||||
Task* t = obj;
|
||||
Task *t = (Task *)obj;
|
||||
return strdup(t->title);
|
||||
}
|
||||
|
||||
|
||||
Task *add_task(Window win)
|
||||
{
|
||||
if (!win) return 0;
|
||||
if (window_is_hidden(win)) return 0;
|
||||
if (!win)
|
||||
return 0;
|
||||
if (window_is_hidden(win))
|
||||
return 0;
|
||||
|
||||
XSelectInput(server.dsp, win, PropertyChangeMask | StructureNotifyMask);
|
||||
XFlush(server.dsp);
|
||||
|
||||
int monitor;
|
||||
if (nb_panel > 1) {
|
||||
monitor = window_get_monitor (win);
|
||||
if (monitor >= nb_panel) monitor = 0;
|
||||
}
|
||||
else monitor = 0;
|
||||
if (num_panels > 1) {
|
||||
monitor = get_window_monitor(win);
|
||||
if (monitor >= num_panels)
|
||||
monitor = 0;
|
||||
} else
|
||||
monitor = 0;
|
||||
|
||||
Task new_tsk;
|
||||
memset(&new_tsk, 0, sizeof(new_tsk));
|
||||
new_tsk.area.has_mouse_over_effect = 1;
|
||||
new_tsk.area.has_mouse_press_effect = 1;
|
||||
new_tsk.win = win;
|
||||
new_tsk.desktop = window_get_desktop (win);
|
||||
new_tsk.area.panel = &panel1[monitor];
|
||||
new_tsk.current_state = window_is_iconified(win) ? TASK_ICONIFIED : TASK_NORMAL;
|
||||
window_get_coordinates(win, &new_tsk.win_x, &new_tsk.win_y, &new_tsk.win_w, &new_tsk.win_h);
|
||||
Task new_task;
|
||||
memset(&new_task, 0, sizeof(new_task));
|
||||
new_task.area.has_mouse_over_effect = 1;
|
||||
new_task.area.has_mouse_press_effect = 1;
|
||||
new_task.win = win;
|
||||
new_task.desktop = get_window_desktop(win);
|
||||
new_task.area.panel = &panels[monitor];
|
||||
new_task.current_state = window_is_iconified(win) ? TASK_ICONIFIED : TASK_NORMAL;
|
||||
get_window_coordinates(win, &new_task.win_x, &new_task.win_y, &new_task.win_w, &new_task.win_h);
|
||||
|
||||
// allocate only one title and one icon
|
||||
// even with task_on_all_desktop and with task_on_all_panel
|
||||
new_tsk.title = 0;
|
||||
new_task.title = 0;
|
||||
int k;
|
||||
for (k = 0; k < TASK_STATE_COUNT; ++k) {
|
||||
new_tsk.icon[k] = 0;
|
||||
new_tsk.state_pix[k] = 0;
|
||||
new_task.icon[k] = 0;
|
||||
new_task.state_pix[k] = 0;
|
||||
}
|
||||
get_title(&new_tsk);
|
||||
get_icon(&new_tsk);
|
||||
get_title(&new_task);
|
||||
get_icon(&new_task);
|
||||
|
||||
//printf("new task %s win %u: desktop %d, monitor %d\n", new_tsk.title, win, new_tsk.desktop, monitor);
|
||||
// printf("new task %s win %u: desktop %d, monitor %d\n", new_task.title, win, new_task.desktop, monitor);
|
||||
|
||||
GPtrArray *task_group = g_ptr_array_new();
|
||||
Taskbar *tskbar;
|
||||
Task *new_tsk2=0;
|
||||
Taskbar *taskbar;
|
||||
Task *new_task2 = 0;
|
||||
int j;
|
||||
for (j=0 ; j < panel1[monitor].nb_desktop ; j++) {
|
||||
if (new_tsk.desktop != ALLDESKTOP && new_tsk.desktop != j) continue;
|
||||
for (j = 0; j < panels[monitor].num_desktops; j++) {
|
||||
if (new_task.desktop != ALLDESKTOP && new_task.desktop != j)
|
||||
continue;
|
||||
|
||||
tskbar = &panel1[monitor].taskbar[j];
|
||||
new_tsk2 = calloc(1, sizeof(Task));
|
||||
memcpy(&new_tsk2->area, &panel1[monitor].g_task.area, sizeof(Area));
|
||||
new_tsk2->area.parent = tskbar;
|
||||
new_tsk2->area.has_mouse_over_effect = 1;
|
||||
new_tsk2->area.has_mouse_press_effect = 1;
|
||||
new_tsk2->win = new_tsk.win;
|
||||
new_tsk2->desktop = new_tsk.desktop;
|
||||
new_tsk2->win_x = new_tsk.win_x;
|
||||
new_tsk2->win_y = new_tsk.win_y;
|
||||
new_tsk2->win_w = new_tsk.win_w;
|
||||
new_tsk2->win_h = new_tsk.win_h;
|
||||
new_tsk2->current_state = -1; // to update the current state later in set_task_state...
|
||||
if (new_tsk2->desktop == ALLDESKTOP && server.desktop != j) {
|
||||
taskbar = &panels[monitor].taskbar[j];
|
||||
new_task2 = calloc(1, sizeof(Task));
|
||||
memcpy(&new_task2->area, &panels[monitor].g_task.area, sizeof(Area));
|
||||
new_task2->area.parent = taskbar;
|
||||
new_task2->area.has_mouse_over_effect = 1;
|
||||
new_task2->area.has_mouse_press_effect = 1;
|
||||
new_task2->win = new_task.win;
|
||||
new_task2->desktop = new_task.desktop;
|
||||
new_task2->win_x = new_task.win_x;
|
||||
new_task2->win_y = new_task.win_y;
|
||||
new_task2->win_w = new_task.win_w;
|
||||
new_task2->win_h = new_task.win_h;
|
||||
new_task2->current_state = -1; // to update the current state later in set_task_state...
|
||||
if (new_task2->desktop == ALLDESKTOP && server.desktop != j) {
|
||||
// hide ALLDESKTOP task on non-current desktop
|
||||
new_tsk2->area.on_screen = 0;
|
||||
new_task2->area.on_screen = FALSE;
|
||||
}
|
||||
new_tsk2->title = new_tsk.title;
|
||||
if (panel1[monitor].g_task.tooltip_enabled)
|
||||
new_tsk2->area._get_tooltip_text = task_get_tooltip;
|
||||
new_task2->title = new_task.title;
|
||||
if (panels[monitor].g_task.tooltip_enabled)
|
||||
new_task2->area._get_tooltip_text = task_get_tooltip;
|
||||
for (k = 0; k < TASK_STATE_COUNT; ++k) {
|
||||
new_tsk2->icon[k] = new_tsk.icon[k];
|
||||
new_tsk2->icon_hover[k] = new_tsk.icon_hover[k];
|
||||
new_tsk2->icon_press[k] = new_tsk.icon_press[k];
|
||||
new_tsk2->state_pix[k] = 0;
|
||||
new_task2->icon[k] = new_task.icon[k];
|
||||
new_task2->icon_hover[k] = new_task.icon_hover[k];
|
||||
new_task2->icon_press[k] = new_task.icon_press[k];
|
||||
new_task2->state_pix[k] = 0;
|
||||
}
|
||||
new_tsk2->icon_width = new_tsk.icon_width;
|
||||
new_tsk2->icon_height = new_tsk.icon_height;
|
||||
tskbar->area.children = g_list_append(tskbar->area.children, new_tsk2);
|
||||
tskbar->area.resize_needed = 1;
|
||||
g_ptr_array_add(task_group, new_tsk2);
|
||||
//printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title);
|
||||
new_task2->icon_width = new_task.icon_width;
|
||||
new_task2->icon_height = new_task.icon_height;
|
||||
taskbar->area.children = g_list_append(taskbar->area.children, new_task2);
|
||||
taskbar->area.resize_needed = 1;
|
||||
g_ptr_array_add(task_group, new_task2);
|
||||
// printf("add_task panel %d, desktop %d, task %s\n", i, j, new_task2->title);
|
||||
}
|
||||
Window *key = calloc(1, sizeof(Window));
|
||||
*key = new_tsk.win;
|
||||
*key = new_task.win;
|
||||
g_hash_table_insert(win_to_task_table, key, task_group);
|
||||
set_task_state(new_tsk2, new_tsk.current_state);
|
||||
set_task_state(new_task2, new_task.current_state);
|
||||
|
||||
sort_taskbar_for_win(win);
|
||||
|
||||
if (panel_mode == MULTI_DESKTOP) {
|
||||
Panel *panel = new_tsk2->area.panel;
|
||||
if (taskbar_mode == MULTI_DESKTOP) {
|
||||
Panel *panel = new_task2->area.panel;
|
||||
panel->area.resize_needed = 1;
|
||||
}
|
||||
|
||||
if (window_is_urgent(win)) {
|
||||
add_urgent(new_tsk2);
|
||||
add_urgent(new_task2);
|
||||
}
|
||||
|
||||
return new_tsk2;
|
||||
return new_task2;
|
||||
}
|
||||
|
||||
|
||||
void remove_task (Task *tsk)
|
||||
void remove_task(Task *task)
|
||||
{
|
||||
if (!tsk) return;
|
||||
if (!task)
|
||||
return;
|
||||
|
||||
if (panel_mode == MULTI_DESKTOP) {
|
||||
Panel *panel = tsk->area.panel;
|
||||
if (taskbar_mode == MULTI_DESKTOP) {
|
||||
Panel *panel = task->area.panel;
|
||||
panel->area.resize_needed = 1;
|
||||
}
|
||||
|
||||
Window win = tsk->win;
|
||||
Window win = task->win;
|
||||
|
||||
// free title and icon just for the first task
|
||||
// even with task_on_all_desktop and with task_on_all_panel
|
||||
//printf("remove_task %s %d\n", tsk->title, tsk->desktop);
|
||||
if (tsk->title)
|
||||
free (tsk->title);
|
||||
// printf("remove_task %s %d\n", task->title, task->desktop);
|
||||
if (task->title)
|
||||
free(task->title);
|
||||
int k;
|
||||
for (k = 0; k < TASK_STATE_COUNT; ++k) {
|
||||
if (tsk->icon[k]) {
|
||||
imlib_context_set_image(tsk->icon[k]);
|
||||
if (task->icon[k]) {
|
||||
imlib_context_set_image(task->icon[k]);
|
||||
imlib_free_image();
|
||||
tsk->icon[k] = 0;
|
||||
task->icon[k] = 0;
|
||||
}
|
||||
if (tsk->icon_hover[k]) {
|
||||
imlib_context_set_image(tsk->icon_hover[k]);
|
||||
if (task->icon_hover[k]) {
|
||||
imlib_context_set_image(task->icon_hover[k]);
|
||||
imlib_free_image();
|
||||
tsk->icon_hover[k] = 0;
|
||||
task->icon_hover[k] = 0;
|
||||
}
|
||||
if (tsk->icon_press[k]) {
|
||||
imlib_context_set_image(tsk->icon_press[k]);
|
||||
if (task->icon_press[k]) {
|
||||
imlib_context_set_image(task->icon_press[k]);
|
||||
imlib_free_image();
|
||||
tsk->icon_press[k] = 0;
|
||||
task->icon_press[k] = 0;
|
||||
}
|
||||
if (tsk->state_pix[k]) XFreePixmap(server.dsp, tsk->state_pix[k]);
|
||||
if (task->state_pix[k])
|
||||
XFreePixmap(server.dsp, task->state_pix[k]);
|
||||
}
|
||||
|
||||
int i;
|
||||
Task *tsk2;
|
||||
Task *task2;
|
||||
GPtrArray *task_group = g_hash_table_lookup(win_to_task_table, &win);
|
||||
for (i = 0; i < task_group->len; ++i) {
|
||||
tsk2 = g_ptr_array_index(task_group, i);
|
||||
if (tsk2 == task_active) task_active = 0;
|
||||
if (tsk2 == task_drag) task_drag = 0;
|
||||
if (g_slist_find(urgent_list, tsk2)) del_urgent(tsk2);
|
||||
remove_area((Area*)tsk2);
|
||||
free(tsk2);
|
||||
task2 = g_ptr_array_index(task_group, i);
|
||||
if (task2 == task_active)
|
||||
task_active = 0;
|
||||
if (task2 == task_drag)
|
||||
task_drag = 0;
|
||||
if (g_slist_find(urgent_list, task2))
|
||||
del_urgent(task2);
|
||||
remove_area((Area *)task2);
|
||||
free(task2);
|
||||
}
|
||||
g_hash_table_remove(win_to_task_table, &win);
|
||||
}
|
||||
|
||||
|
||||
int get_title(Task *tsk)
|
||||
gboolean get_title(Task *task)
|
||||
{
|
||||
Panel *panel = tsk->area.panel;
|
||||
Panel *panel = task->area.panel;
|
||||
char *title, *name;
|
||||
|
||||
if (!panel->g_task.text &&
|
||||
!panel->g_task.tooltip_enabled &&
|
||||
taskbar_sort_method != TASKBAR_SORT_TITLE)
|
||||
if (!panel->g_task.text && !panel->g_task.tooltip_enabled && taskbar_sort_method != TASKBAR_SORT_TITLE)
|
||||
return 0;
|
||||
|
||||
name = server_get_property (tsk->win, server.atom._NET_WM_VISIBLE_NAME, server.atom.UTF8_STRING, 0);
|
||||
name = server_get_property(task->win, server.atom._NET_WM_VISIBLE_NAME, server.atom.UTF8_STRING, 0);
|
||||
if (!name || !strlen(name)) {
|
||||
name = server_get_property (tsk->win, server.atom._NET_WM_NAME, server.atom.UTF8_STRING, 0);
|
||||
name = server_get_property(task->win, server.atom._NET_WM_NAME, server.atom.UTF8_STRING, 0);
|
||||
if (!name || !strlen(name)) {
|
||||
name = server_get_property (tsk->win, server.atom.WM_NAME, XA_STRING, 0);
|
||||
name = server_get_property(task->win, server.atom.WM_NAME, XA_STRING, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,51 +221,50 @@ int get_title(Task *tsk)
|
||||
} else {
|
||||
title = strdup("Untitled");
|
||||
}
|
||||
if (name) XFree (name);
|
||||
if (name)
|
||||
XFree(name);
|
||||
|
||||
if (tsk->title) {
|
||||
if (task->title) {
|
||||
// check unecessary title change
|
||||
if (strcmp(tsk->title, title) == 0) {
|
||||
if (strcmp(task->title, title) == 0) {
|
||||
free(title);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
free(tsk->title);
|
||||
} else
|
||||
free(task->title);
|
||||
}
|
||||
|
||||
tsk->title = title;
|
||||
GPtrArray* task_group = task_get_tasks(tsk->win);
|
||||
task->title = title;
|
||||
GPtrArray *task_group = task_get_tasks(task->win);
|
||||
if (task_group) {
|
||||
int i;
|
||||
for (i = 0; i < task_group->len; ++i) {
|
||||
Task* tsk2 = g_ptr_array_index(task_group, i);
|
||||
tsk2->title = tsk->title;
|
||||
set_task_redraw(tsk2);
|
||||
Task *task2 = g_ptr_array_index(task_group, i);
|
||||
task2->title = task->title;
|
||||
set_task_redraw(task2);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void get_icon (Task *tsk)
|
||||
void get_icon(Task *task)
|
||||
{
|
||||
Panel *panel = tsk->area.panel;
|
||||
if (!panel->g_task.icon) return;
|
||||
Panel *panel = task->area.panel;
|
||||
if (!panel->g_task.icon)
|
||||
return;
|
||||
int i;
|
||||
Imlib_Image img = NULL;
|
||||
XWMHints *hints = 0;
|
||||
gulong *data = 0;
|
||||
|
||||
int k;
|
||||
for (k=0; k<TASK_STATE_COUNT; ++k) {
|
||||
if (tsk->icon[k]) {
|
||||
imlib_context_set_image(tsk->icon[k]);
|
||||
for (int k = 0; k < TASK_STATE_COUNT; ++k) {
|
||||
if (task->icon[k]) {
|
||||
imlib_context_set_image(task->icon[k]);
|
||||
imlib_free_image();
|
||||
tsk->icon[k] = 0;
|
||||
task->icon[k] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
data = server_get_property (tsk->win, server.atom._NET_WM_ICON, XA_CARDINAL, &i);
|
||||
data = server_get_property(task->win, server.atom._NET_WM_ICON, XA_CARDINAL, &i);
|
||||
if (data) {
|
||||
// get ARGB icon
|
||||
int w, h;
|
||||
@@ -277,10 +280,9 @@ void get_icon (Task *tsk)
|
||||
#else
|
||||
img = imlib_create_image_using_data(w, h, (DATA32 *)tmp_data);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// get Pixmap icon
|
||||
hints = XGetWMHints(server.dsp, tsk->win);
|
||||
hints = XGetWMHints(server.dsp, task->win);
|
||||
if (hints) {
|
||||
if (hints->flags & IconPixmapHint && hints->icon_pixmap != 0) {
|
||||
// get width, height and depth for the pixmap
|
||||
@@ -307,25 +309,37 @@ void get_icon (Task *tsk)
|
||||
int w, h;
|
||||
w = imlib_image_get_width();
|
||||
h = imlib_image_get_height();
|
||||
Imlib_Image orig_image = imlib_create_cropped_scaled_image(0, 0, w, h, panel->g_task.icon_size1, panel->g_task.icon_size1);
|
||||
Imlib_Image orig_image =
|
||||
imlib_create_cropped_scaled_image(0, 0, w, h, panel->g_task.icon_size1, panel->g_task.icon_size1);
|
||||
imlib_free_image();
|
||||
|
||||
imlib_context_set_image(orig_image);
|
||||
tsk->icon_width = imlib_image_get_width();
|
||||
tsk->icon_height = imlib_image_get_height();
|
||||
for (k=0; k<TASK_STATE_COUNT; ++k) {
|
||||
task->icon_width = imlib_image_get_width();
|
||||
task->icon_height = imlib_image_get_height();
|
||||
for (int k = 0; k < TASK_STATE_COUNT; ++k) {
|
||||
imlib_context_set_image(orig_image);
|
||||
tsk->icon[k] = imlib_clone_image();
|
||||
imlib_context_set_image(tsk->icon[k]);
|
||||
task->icon[k] = imlib_clone_image();
|
||||
imlib_context_set_image(task->icon[k]);
|
||||
DATA32 *data32;
|
||||
if (panel->g_task.alpha[k] != 100 || panel->g_task.saturation[k] != 0 || panel->g_task.brightness[k] != 0) {
|
||||
data32 = imlib_image_get_data();
|
||||
adjust_asb(data32, tsk->icon_width, tsk->icon_height, panel->g_task.alpha[k], (float)panel->g_task.saturation[k]/100, (float)panel->g_task.brightness[k]/100);
|
||||
adjust_asb(data32,
|
||||
task->icon_width,
|
||||
task->icon_height,
|
||||
panel->g_task.alpha[k],
|
||||
(float)panel->g_task.saturation[k] / 100,
|
||||
(float)panel->g_task.brightness[k] / 100);
|
||||
imlib_image_put_back_data(data32);
|
||||
}
|
||||
if (panel_config.mouse_effects) {
|
||||
tsk->icon_hover[k] = adjust_icon(tsk->icon[k], panel_config.mouse_over_alpha, panel_config.mouse_over_saturation, panel_config.mouse_over_brightness);
|
||||
tsk->icon_press[k] = adjust_icon(tsk->icon[k], panel_config.mouse_pressed_alpha, panel_config.mouse_pressed_saturation, panel_config.mouse_pressed_brightness);
|
||||
task->icon_hover[k] = adjust_icon(task->icon[k],
|
||||
panel_config.mouse_over_alpha,
|
||||
panel_config.mouse_over_saturation,
|
||||
panel_config.mouse_over_brightness);
|
||||
task->icon_press[k] = adjust_icon(task->icon[k],
|
||||
panel_config.mouse_pressed_alpha,
|
||||
panel_config.mouse_pressed_saturation,
|
||||
panel_config.mouse_pressed_brightness);
|
||||
}
|
||||
}
|
||||
imlib_context_set_image(orig_image);
|
||||
@@ -336,90 +350,91 @@ void get_icon (Task *tsk)
|
||||
if (data)
|
||||
XFree(data);
|
||||
|
||||
GPtrArray* task_group = task_get_tasks(tsk->win);
|
||||
GPtrArray *task_group = task_get_tasks(task->win);
|
||||
if (task_group) {
|
||||
for (i = 0; i < task_group->len; ++i) {
|
||||
Task* tsk2 = g_ptr_array_index(task_group, i);
|
||||
tsk2->icon_width = tsk->icon_width;
|
||||
tsk2->icon_height = tsk->icon_height;
|
||||
int k;
|
||||
for (k=0; k<TASK_STATE_COUNT; ++k) {
|
||||
tsk2->icon[k] = tsk->icon[k];
|
||||
tsk2->icon_hover[k] = tsk->icon_hover[k];
|
||||
tsk2->icon_press[k] = tsk->icon_press[k];
|
||||
Task *task2 = g_ptr_array_index(task_group, i);
|
||||
task2->icon_width = task->icon_width;
|
||||
task2->icon_height = task->icon_height;
|
||||
for (int k = 0; k < TASK_STATE_COUNT; ++k) {
|
||||
task2->icon[k] = task->icon[k];
|
||||
task2->icon_hover[k] = task->icon_hover[k];
|
||||
task2->icon_press[k] = task->icon_press[k];
|
||||
}
|
||||
set_task_redraw(tsk2);
|
||||
set_task_redraw(task2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO icons look too large when the panel is large
|
||||
void draw_task_icon (Task *tsk, int text_width)
|
||||
void draw_task_icon(Task *task, int text_width)
|
||||
{
|
||||
if (tsk->icon[tsk->current_state] == 0) return;
|
||||
if (!task->icon[task->current_state])
|
||||
return;
|
||||
|
||||
// Find pos
|
||||
int pos_x;
|
||||
Panel *panel = (Panel*)tsk->area.panel;
|
||||
Panel *panel = (Panel *)task->area.panel;
|
||||
if (panel->g_task.centered) {
|
||||
if (panel->g_task.text)
|
||||
pos_x = (tsk->area.width - text_width - panel->g_task.icon_size1) / 2;
|
||||
pos_x = (task->area.width - text_width - panel->g_task.icon_size1) / 2;
|
||||
else
|
||||
pos_x = (tsk->area.width - panel->g_task.icon_size1) / 2;
|
||||
}
|
||||
else pos_x = panel->g_task.area.paddingxlr + tsk->area.bg->border.width;
|
||||
pos_x = (task->area.width - panel->g_task.icon_size1) / 2;
|
||||
} else
|
||||
pos_x = panel->g_task.area.paddingxlr + task->area.bg->border.width;
|
||||
|
||||
// Render
|
||||
|
||||
Imlib_Image image;
|
||||
// Render
|
||||
if (panel_config.mouse_effects) {
|
||||
if (tsk->area.mouse_state == MOUSE_OVER)
|
||||
image = tsk->icon_hover[tsk->current_state];
|
||||
else if (tsk->area.mouse_state == MOUSE_DOWN)
|
||||
image = tsk->icon_press[tsk->current_state];
|
||||
if (task->area.mouse_state == MOUSE_OVER)
|
||||
image = task->icon_hover[task->current_state];
|
||||
else if (task->area.mouse_state == MOUSE_DOWN)
|
||||
image = task->icon_press[task->current_state];
|
||||
else
|
||||
image = tsk->icon[tsk->current_state];
|
||||
image = task->icon[task->current_state];
|
||||
} else {
|
||||
image = tsk->icon[tsk->current_state];
|
||||
image = task->icon[task->current_state];
|
||||
}
|
||||
|
||||
imlib_context_set_image(image);
|
||||
render_image(tsk->area.pix, pos_x, panel->g_task.icon_posy);
|
||||
render_image(task->area.pix, pos_x, panel->g_task.icon_posy);
|
||||
}
|
||||
|
||||
|
||||
void draw_task(void *obj, cairo_t *c)
|
||||
{
|
||||
Task *tsk = obj;
|
||||
Task *task = obj;
|
||||
if (!panel_config.mouse_effects)
|
||||
tsk->state_pix[tsk->current_state] = tsk->area.pix;
|
||||
task->state_pix[task->current_state] = task->area.pix;
|
||||
PangoLayout *layout;
|
||||
Color *config_text;
|
||||
int width = 0, height;
|
||||
Panel *panel = (Panel*)tsk->area.panel;
|
||||
//printf("draw_task %d %d\n", tsk->area.posx, tsk->area.posy);
|
||||
Panel *panel = (Panel *)task->area.panel;
|
||||
// printf("draw_task %d %d\n", task->area.posx, task->area.posy);
|
||||
|
||||
if (panel->g_task.text) {
|
||||
/* Layout */
|
||||
layout = pango_cairo_create_layout(c);
|
||||
pango_layout_set_font_description(layout, panel->g_task.font_desc);
|
||||
pango_layout_set_text(layout, tsk->title, -1);
|
||||
pango_layout_set_text(layout, task->title, -1);
|
||||
|
||||
/* Drawing width and Cut text */
|
||||
// pango use U+22EF or U+2026
|
||||
pango_layout_set_width(layout, ((Taskbar*)tsk->area.parent)->text_width * PANGO_SCALE);
|
||||
pango_layout_set_width(layout, ((Taskbar *)task->area.parent)->text_width * PANGO_SCALE);
|
||||
pango_layout_set_height(layout, panel->g_task.text_height * PANGO_SCALE);
|
||||
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
|
||||
|
||||
/* Center text */
|
||||
if (panel->g_task.centered) pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
|
||||
else pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
|
||||
if (panel->g_task.centered)
|
||||
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
|
||||
else
|
||||
pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
|
||||
|
||||
pango_layout_get_pixel_size(layout, &width, &height);
|
||||
|
||||
config_text = &panel->g_task.font[tsk->current_state];
|
||||
config_text = &panel->g_task.font[task->current_state];
|
||||
|
||||
double text_posy = (panel->g_task.area.height - height) / 2.0;
|
||||
|
||||
@@ -429,21 +444,27 @@ void draw_task (void *obj, cairo_t *c)
|
||||
}
|
||||
|
||||
if (panel->g_task.icon) {
|
||||
draw_task_icon (tsk, width);
|
||||
draw_task_icon(task, width);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void on_change_task(void *obj)
|
||||
{
|
||||
Task *tsk = obj;
|
||||
Panel *panel = (Panel*)tsk->area.panel;
|
||||
Task *task = obj;
|
||||
Panel *panel = (Panel *)task->area.panel;
|
||||
|
||||
long value[] = { panel->posx+tsk->area.posx, panel->posy+tsk->area.posy, tsk->area.width, tsk->area.height };
|
||||
XChangeProperty (server.dsp, tsk->win, server.atom._NET_WM_ICON_GEOMETRY, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)value, 4);
|
||||
long value[] = {panel->posx + task->area.posx, panel->posy + task->area.posy, task->area.width, task->area.height};
|
||||
XChangeProperty(server.dsp,
|
||||
task->win,
|
||||
server.atom._NET_WM_ICON_GEOMETRY,
|
||||
XA_CARDINAL,
|
||||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)value,
|
||||
4);
|
||||
|
||||
// reset Pixmap when position/size changed
|
||||
set_task_redraw(tsk);
|
||||
set_task_redraw(task);
|
||||
}
|
||||
|
||||
// Given a pointer to the active task (active_task) and a pointer
|
||||
@@ -454,35 +475,35 @@ Task *find_active_task(Task *current_task, Task *active_task)
|
||||
if (active_task == NULL)
|
||||
return current_task;
|
||||
|
||||
Taskbar* tskbar = current_task->area.parent;
|
||||
Taskbar *taskbar = current_task->area.parent;
|
||||
|
||||
GList *l0 = tskbar->area.children;
|
||||
GList *l0 = taskbar->area.children;
|
||||
if (taskbarname_enabled)
|
||||
l0 = l0->next;
|
||||
for (; l0; l0 = l0->next) {
|
||||
Task *tsk = l0->data;
|
||||
if (tsk->win == active_task->win)
|
||||
return tsk;
|
||||
Task *task = l0->data;
|
||||
if (task->win == active_task->win)
|
||||
return task;
|
||||
}
|
||||
|
||||
return current_task;
|
||||
}
|
||||
|
||||
Task *next_task(Task *tsk)
|
||||
Task *next_task(Task *task)
|
||||
{
|
||||
if (tsk == 0)
|
||||
if (!task)
|
||||
return 0;
|
||||
|
||||
Taskbar* tskbar = tsk->area.parent;
|
||||
Taskbar *taskbar = task->area.parent;
|
||||
|
||||
GList *l0 = tskbar->area.children;
|
||||
if (taskbarname_enabled) l0 = l0->next;
|
||||
GList *lfirst_tsk = l0;
|
||||
GList *l0 = taskbar->area.children;
|
||||
if (taskbarname_enabled)
|
||||
l0 = l0->next;
|
||||
GList *lfirst_task = l0;
|
||||
for (; l0; l0 = l0->next) {
|
||||
Task *tsk1 = l0->data;
|
||||
if (tsk1 == tsk) {
|
||||
if (l0->next == 0) l0 = lfirst_tsk;
|
||||
else l0 = l0->next;
|
||||
Task *task1 = l0->data;
|
||||
if (task1 == task) {
|
||||
l0 = l0->next ? l0->next : lfirst_task;
|
||||
return l0->data;
|
||||
}
|
||||
}
|
||||
@@ -490,34 +511,33 @@ Task *next_task(Task *tsk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
Task *prev_task(Task *tsk)
|
||||
Task *prev_task(Task *task)
|
||||
{
|
||||
if (tsk == 0)
|
||||
if (!task)
|
||||
return 0;
|
||||
|
||||
Task *tsk1, *tsk2;
|
||||
Taskbar* tskbar = tsk->area.parent;
|
||||
Taskbar *taskbar = task->area.parent;
|
||||
|
||||
tsk2 = 0;
|
||||
GList *l0 = tskbar->area.children;
|
||||
if (taskbarname_enabled) l0 = l0->next;
|
||||
GList *lfirst_tsk = l0;
|
||||
Task *task2 = NULL;
|
||||
GList *l0 = taskbar->area.children;
|
||||
if (taskbarname_enabled)
|
||||
l0 = l0->next;
|
||||
GList *lfirst_task = l0;
|
||||
for (; l0; l0 = l0->next) {
|
||||
tsk1 = l0->data;
|
||||
if (tsk1 == tsk) {
|
||||
if (l0 == lfirst_tsk) {
|
||||
Task *task1 = l0->data;
|
||||
if (task1 == task) {
|
||||
if (l0 == lfirst_task) {
|
||||
l0 = g_list_last(l0);
|
||||
tsk2 = l0->data;
|
||||
task2 = l0->data;
|
||||
}
|
||||
return tsk2;
|
||||
return task2;
|
||||
}
|
||||
tsk2 = tsk1;
|
||||
task2 = task1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void active_task()
|
||||
{
|
||||
if (task_active) {
|
||||
@@ -525,7 +545,7 @@ void active_task()
|
||||
task_active = 0;
|
||||
}
|
||||
|
||||
Window w1 = window_get_active();
|
||||
Window w1 = get_active_window();
|
||||
// printf("Change active task %ld\n", w1);
|
||||
|
||||
if (w1) {
|
||||
@@ -538,32 +558,31 @@ void active_task()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void set_task_state(Task *tsk, int state)
|
||||
void set_task_state(Task *task, TaskState state)
|
||||
{
|
||||
if (tsk == 0 || state < 0 || state >= TASK_STATE_COUNT)
|
||||
if (!task || state < 0 || state >= TASK_STATE_COUNT)
|
||||
return;
|
||||
|
||||
if (tsk->current_state != state || hide_task_diff_monitor) {
|
||||
GPtrArray* task_group = task_get_tasks(tsk->win);
|
||||
if (task->current_state != state || hide_task_diff_monitor) {
|
||||
GPtrArray *task_group = task_get_tasks(task->win);
|
||||
if (task_group) {
|
||||
int i;
|
||||
for (i = 0; i < task_group->len; ++i) {
|
||||
Task* tsk1 = g_ptr_array_index(task_group, i);
|
||||
tsk1->current_state = state;
|
||||
tsk1->area.bg = panel1[0].g_task.background[state];
|
||||
Task *task1 = g_ptr_array_index(task_group, i);
|
||||
task1->current_state = state;
|
||||
task1->area.bg = panels[0].g_task.background[state];
|
||||
if (!panel_config.mouse_effects) {
|
||||
tsk1->area.pix = tsk1->state_pix[state];
|
||||
if (!tsk1->area.pix)
|
||||
tsk1->area.redraw_needed = 1;
|
||||
task1->area.pix = task1->state_pix[state];
|
||||
if (!task1->area.pix)
|
||||
task1->area.redraw_needed = TRUE;
|
||||
} else {
|
||||
tsk1->area.redraw_needed = 1;
|
||||
task1->area.redraw_needed = TRUE;
|
||||
}
|
||||
if (state == TASK_ACTIVE && g_slist_find(urgent_list, tsk1))
|
||||
del_urgent(tsk1);
|
||||
if (state == TASK_ACTIVE && g_slist_find(urgent_list, task1))
|
||||
del_urgent(task1);
|
||||
int hide = 0;
|
||||
Taskbar *taskbar = (Taskbar *)tsk1->area.parent;
|
||||
if (tsk->desktop == ALLDESKTOP && server.desktop != taskbar->desktop) {
|
||||
Taskbar *taskbar = (Taskbar *)task1->area.parent;
|
||||
if (task->desktop == ALLDESKTOP && server.desktop != taskbar->desktop) {
|
||||
// Hide ALLDESKTOP task on non-current desktop
|
||||
hide = 1;
|
||||
}
|
||||
@@ -573,37 +592,36 @@ void set_task_state(Task *tsk, int state)
|
||||
hide = 1;
|
||||
}
|
||||
}
|
||||
if (window_get_monitor(tsk->win) != ((Panel*)tsk->area.panel)->monitor &&
|
||||
(hide_task_diff_monitor || nb_panel > 1)) {
|
||||
if (get_window_monitor(task->win) != ((Panel *)task->area.panel)->monitor &&
|
||||
(hide_task_diff_monitor || num_panels > 1)) {
|
||||
hide = 1;
|
||||
}
|
||||
if (1 - hide != tsk1->area.on_screen) {
|
||||
tsk1->area.on_screen = 1 - hide;
|
||||
set_task_redraw(tsk1);
|
||||
Panel *p = (Panel*)tsk->area.panel;
|
||||
tsk->area.resize_needed = 1;
|
||||
if (1 - hide != task1->area.on_screen) {
|
||||
task1->area.on_screen = TRUE - hide;
|
||||
set_task_redraw(task1);
|
||||
Panel *p = (Panel *)task->area.panel;
|
||||
task->area.resize_needed = 1;
|
||||
p->taskbar->area.resize_needed = 1;
|
||||
p->area.resize_needed = 1;
|
||||
}
|
||||
}
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void set_task_redraw(Task* tsk)
|
||||
void set_task_redraw(Task *task)
|
||||
{
|
||||
int k;
|
||||
for (k = 0; k < TASK_STATE_COUNT; ++k) {
|
||||
if (tsk->state_pix[k]) XFreePixmap(server.dsp, tsk->state_pix[k]);
|
||||
tsk->state_pix[k] = 0;
|
||||
if (task->state_pix[k])
|
||||
XFreePixmap(server.dsp, task->state_pix[k]);
|
||||
task->state_pix[k] = 0;
|
||||
}
|
||||
tsk->area.pix = 0;
|
||||
tsk->area.redraw_needed = 1;
|
||||
task->area.pix = 0;
|
||||
task->area.redraw_needed = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void blink_urgent(void *arg)
|
||||
{
|
||||
GSList *urgent_task = urgent_list;
|
||||
@@ -617,39 +635,37 @@ void blink_urgent(void* arg)
|
||||
}
|
||||
urgent_task = urgent_task->next;
|
||||
}
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void add_urgent(Task *tsk)
|
||||
void add_urgent(Task *task)
|
||||
{
|
||||
if (!tsk)
|
||||
if (!task)
|
||||
return;
|
||||
|
||||
// some programs set urgency hint although they are active
|
||||
if ( task_active && task_active->win == tsk->win )
|
||||
if (task_active && task_active->win == task->win)
|
||||
return;
|
||||
|
||||
tsk = task_get_task(tsk->win); // always add the first tsk for a task group (omnipresent windows)
|
||||
tsk->urgent_tick = 0;
|
||||
if (g_slist_find(urgent_list, tsk))
|
||||
task = task_get_task(task->win); // always add the first task for a task group (omnipresent windows)
|
||||
task->urgent_tick = 0;
|
||||
if (g_slist_find(urgent_list, task))
|
||||
return;
|
||||
|
||||
// not yet in the list, so we have to add it
|
||||
urgent_list = g_slist_prepend(urgent_list, tsk);
|
||||
urgent_list = g_slist_prepend(urgent_list, task);
|
||||
|
||||
if (!urgent_timeout)
|
||||
urgent_timeout = add_timeout(10, 1000, blink_urgent, 0, &urgent_timeout);
|
||||
|
||||
Panel *panel = tsk->area.panel;
|
||||
Panel *panel = task->area.panel;
|
||||
if (panel->is_hidden)
|
||||
autohide_show(panel);
|
||||
}
|
||||
|
||||
|
||||
void del_urgent(Task *tsk)
|
||||
void del_urgent(Task *task)
|
||||
{
|
||||
urgent_list = g_slist_remove(urgent_list, tsk);
|
||||
urgent_list = g_slist_remove(urgent_list, task);
|
||||
if (!urgent_list) {
|
||||
stop_timeout(urgent_timeout);
|
||||
urgent_timeout = NULL;
|
||||
|
||||
@@ -13,19 +13,25 @@
|
||||
#include "common.h"
|
||||
#include "timer.h"
|
||||
|
||||
typedef enum TaskState {
|
||||
TASK_NORMAL = 0,
|
||||
TASK_ACTIVE,
|
||||
TASK_ICONIFIED,
|
||||
TASK_URGENT,
|
||||
TASK_STATE_COUNT,
|
||||
} TaskState;
|
||||
|
||||
enum { TASK_NORMAL, TASK_ACTIVE, TASK_ICONIFIED, TASK_URGENT, TASK_STATE_COUNT };
|
||||
extern timeout *urgent_timeout;
|
||||
extern GSList *urgent_list;
|
||||
|
||||
// --------------------------------------------------
|
||||
// global task parameter
|
||||
typedef struct {
|
||||
typedef struct GlobalTask {
|
||||
Area area;
|
||||
|
||||
int text;
|
||||
int icon;
|
||||
int centered;
|
||||
gboolean text;
|
||||
gboolean icon;
|
||||
gboolean centered;
|
||||
|
||||
int icon_posy;
|
||||
int icon_size1;
|
||||
@@ -43,10 +49,8 @@ typedef struct {
|
||||
PangoFontDescription *font_desc;
|
||||
Color font[TASK_STATE_COUNT];
|
||||
int config_font_mask;
|
||||
int tooltip_enabled;
|
||||
} Global_task;
|
||||
|
||||
|
||||
gboolean tooltip_enabled;
|
||||
} GlobalTask;
|
||||
|
||||
typedef struct {
|
||||
// always start with area
|
||||
@@ -55,7 +59,7 @@ typedef struct {
|
||||
// TODO: group task with list of windows here
|
||||
Window win;
|
||||
int desktop;
|
||||
int current_state;
|
||||
TaskState current_state;
|
||||
Imlib_Image icon[TASK_STATE_COUNT];
|
||||
Imlib_Image icon_hover[TASK_STATE_COUNT];
|
||||
Imlib_Image icon_press[TASK_STATE_COUNT];
|
||||
@@ -71,25 +75,23 @@ typedef struct {
|
||||
int win_h;
|
||||
} Task;
|
||||
|
||||
|
||||
Task *add_task(Window win);
|
||||
void remove_task (Task *tsk);
|
||||
void remove_task(Task *task);
|
||||
|
||||
void draw_task(void *obj, cairo_t *c);
|
||||
void on_change_task(void *obj);
|
||||
|
||||
void get_icon (Task *tsk);
|
||||
int get_title(Task *tsk);
|
||||
void get_icon(Task *task);
|
||||
gboolean get_title(Task *task);
|
||||
void active_task();
|
||||
void set_task_state(Task* tsk, int state);
|
||||
void set_task_redraw(Task* tsk);
|
||||
void set_task_state(Task *task, TaskState state);
|
||||
void set_task_redraw(Task *task);
|
||||
|
||||
Task *find_active_task(Task *current_task, Task *active_task);
|
||||
Task *next_task (Task *tsk);
|
||||
Task *prev_task (Task *tsk);
|
||||
Task *next_task(Task *task);
|
||||
Task *prev_task(Task *task);
|
||||
|
||||
void add_urgent(Task *tsk);
|
||||
void del_urgent(Task *tsk);
|
||||
void add_urgent(Task *task);
|
||||
void del_urgent(Task *task);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -33,26 +33,33 @@
|
||||
#include "panel.h"
|
||||
#include "strnatcmp.h"
|
||||
|
||||
|
||||
/* win_to_task_table holds for every Window an array of tasks. Usually the array contains only one
|
||||
element. However for omnipresent windows (windows which are visible in every taskbar) the array
|
||||
contains to every Task* on each panel a pointer (i.e. GPtrArray.len == server.nb_desktop)
|
||||
contains to every Task* on each panel a pointer (i.e. GPtrArray.len == server.num_desktops)
|
||||
*/
|
||||
GHashTable *win_to_task_table;
|
||||
|
||||
Task *task_active;
|
||||
Task *task_drag;
|
||||
int taskbar_enabled;
|
||||
int taskbar_distribute_size;
|
||||
int hide_inactive_tasks;
|
||||
int hide_task_diff_monitor;
|
||||
int taskbar_sort_method;
|
||||
int taskbar_alignment;
|
||||
|
||||
guint win_hash(gconstpointer key) { return (guint)*((Window*)key); }
|
||||
gboolean win_compare(gconstpointer a, gconstpointer b) { return (*((Window*)a) == *((Window*)b)); }
|
||||
void free_ptr_array(gpointer data) { g_ptr_array_free(data, 1); }
|
||||
gboolean taskbar_enabled;
|
||||
gboolean taskbar_distribute_size;
|
||||
gboolean hide_inactive_tasks;
|
||||
gboolean hide_task_diff_monitor;
|
||||
TaskbarSortMethod taskbar_sort_method;
|
||||
Alignment taskbar_alignment;
|
||||
|
||||
guint win_hash(gconstpointer key)
|
||||
{
|
||||
return (guint) * ((const Window *)key);
|
||||
}
|
||||
gboolean win_compare(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
return (*((const Window *)a) == *((const Window *)b));
|
||||
}
|
||||
void free_ptr_array(gpointer data)
|
||||
{
|
||||
g_ptr_array_free(data, 1);
|
||||
}
|
||||
|
||||
void default_taskbar()
|
||||
{
|
||||
@@ -71,7 +78,7 @@ void default_taskbar()
|
||||
void cleanup_taskbar()
|
||||
{
|
||||
Panel *panel;
|
||||
Taskbar *tskbar;
|
||||
Taskbar *taskbar;
|
||||
int i, j, k;
|
||||
|
||||
cleanup_taskbarname();
|
||||
@@ -88,18 +95,18 @@ void cleanup_taskbar()
|
||||
g_hash_table_destroy(win_to_task_table);
|
||||
win_to_task_table = NULL;
|
||||
}
|
||||
for (i = 0 ; i < nb_panel; i++) {
|
||||
panel = &panel1[i];
|
||||
for (j = 0; j < panel->nb_desktop; j++) {
|
||||
tskbar = &panel->taskbar[j];
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
panel = &panels[i];
|
||||
for (j = 0; j < panel->num_desktops; j++) {
|
||||
taskbar = &panel->taskbar[j];
|
||||
for (k = 0; k < TASKBAR_STATE_COUNT; ++k) {
|
||||
if (tskbar->state_pix[k])
|
||||
XFreePixmap(server.dsp, tskbar->state_pix[k]);
|
||||
tskbar->state_pix[k] = 0;
|
||||
if (taskbar->state_pix[k])
|
||||
XFreePixmap(server.dsp, taskbar->state_pix[k]);
|
||||
taskbar->state_pix[k] = 0;
|
||||
}
|
||||
free_area(&tskbar->area);
|
||||
free_area(&taskbar->area);
|
||||
// remove taskbar from the panel
|
||||
remove_area((Area*)tskbar);
|
||||
remove_area((Area *)taskbar);
|
||||
}
|
||||
if (panel->taskbar) {
|
||||
free(panel->taskbar);
|
||||
@@ -113,33 +120,31 @@ void cleanup_taskbar()
|
||||
stop_timeout(urgent_timeout);
|
||||
}
|
||||
|
||||
|
||||
void init_taskbar()
|
||||
{
|
||||
if (win_to_task_table == 0)
|
||||
if (!win_to_task_table)
|
||||
win_to_task_table = g_hash_table_new_full(win_hash, win_compare, free, free_ptr_array);
|
||||
|
||||
task_active = 0;
|
||||
task_drag = 0;
|
||||
}
|
||||
|
||||
|
||||
void init_taskbar_panel(void *p)
|
||||
{
|
||||
Panel *panel = (Panel *)p;
|
||||
int j;
|
||||
|
||||
if (panel->g_taskbar.background[TASKBAR_NORMAL] == 0) {
|
||||
if (!panel->g_taskbar.background[TASKBAR_NORMAL]) {
|
||||
panel->g_taskbar.background[TASKBAR_NORMAL] = &g_array_index(backgrounds, Background, 0);
|
||||
panel->g_taskbar.background[TASKBAR_ACTIVE] = &g_array_index(backgrounds, Background, 0);
|
||||
}
|
||||
if (panel->g_taskbar.background_name[TASKBAR_NORMAL] == 0) {
|
||||
if (!panel->g_taskbar.background_name[TASKBAR_NORMAL]) {
|
||||
panel->g_taskbar.background_name[TASKBAR_NORMAL] = &g_array_index(backgrounds, Background, 0);
|
||||
panel->g_taskbar.background_name[TASKBAR_ACTIVE] = &g_array_index(backgrounds, Background, 0);
|
||||
}
|
||||
if (!panel->g_task.font_desc)
|
||||
panel->g_task.font_desc = pango_font_description_from_string(DEFAULT_FONT);
|
||||
if (panel->g_task.area.bg == 0)
|
||||
if (!panel->g_task.area.bg)
|
||||
panel->g_task.area.bg = &g_array_index(backgrounds, Background, 0);
|
||||
|
||||
// taskbar name
|
||||
@@ -149,7 +154,7 @@ void init_taskbar_panel(void *p)
|
||||
panel->g_taskbar.area_name._draw_foreground = draw_taskbarname;
|
||||
panel->g_taskbar.area_name._on_change_layout = 0;
|
||||
panel->g_taskbar.area_name.resize_needed = 1;
|
||||
panel->g_taskbar.area_name.on_screen = 1;
|
||||
panel->g_taskbar.area_name.on_screen = TRUE;
|
||||
|
||||
// taskbar
|
||||
panel->g_taskbar.area.parent = panel;
|
||||
@@ -160,14 +165,13 @@ void init_taskbar_panel(void *p)
|
||||
panel->g_taskbar.area._draw_foreground = draw_taskbar;
|
||||
panel->g_taskbar.area._on_change_layout = on_change_taskbar;
|
||||
panel->g_taskbar.area.resize_needed = 1;
|
||||
panel->g_taskbar.area.on_screen = 1;
|
||||
panel->g_taskbar.area.on_screen = TRUE;
|
||||
if (panel_horizontal) {
|
||||
panel->g_taskbar.area.posy = panel->area.bg->border.width + panel->area.paddingy;
|
||||
panel->g_taskbar.area.height = panel->area.height - (2 * panel->g_taskbar.area.posy);
|
||||
panel->g_taskbar.area_name.posy = panel->g_taskbar.area.posy;
|
||||
panel->g_taskbar.area_name.height = panel->g_taskbar.area.height;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
panel->g_taskbar.area.posx = panel->area.bg->border.width + panel->area.paddingy;
|
||||
panel->g_taskbar.area.width = panel->area.width - (2 * panel->g_taskbar.area.posx);
|
||||
panel->g_taskbar.area_name.posx = panel->g_taskbar.area.posx;
|
||||
@@ -180,7 +184,7 @@ void init_taskbar_panel(void *p)
|
||||
panel->g_task.area._draw_foreground = draw_task;
|
||||
panel->g_task.area._on_change_layout = on_change_task;
|
||||
panel->g_task.area.resize_needed = 1;
|
||||
panel->g_task.area.on_screen = 1;
|
||||
panel->g_task.area.on_screen = TRUE;
|
||||
if ((panel->g_task.config_asb_mask & (1 << TASK_NORMAL)) == 0) {
|
||||
panel->g_task.alpha[TASK_NORMAL] = 100;
|
||||
panel->g_task.saturation[TASK_NORMAL] = 0;
|
||||
@@ -201,30 +205,42 @@ void init_taskbar_panel(void *p)
|
||||
panel->g_task.saturation[TASK_URGENT] = panel->g_task.saturation[TASK_ACTIVE];
|
||||
panel->g_task.brightness[TASK_URGENT] = panel->g_task.brightness[TASK_ACTIVE];
|
||||
}
|
||||
if ((panel->g_task.config_font_mask & (1<<TASK_NORMAL)) == 0) panel->g_task.font[TASK_NORMAL] = (Color){{0, 0, 0}, 0};
|
||||
if ((panel->g_task.config_font_mask & (1<<TASK_ACTIVE)) == 0) panel->g_task.font[TASK_ACTIVE] = panel->g_task.font[TASK_NORMAL];
|
||||
if ((panel->g_task.config_font_mask & (1<<TASK_ICONIFIED)) == 0) panel->g_task.font[TASK_ICONIFIED] = panel->g_task.font[TASK_NORMAL];
|
||||
if ((panel->g_task.config_font_mask & (1<<TASK_URGENT)) == 0) panel->g_task.font[TASK_URGENT] = panel->g_task.font[TASK_ACTIVE];
|
||||
if ((panel->g_task.config_background_mask & (1<<TASK_NORMAL)) == 0) panel->g_task.background[TASK_NORMAL] = &g_array_index(backgrounds, Background, 0);
|
||||
if ((panel->g_task.config_background_mask & (1<<TASK_ACTIVE)) == 0) panel->g_task.background[TASK_ACTIVE] = panel->g_task.background[TASK_NORMAL];
|
||||
if ((panel->g_task.config_background_mask & (1<<TASK_ICONIFIED)) == 0) panel->g_task.background[TASK_ICONIFIED] = panel->g_task.background[TASK_NORMAL];
|
||||
if ((panel->g_task.config_background_mask & (1<<TASK_URGENT)) == 0) panel->g_task.background[TASK_URGENT] = panel->g_task.background[TASK_ACTIVE];
|
||||
if ((panel->g_task.config_font_mask & (1 << TASK_NORMAL)) == 0)
|
||||
panel->g_task.font[TASK_NORMAL] = (Color){{0, 0, 0}, 0};
|
||||
if ((panel->g_task.config_font_mask & (1 << TASK_ACTIVE)) == 0)
|
||||
panel->g_task.font[TASK_ACTIVE] = panel->g_task.font[TASK_NORMAL];
|
||||
if ((panel->g_task.config_font_mask & (1 << TASK_ICONIFIED)) == 0)
|
||||
panel->g_task.font[TASK_ICONIFIED] = panel->g_task.font[TASK_NORMAL];
|
||||
if ((panel->g_task.config_font_mask & (1 << TASK_URGENT)) == 0)
|
||||
panel->g_task.font[TASK_URGENT] = panel->g_task.font[TASK_ACTIVE];
|
||||
if ((panel->g_task.config_background_mask & (1 << TASK_NORMAL)) == 0)
|
||||
panel->g_task.background[TASK_NORMAL] = &g_array_index(backgrounds, Background, 0);
|
||||
if ((panel->g_task.config_background_mask & (1 << TASK_ACTIVE)) == 0)
|
||||
panel->g_task.background[TASK_ACTIVE] = panel->g_task.background[TASK_NORMAL];
|
||||
if ((panel->g_task.config_background_mask & (1 << TASK_ICONIFIED)) == 0)
|
||||
panel->g_task.background[TASK_ICONIFIED] = panel->g_task.background[TASK_NORMAL];
|
||||
if ((panel->g_task.config_background_mask & (1 << TASK_URGENT)) == 0)
|
||||
panel->g_task.background[TASK_URGENT] = panel->g_task.background[TASK_ACTIVE];
|
||||
|
||||
if (panel_horizontal) {
|
||||
panel->g_task.area.posy = panel->g_taskbar.area.posy + panel->g_taskbar.background[TASKBAR_NORMAL]->border.width + panel->g_taskbar.area.paddingy;
|
||||
panel->g_task.area.posy = panel->g_taskbar.area.posy +
|
||||
panel->g_taskbar.background[TASKBAR_NORMAL]->border.width +
|
||||
panel->g_taskbar.area.paddingy;
|
||||
panel->g_task.area.height = panel->area.height - (2 * panel->g_task.area.posy);
|
||||
}
|
||||
else {
|
||||
panel->g_task.area.posx = panel->g_taskbar.area.posx + panel->g_taskbar.background[TASKBAR_NORMAL]->border.width + panel->g_taskbar.area.paddingy;
|
||||
} else {
|
||||
panel->g_task.area.posx = panel->g_taskbar.area.posx +
|
||||
panel->g_taskbar.background[TASKBAR_NORMAL]->border.width +
|
||||
panel->g_taskbar.area.paddingy;
|
||||
panel->g_task.area.width = panel->area.width - (2 * panel->g_task.area.posx);
|
||||
panel->g_task.area.height = panel->g_task.maximum_height;
|
||||
}
|
||||
|
||||
for (j = 0; j < TASK_STATE_COUNT; ++j) {
|
||||
if (panel->g_task.background[j] == 0)
|
||||
if (!panel->g_task.background[j])
|
||||
panel->g_task.background[j] = &g_array_index(backgrounds, Background, 0);
|
||||
if (panel->g_task.background[j]->border.radius > panel->g_task.area.height / 2) {
|
||||
printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n", j==0 ? "_" : j==1 ? "_active_" : j==2 ? "_iconified_" : "_urgent_");
|
||||
printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n",
|
||||
j == 0 ? "_" : j == 1 ? "_active_" : j == 2 ? "_iconified_" : "_urgent_");
|
||||
g_array_append_val(backgrounds, *panel->g_task.background[j]);
|
||||
panel->g_task.background[j] = &g_array_index(backgrounds, Background, backgrounds->len - 1);
|
||||
panel->g_task.background[j]->border.radius = panel->g_task.area.height / 2;
|
||||
@@ -233,7 +249,16 @@ void init_taskbar_panel(void *p)
|
||||
|
||||
// compute vertical position : text and icon
|
||||
int height_ink, height, width;
|
||||
get_text_size2(panel->g_task.font_desc, &height_ink, &height, &width, panel->area.height, panel->area.width, "TAjpg", 5, PANGO_WRAP_WORD_CHAR, PANGO_ELLIPSIZE_END);
|
||||
get_text_size2(panel->g_task.font_desc,
|
||||
&height_ink,
|
||||
&height,
|
||||
&width,
|
||||
panel->area.height,
|
||||
panel->area.width,
|
||||
"TAjpg",
|
||||
5,
|
||||
PANGO_WRAP_WORD_CHAR,
|
||||
PANGO_ELLIPSIZE_END);
|
||||
|
||||
if (!panel->g_task.maximum_width && panel_horizontal)
|
||||
panel->g_task.maximum_width = server.monitor[panel->monitor].width;
|
||||
@@ -247,28 +272,26 @@ void init_taskbar_panel(void *p)
|
||||
}
|
||||
// printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width);
|
||||
|
||||
Taskbar *tskbar;
|
||||
panel->nb_desktop = server.nb_desktop;
|
||||
panel->taskbar = calloc(server.nb_desktop, sizeof(Taskbar));
|
||||
for (j=0 ; j < panel->nb_desktop ; j++) {
|
||||
tskbar = &panel->taskbar[j];
|
||||
memcpy(&tskbar->area, &panel->g_taskbar.area, sizeof(Area));
|
||||
tskbar->desktop = j;
|
||||
Taskbar *taskbar;
|
||||
panel->num_desktops = server.num_desktops;
|
||||
panel->taskbar = calloc(server.num_desktops, sizeof(Taskbar));
|
||||
for (j = 0; j < panel->num_desktops; j++) {
|
||||
taskbar = &panel->taskbar[j];
|
||||
memcpy(&taskbar->area, &panel->g_taskbar.area, sizeof(Area));
|
||||
taskbar->desktop = j;
|
||||
if (j == server.desktop)
|
||||
tskbar->area.bg = panel->g_taskbar.background[TASKBAR_ACTIVE];
|
||||
taskbar->area.bg = panel->g_taskbar.background[TASKBAR_ACTIVE];
|
||||
else
|
||||
tskbar->area.bg = panel->g_taskbar.background[TASKBAR_NORMAL];
|
||||
taskbar->area.bg = panel->g_taskbar.background[TASKBAR_NORMAL];
|
||||
}
|
||||
init_taskbarname_panel(panel);
|
||||
}
|
||||
|
||||
|
||||
void taskbar_remove_task(gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
remove_task(task_get_task(*(Window *)key));
|
||||
}
|
||||
|
||||
|
||||
Task *task_get_task(Window win)
|
||||
{
|
||||
GPtrArray *task_group = task_get_tasks(win);
|
||||
@@ -278,7 +301,6 @@ Task *task_get_task (Window win)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
GPtrArray *task_get_tasks(Window win)
|
||||
{
|
||||
if (win_to_task_table && taskbar_enabled)
|
||||
@@ -287,15 +309,16 @@ GPtrArray* task_get_tasks(Window win)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void task_refresh_tasklist()
|
||||
{
|
||||
Window *win;
|
||||
int num_results, i;
|
||||
|
||||
if (!taskbar_enabled) return;
|
||||
if (!taskbar_enabled)
|
||||
return;
|
||||
win = server_get_property(server.root_win, server.atom._NET_CLIENT_LIST, XA_WINDOW, &num_results);
|
||||
if (!win) return;
|
||||
if (!win)
|
||||
return;
|
||||
|
||||
GList *win_list = g_hash_table_get_keys(win_to_task_table);
|
||||
GList *it;
|
||||
@@ -316,17 +339,15 @@ void task_refresh_tasklist ()
|
||||
XFree(win);
|
||||
}
|
||||
|
||||
|
||||
void draw_taskbar(void *obj, cairo_t *c)
|
||||
{
|
||||
Taskbar *taskbar = obj;
|
||||
Taskbar *taskbar = (Taskbar *)obj;
|
||||
int state = (taskbar->desktop == server.desktop) ? TASKBAR_ACTIVE : TASKBAR_NORMAL;
|
||||
|
||||
taskbar->state_pix[state] = taskbar->area.pix;
|
||||
}
|
||||
|
||||
|
||||
int resize_taskbar(void *obj)
|
||||
gboolean resize_taskbar(void *obj)
|
||||
{
|
||||
Taskbar *taskbar = (Taskbar *)obj;
|
||||
Panel *panel = (Panel *)taskbar->area.panel;
|
||||
@@ -338,94 +359,95 @@ int resize_taskbar(void *obj)
|
||||
|
||||
text_width = panel->g_task.maximum_width;
|
||||
GList *l = taskbar->area.children;
|
||||
if (taskbarname_enabled) l = l->next;
|
||||
if (taskbarname_enabled)
|
||||
l = l->next;
|
||||
for (; l != NULL; l = l->next) {
|
||||
if (((Task *)l->data)->area.on_screen) {
|
||||
text_width = ((Task *)l->data)->area.width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
taskbar->text_width = text_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingxlr;
|
||||
}
|
||||
else {
|
||||
taskbar->text_width =
|
||||
text_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingxlr;
|
||||
} else {
|
||||
relayout_with_constraint(&taskbar->area, panel->g_task.maximum_height);
|
||||
|
||||
taskbar->text_width = taskbar->area.width - (2 * panel->g_taskbar.area.paddingy) - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingxlr;
|
||||
taskbar->text_width = taskbar->area.width - (2 * panel->g_taskbar.area.paddingy) - panel->g_task.text_posx -
|
||||
panel->g_task.area.bg->border.width - panel->g_task.area.paddingxlr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void on_change_taskbar(void *obj)
|
||||
{
|
||||
Taskbar *tskbar = obj;
|
||||
Taskbar *taskbar = (Taskbar *)obj;
|
||||
int k;
|
||||
|
||||
// reset Pixmap when position/size changed
|
||||
for (k = 0; k < TASKBAR_STATE_COUNT; ++k) {
|
||||
if (tskbar->state_pix[k]) XFreePixmap(server.dsp, tskbar->state_pix[k]);
|
||||
tskbar->state_pix[k] = 0;
|
||||
if (taskbar->state_pix[k])
|
||||
XFreePixmap(server.dsp, taskbar->state_pix[k]);
|
||||
taskbar->state_pix[k] = 0;
|
||||
}
|
||||
tskbar->area.pix = 0;
|
||||
tskbar->area.redraw_needed = 1;
|
||||
taskbar->area.pix = 0;
|
||||
taskbar->area.redraw_needed = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void set_taskbar_state(Taskbar *tskbar, int state)
|
||||
void set_taskbar_state(Taskbar *taskbar, TaskbarState state)
|
||||
{
|
||||
tskbar->area.bg = panel1[0].g_taskbar.background[state];
|
||||
tskbar->area.pix = tskbar->state_pix[state];
|
||||
taskbar->area.bg = panels[0].g_taskbar.background[state];
|
||||
taskbar->area.pix = taskbar->state_pix[state];
|
||||
if (taskbarname_enabled) {
|
||||
tskbar->bar_name.area.bg = panel1[0].g_taskbar.background_name[state];
|
||||
taskbar->bar_name.area.bg = panels[0].g_taskbar.background_name[state];
|
||||
if (!panel_config.mouse_effects) {
|
||||
tskbar->bar_name.area.pix = tskbar->bar_name.state_pix[state];
|
||||
taskbar->bar_name.area.pix = taskbar->bar_name.state_pix[state];
|
||||
}
|
||||
}
|
||||
if (panel_mode != MULTI_DESKTOP) {
|
||||
if (taskbar_mode != MULTI_DESKTOP) {
|
||||
if (state == TASKBAR_NORMAL)
|
||||
tskbar->area.on_screen = 0;
|
||||
taskbar->area.on_screen = FALSE;
|
||||
else
|
||||
tskbar->area.on_screen = 1;
|
||||
taskbar->area.on_screen = TRUE;
|
||||
}
|
||||
if (tskbar->area.on_screen == 1) {
|
||||
if (tskbar->state_pix[state] == 0)
|
||||
tskbar->area.redraw_needed = 1;
|
||||
if (taskbar->area.on_screen) {
|
||||
if (!taskbar->state_pix[state])
|
||||
taskbar->area.redraw_needed = TRUE;
|
||||
if (taskbarname_enabled) {
|
||||
if (!panel_config.mouse_effects) {
|
||||
if (tskbar->bar_name.state_pix[state] == 0)
|
||||
tskbar->bar_name.area.redraw_needed = 1;
|
||||
if (!taskbar->bar_name.state_pix[state])
|
||||
taskbar->bar_name.area.redraw_needed = TRUE;
|
||||
} else {
|
||||
tskbar->bar_name.area.redraw_needed = 1;
|
||||
taskbar->bar_name.area.redraw_needed = TRUE;
|
||||
}
|
||||
}
|
||||
if (panel_mode == MULTI_DESKTOP && panel1[0].g_taskbar.background[TASKBAR_NORMAL] != panel1[0].g_taskbar.background[TASKBAR_ACTIVE]) {
|
||||
GList *l = tskbar->area.children;
|
||||
if (taskbarname_enabled) l = l->next;
|
||||
if (taskbar_mode == MULTI_DESKTOP &&
|
||||
panels[0].g_taskbar.background[TASKBAR_NORMAL] != panels[0].g_taskbar.background[TASKBAR_ACTIVE]) {
|
||||
GList *l = taskbar->area.children;
|
||||
if (taskbarname_enabled)
|
||||
l = l->next;
|
||||
for (; l; l = l->next)
|
||||
set_task_redraw(l->data);
|
||||
}
|
||||
}
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void visible_taskbar(void *p)
|
||||
{
|
||||
Panel *panel = (Panel *)p;
|
||||
int j;
|
||||
|
||||
Taskbar *taskbar;
|
||||
for (j=0 ; j < panel->nb_desktop ; j++) {
|
||||
for (j = 0; j < panel->num_desktops; j++) {
|
||||
taskbar = &panel->taskbar[j];
|
||||
if (panel_mode != MULTI_DESKTOP && taskbar->desktop != server.desktop) {
|
||||
if (taskbar_mode != MULTI_DESKTOP && taskbar->desktop != server.desktop) {
|
||||
// SINGLE_DESKTOP and not current desktop
|
||||
taskbar->area.on_screen = 0;
|
||||
}
|
||||
else {
|
||||
taskbar->area.on_screen = 1;
|
||||
taskbar->area.on_screen = FALSE;
|
||||
} else {
|
||||
taskbar->area.on_screen = TRUE;
|
||||
}
|
||||
}
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
|
||||
#define NONTRIVIAL 2
|
||||
@@ -444,9 +466,7 @@ gint compare_tasks_trivial(Task *a, Task *b, Taskbar *taskbar)
|
||||
|
||||
gint contained_within(Task *a, Task *b)
|
||||
{
|
||||
if ((a->win_x <= b->win_x) &&
|
||||
(a->win_y <= b->win_y) &&
|
||||
(a->win_x + a->win_w >= b->win_x + b->win_w) &&
|
||||
if ((a->win_x <= b->win_x) && (a->win_y <= b->win_y) && (a->win_x + a->win_w >= b->win_x + b->win_w) &&
|
||||
(a->win_y + a->win_h >= b->win_y + b->win_h)) {
|
||||
return 1;
|
||||
}
|
||||
@@ -461,10 +481,7 @@ gint compare_task_centers(Task *a, Task *b, Taskbar *taskbar)
|
||||
|
||||
// If a window has the same coordinates and size as the other,
|
||||
// they are considered to be equal in the comparison.
|
||||
if ((a->win_x == b->win_x) &&
|
||||
(a->win_y == b->win_y) &&
|
||||
(a->win_w == b->win_w) &&
|
||||
(a->win_h == b->win_h)) {
|
||||
if ((a->win_x == b->win_x) && (a->win_y == b->win_y) && (a->win_w == b->win_w) && (a->win_h == b->win_h)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -536,16 +553,15 @@ void sort_tasks(Taskbar *taskbar)
|
||||
{
|
||||
if (!taskbar)
|
||||
return;
|
||||
if (!taskbar_needs_sort(taskbar)) {
|
||||
if (!taskbar_needs_sort(taskbar))
|
||||
return;
|
||||
}
|
||||
|
||||
taskbar->area.children = g_list_sort_with_data(taskbar->area.children, (GCompareDataFunc)compare_tasks, taskbar);
|
||||
taskbar->area.resize_needed = 1;
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
((Panel *)taskbar->area.panel)->area.resize_needed = 1;
|
||||
}
|
||||
|
||||
|
||||
void sort_taskbar_for_win(Window win)
|
||||
{
|
||||
if (taskbar_sort_method == TASKBAR_NOSORT)
|
||||
@@ -554,17 +570,17 @@ void sort_taskbar_for_win(Window win)
|
||||
GPtrArray *task_group = task_get_tasks(win);
|
||||
if (task_group) {
|
||||
int i;
|
||||
Task* tsk0 = g_ptr_array_index(task_group, 0);
|
||||
if (tsk0) {
|
||||
window_get_coordinates(win, &tsk0->win_x, &tsk0->win_y, &tsk0->win_w, &tsk0->win_h);
|
||||
Task *task0 = g_ptr_array_index(task_group, 0);
|
||||
if (task0) {
|
||||
get_window_coordinates(win, &task0->win_x, &task0->win_y, &task0->win_w, &task0->win_h);
|
||||
}
|
||||
for (i = 0; i < task_group->len; ++i) {
|
||||
Task* tsk = g_ptr_array_index(task_group, i);
|
||||
tsk->win_x = tsk0->win_x;
|
||||
tsk->win_y = tsk0->win_y;
|
||||
tsk->win_w = tsk0->win_w;
|
||||
tsk->win_h = tsk0->win_h;
|
||||
sort_tasks(tsk->area.parent);
|
||||
Task *task = g_ptr_array_index(task_group, i);
|
||||
task->win_x = task0->win_x;
|
||||
task->win_y = task0->win_y;
|
||||
task->win_w = task0->win_w;
|
||||
task->win_h = task0->win_h;
|
||||
sort_tasks(task->area.parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,20 +11,29 @@
|
||||
#include "task.h"
|
||||
#include "taskbarname.h"
|
||||
|
||||
enum { TASKBAR_NORMAL, TASKBAR_ACTIVE, TASKBAR_STATE_COUNT };
|
||||
typedef enum TaskbarState {
|
||||
TASKBAR_NORMAL = 0,
|
||||
TASKBAR_ACTIVE,
|
||||
TASKBAR_STATE_COUNT,
|
||||
} TaskbarState;
|
||||
|
||||
typedef enum TaskbarSortMethod {
|
||||
TASKBAR_NOSORT = 0,
|
||||
TASKBAR_SORT_CENTER,
|
||||
TASKBAR_SORT_TITLE,
|
||||
} TaskbarSortMethod;
|
||||
|
||||
extern GHashTable *win_to_task_table;
|
||||
extern Task *task_active;
|
||||
extern Task *task_drag;
|
||||
extern int taskbar_enabled;
|
||||
extern int taskbar_distribute_size;
|
||||
extern int hide_inactive_tasks;
|
||||
extern int hide_task_diff_monitor;
|
||||
enum { TASKBAR_NOSORT, TASKBAR_SORT_CENTER, TASKBAR_SORT_TITLE };
|
||||
extern int taskbar_sort_method;
|
||||
extern int taskbar_alignment;
|
||||
extern gboolean taskbar_enabled;
|
||||
extern gboolean taskbar_distribute_size;
|
||||
extern gboolean hide_inactive_tasks;
|
||||
extern gboolean hide_task_diff_monitor;
|
||||
extern TaskbarSortMethod taskbar_sort_method;
|
||||
extern Alignment taskbar_alignment;
|
||||
|
||||
typedef struct {
|
||||
// always start with area
|
||||
Area area;
|
||||
Pixmap state_pix[TASKBAR_STATE_COUNT];
|
||||
|
||||
@@ -32,28 +41,21 @@ typedef struct {
|
||||
int posy;
|
||||
} Taskbarname;
|
||||
|
||||
// tint2 use one taskbar per desktop.
|
||||
typedef struct {
|
||||
// always start with area
|
||||
Area area;
|
||||
|
||||
int desktop;
|
||||
Pixmap state_pix[TASKBAR_STATE_COUNT];
|
||||
|
||||
int desktop;
|
||||
Taskbarname bar_name;
|
||||
|
||||
// task parameters
|
||||
int text_width;
|
||||
} Taskbar;
|
||||
|
||||
typedef struct {
|
||||
typedef struct GlobalTaskbar {
|
||||
// always start with area
|
||||
Area area;
|
||||
Area area_name;
|
||||
Background *background[TASKBAR_STATE_COUNT];
|
||||
Background *background_name[TASKBAR_STATE_COUNT];
|
||||
} Global_taskbar;
|
||||
|
||||
} GlobalTaskbar;
|
||||
|
||||
// default global data
|
||||
void default_taskbar();
|
||||
@@ -70,9 +72,9 @@ Task *task_get_task (Window win);
|
||||
GPtrArray *task_get_tasks(Window win);
|
||||
void task_refresh_tasklist();
|
||||
|
||||
int resize_taskbar(void *obj);
|
||||
gboolean resize_taskbar(void *obj);
|
||||
void on_change_taskbar(void *obj);
|
||||
void set_taskbar_state(Taskbar *tskbar, int state);
|
||||
void set_taskbar_state(Taskbar *taskbar, TaskbarState state);
|
||||
|
||||
// show/hide taskbar according to current desktop
|
||||
void visible_taskbar(void *p);
|
||||
@@ -81,4 +83,3 @@ void sort_taskbar_for_win(Window win);
|
||||
void sort_tasks(Taskbar *taskbar);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -37,18 +37,16 @@ PangoFontDescription *taskbarname_font_desc;
|
||||
Color taskbarname_font;
|
||||
Color taskbarname_active_font;
|
||||
|
||||
|
||||
void default_taskbarname()
|
||||
{
|
||||
taskbarname_enabled = 0;
|
||||
taskbarname_font_desc = NULL;
|
||||
}
|
||||
|
||||
|
||||
void init_taskbarname_panel(void *p)
|
||||
{
|
||||
Panel *panel = (Panel *)p;
|
||||
Taskbar *tskbar;
|
||||
Taskbar *taskbar;
|
||||
int j;
|
||||
|
||||
if (!taskbarname_enabled)
|
||||
@@ -57,28 +55,27 @@ void init_taskbarname_panel(void *p)
|
||||
if (!panel_config.taskbarname_font_desc)
|
||||
panel_config.taskbarname_font_desc = pango_font_description_from_string(DEFAULT_FONT);
|
||||
|
||||
GSList *l, *list = server_get_name_of_desktop();
|
||||
for (j=0, l=list ; j < panel->nb_desktop ; j++) {
|
||||
tskbar = &panel->taskbar[j];
|
||||
memcpy(&tskbar->bar_name.area, &panel->g_taskbar.area_name, sizeof(Area));
|
||||
tskbar->bar_name.area.parent = tskbar;
|
||||
tskbar->bar_name.area.has_mouse_over_effect = 1;
|
||||
tskbar->bar_name.area.has_mouse_press_effect = 1;
|
||||
GSList *l, *list = get_desktop_names();
|
||||
for (j = 0, l = list; j < panel->num_desktops; j++) {
|
||||
taskbar = &panel->taskbar[j];
|
||||
memcpy(&taskbar->bar_name.area, &panel->g_taskbar.area_name, sizeof(Area));
|
||||
taskbar->bar_name.area.parent = taskbar;
|
||||
taskbar->bar_name.area.has_mouse_over_effect = 1;
|
||||
taskbar->bar_name.area.has_mouse_press_effect = 1;
|
||||
if (j == server.desktop)
|
||||
tskbar->bar_name.area.bg = panel->g_taskbar.background_name[TASKBAR_ACTIVE];
|
||||
taskbar->bar_name.area.bg = panel->g_taskbar.background_name[TASKBAR_ACTIVE];
|
||||
else
|
||||
tskbar->bar_name.area.bg = panel->g_taskbar.background_name[TASKBAR_NORMAL];
|
||||
taskbar->bar_name.area.bg = panel->g_taskbar.background_name[TASKBAR_NORMAL];
|
||||
|
||||
// use desktop number if name is missing
|
||||
if (l) {
|
||||
tskbar->bar_name.name = g_strdup(l->data);
|
||||
taskbar->bar_name.name = g_strdup(l->data);
|
||||
l = l->next;
|
||||
}
|
||||
else
|
||||
tskbar->bar_name.name = g_strdup_printf("%d", j+1);
|
||||
} else
|
||||
taskbar->bar_name.name = g_strdup_printf("%d", j + 1);
|
||||
|
||||
// append the name at the beginning of taskbar
|
||||
tskbar->area.children = g_list_append(tskbar->area.children, &tskbar->bar_name);
|
||||
taskbar->area.children = g_list_append(taskbar->area.children, &taskbar->bar_name);
|
||||
}
|
||||
|
||||
for (l = list; l; l = l->next)
|
||||
@@ -86,31 +83,29 @@ void init_taskbarname_panel(void *p)
|
||||
g_slist_free(list);
|
||||
}
|
||||
|
||||
|
||||
void cleanup_taskbarname()
|
||||
{
|
||||
int i, j, k;
|
||||
Panel *panel;
|
||||
Taskbar *tskbar;
|
||||
Taskbar *taskbar;
|
||||
|
||||
for (i = 0; i < nb_panel; i++) {
|
||||
panel = &panel1[i];
|
||||
for (j = 0; j < panel->nb_desktop; j++) {
|
||||
tskbar = &panel->taskbar[j];
|
||||
g_free(tskbar->bar_name.name);
|
||||
tskbar->bar_name.name = NULL;
|
||||
free_area(&tskbar->bar_name.area);
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
panel = &panels[i];
|
||||
for (j = 0; j < panel->num_desktops; j++) {
|
||||
taskbar = &panel->taskbar[j];
|
||||
g_free(taskbar->bar_name.name);
|
||||
taskbar->bar_name.name = NULL;
|
||||
free_area(&taskbar->bar_name.area);
|
||||
for (k = 0; k < TASKBAR_STATE_COUNT; ++k) {
|
||||
if (tskbar->bar_name.state_pix[k])
|
||||
XFreePixmap(server.dsp, tskbar->bar_name.state_pix[k]);
|
||||
tskbar->bar_name.state_pix[k] = 0;
|
||||
if (taskbar->bar_name.state_pix[k])
|
||||
XFreePixmap(server.dsp, taskbar->bar_name.state_pix[k]);
|
||||
taskbar->bar_name.state_pix[k] = 0;
|
||||
}
|
||||
remove_area((Area*)&tskbar->bar_name);
|
||||
remove_area((Area *)&taskbar->bar_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw_taskbarname(void *obj, cairo_t *c)
|
||||
{
|
||||
Taskbarname *taskbar_name = obj;
|
||||
@@ -140,16 +135,22 @@ void draw_taskbarname (void *obj, cairo_t *c)
|
||||
// printf("draw_taskbarname %s ******************************\n", taskbar_name->name);
|
||||
}
|
||||
|
||||
|
||||
int resize_taskbarname(void *obj)
|
||||
gboolean resize_taskbarname(void *obj)
|
||||
{
|
||||
Taskbarname *taskbar_name = obj;
|
||||
Panel *panel = taskbar_name->area.panel;
|
||||
int name_height, name_width, name_height_ink;
|
||||
int ret = 0;
|
||||
|
||||
taskbar_name->area.redraw_needed = 1;
|
||||
get_text_size2(panel_config.taskbarname_font_desc, &name_height_ink, &name_height, &name_width, panel->area.height, panel->area.width, taskbar_name->name, strlen(taskbar_name->name),
|
||||
taskbar_name->area.redraw_needed = TRUE;
|
||||
get_text_size2(panel_config.taskbarname_font_desc,
|
||||
&name_height_ink,
|
||||
&name_height,
|
||||
&name_width,
|
||||
panel->area.height,
|
||||
panel->area.width,
|
||||
taskbar_name->name,
|
||||
strlen(taskbar_name->name),
|
||||
PANGO_WRAP_WORD_CHAR,
|
||||
PANGO_ELLIPSIZE_NONE);
|
||||
|
||||
@@ -160,8 +161,7 @@ int resize_taskbarname(void *obj)
|
||||
taskbar_name->posy = (taskbar_name->area.height - name_height) / 2;
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
int new_size = name_height + (2 * (taskbar_name->area.paddingxlr + taskbar_name->area.bg->border.width));
|
||||
if (new_size != taskbar_name->area.height) {
|
||||
taskbar_name->area.height = new_size;
|
||||
@@ -171,4 +171,3 @@ int resize_taskbarname(void *obj)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "common.h"
|
||||
#include "area.h"
|
||||
|
||||
extern int taskbarname_enabled;
|
||||
extern gboolean taskbarname_enabled;
|
||||
extern Color taskbarname_font;
|
||||
extern Color taskbarname_active_font;
|
||||
|
||||
@@ -19,8 +19,6 @@ void init_taskbarname_panel(void *p);
|
||||
|
||||
void draw_taskbarname(void *obj, cairo_t *c);
|
||||
|
||||
int resize_taskbarname(void *obj);
|
||||
|
||||
gboolean resize_taskbarname(void *obj);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
569
src/tint.c
569
src/tint.c
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,6 @@ void stop_tooltip_timeout();
|
||||
|
||||
Tooltip g_tooltip;
|
||||
|
||||
|
||||
void default_tooltip()
|
||||
{
|
||||
// give the tooltip some reasonable default values
|
||||
@@ -62,12 +61,11 @@ void cleanup_tooltip()
|
||||
g_tooltip.font_desc = NULL;
|
||||
}
|
||||
|
||||
|
||||
void init_tooltip()
|
||||
{
|
||||
if (!g_tooltip.font_desc)
|
||||
g_tooltip.font_desc = pango_font_description_from_string(DEFAULT_FONT);
|
||||
if (g_tooltip.bg == 0)
|
||||
if (!g_tooltip.bg)
|
||||
g_tooltip.bg = &g_array_index(backgrounds, Background, 0);
|
||||
|
||||
XSetWindowAttributes attr;
|
||||
@@ -79,10 +77,10 @@ void init_tooltip()
|
||||
unsigned long mask = CWEventMask | CWColormap | CWBorderPixel | CWBackPixel | CWOverrideRedirect;
|
||||
if (g_tooltip.window)
|
||||
XDestroyWindow(server.dsp, g_tooltip.window);
|
||||
g_tooltip.window = XCreateWindow(server.dsp, server.root_win, 0, 0, 100, 20, 0, server.depth, InputOutput, server.visual, mask, &attr);
|
||||
g_tooltip.window =
|
||||
XCreateWindow(server.dsp, server.root_win, 0, 0, 100, 20, 0, server.depth, InputOutput, server.visual, mask, &attr);
|
||||
}
|
||||
|
||||
|
||||
void tooltip_trigger_show(Area *area, Panel *p, XEvent *e)
|
||||
{
|
||||
// Position the tooltip in the center of the area
|
||||
@@ -94,13 +92,11 @@ void tooltip_trigger_show(Area* area, Panel* p, XEvent *e)
|
||||
tooltip_copy_text(area);
|
||||
tooltip_update();
|
||||
stop_tooltip_timeout();
|
||||
}
|
||||
else if (!g_tooltip.mapped) {
|
||||
} else if (!g_tooltip.mapped) {
|
||||
start_show_timeout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tooltip_show(void *arg)
|
||||
{
|
||||
int mx, my;
|
||||
@@ -117,7 +113,6 @@ void tooltip_show(void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tooltip_update_geometry()
|
||||
{
|
||||
cairo_surface_t *cs;
|
||||
@@ -148,7 +143,6 @@ void tooltip_update_geometry()
|
||||
cairo_surface_destroy(cs);
|
||||
}
|
||||
|
||||
|
||||
void tooltip_adjust_geometry()
|
||||
{
|
||||
// adjust coordinates and size to not go offscreen
|
||||
@@ -158,7 +152,8 @@ void tooltip_adjust_geometry()
|
||||
Panel *panel = g_tooltip.panel;
|
||||
int screen_width = server.monitor[panel->monitor].x + server.monitor[panel->monitor].width;
|
||||
int screen_height = server.monitor[panel->monitor].y + server.monitor[panel->monitor].height;
|
||||
if ( x+width <= screen_width && y+height <= screen_height && x>=server.monitor[panel->monitor].x && y>=server.monitor[panel->monitor].y )
|
||||
if (x + width <= screen_width && y + height <= screen_height && x >= server.monitor[panel->monitor].x &&
|
||||
y >= server.monitor[panel->monitor].y)
|
||||
return; // no adjustment needed
|
||||
|
||||
if (panel_horizontal) {
|
||||
@@ -169,8 +164,7 @@ void tooltip_adjust_geometry()
|
||||
min_y = 0;
|
||||
else
|
||||
min_y = panel->area.height;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
max_width = server.monitor[panel->monitor].width - panel->area.width;
|
||||
min_y = 0;
|
||||
max_height = server.monitor[panel->monitor].height;
|
||||
@@ -223,8 +217,7 @@ void tooltip_update()
|
||||
clear_pixmap(g_tooltip.window, 0, 0, width, height);
|
||||
draw_rect(c, b.width, b.width, width - 2 * b.width, height - 2 * b.width, b.radius - b.width / 1.571);
|
||||
cairo_set_source_rgba(c, bc.rgb[0], bc.rgb[1], bc.rgb[2], bc.alpha);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
cairo_rectangle(c, 0., 0, width, height);
|
||||
cairo_set_source_rgb(c, bc.rgb[0], bc.rgb[1], bc.rgb[2]);
|
||||
}
|
||||
@@ -247,7 +240,8 @@ void tooltip_update()
|
||||
pango_layout_set_width(layout, width * PANGO_SCALE);
|
||||
pango_layout_set_height(layout, height * PANGO_SCALE);
|
||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
|
||||
// I do not know why this is the right way, but with the below cairo_move_to it seems to be centered (horiz. and vert.)
|
||||
// I do not know why this is the right way, but with the below cairo_move_to it seems to be centered (horiz. and
|
||||
// vert.)
|
||||
cairo_move_to(c,
|
||||
-r1.x / 2 + g_tooltip.bg->border.width + g_tooltip.paddingx,
|
||||
-r1.y / 2 + 1 + g_tooltip.bg->border.width + g_tooltip.paddingy);
|
||||
@@ -258,20 +252,17 @@ void tooltip_update()
|
||||
cairo_surface_destroy(cs);
|
||||
}
|
||||
|
||||
|
||||
void tooltip_trigger_hide()
|
||||
{
|
||||
if (g_tooltip.mapped) {
|
||||
tooltip_copy_text(0);
|
||||
start_hide_timeout();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// tooltip not visible yet, but maybe a timeout is still pending
|
||||
stop_tooltip_timeout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tooltip_hide(void *arg)
|
||||
{
|
||||
if (g_tooltip.mapped) {
|
||||
@@ -281,25 +272,21 @@ void tooltip_hide(void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void start_show_timeout()
|
||||
{
|
||||
change_timeout(&g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
|
||||
}
|
||||
|
||||
|
||||
void start_hide_timeout()
|
||||
{
|
||||
change_timeout(&g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
|
||||
}
|
||||
|
||||
|
||||
void stop_tooltip_timeout()
|
||||
{
|
||||
stop_timeout(g_tooltip.timeout);
|
||||
}
|
||||
|
||||
|
||||
void tooltip_copy_text(Area *area)
|
||||
{
|
||||
free(g_tooltip.tooltip_text);
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "panel.h"
|
||||
#include "timer.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
Area *area; // never ever use the area attribut if you are not 100% sure that this area was not freed
|
||||
char *tooltip_text;
|
||||
@@ -41,7 +40,6 @@ typedef struct {
|
||||
|
||||
extern Tooltip g_tooltip;
|
||||
|
||||
|
||||
// default global data
|
||||
void default_tooltip();
|
||||
|
||||
|
||||
242
src/util/area.c
242
src/util/area.c
@@ -32,23 +32,24 @@
|
||||
|
||||
Area *mouse_over_area = NULL;
|
||||
|
||||
void initialize_positions(void *obj, int pos)
|
||||
void init_background(Background *bg)
|
||||
{
|
||||
memset(bg, 0, sizeof(Background));
|
||||
}
|
||||
|
||||
void initialize_positions(void *obj, int offset)
|
||||
{
|
||||
Area *a = (Area *)obj;
|
||||
|
||||
// initialize fixed position/size
|
||||
GList *l;
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (panel_horizontal) {
|
||||
child->posy = pos + a->bg->border.width + a->paddingy;
|
||||
child->posy = offset + a->bg->border.width + a->paddingy;
|
||||
child->height = a->height - (2 * (a->bg->border.width + a->paddingy));
|
||||
if (child->_on_change_layout)
|
||||
child->_on_change_layout(child);
|
||||
initialize_positions(child, child->posy);
|
||||
}
|
||||
else {
|
||||
child->posx = pos + a->bg->border.width + a->paddingy;
|
||||
} else {
|
||||
child->posx = offset + a->bg->border.width + a->paddingy;
|
||||
child->width = a->width - (2 * (a->bg->border.width + a->paddingy));
|
||||
if (child->_on_change_layout)
|
||||
child->_on_change_layout(child);
|
||||
@@ -57,8 +58,7 @@ void initialize_positions(void *obj, int pos)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _relayout_fixed(Area *a)
|
||||
void relayout_fixed(Area *a)
|
||||
{
|
||||
if (!a->on_screen)
|
||||
return;
|
||||
@@ -66,7 +66,7 @@ void _relayout_fixed(Area *a)
|
||||
// Children are resized before the parent
|
||||
GList *l;
|
||||
for (l = a->children; l; l = l->next)
|
||||
_relayout_fixed(l->data);
|
||||
relayout_fixed(l->data);
|
||||
|
||||
// Recalculate size
|
||||
a->_changed = 0;
|
||||
@@ -84,23 +84,19 @@ void _relayout_fixed(Area *a)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _relayout_dynamic(Area *a, int level)
|
||||
void relayout_dynamic(Area *a, int level)
|
||||
{
|
||||
// don't resize hiden objects
|
||||
if (!a->on_screen)
|
||||
return;
|
||||
|
||||
// parent node is resized before its children
|
||||
// calculate area's size
|
||||
GList *l;
|
||||
// Area is resized before its children
|
||||
if (a->resize_needed && a->size_mode == LAYOUT_DYNAMIC) {
|
||||
a->resize_needed = 0;
|
||||
|
||||
if (a->_resize) {
|
||||
a->_resize(a);
|
||||
// resize children with LAYOUT_DYNAMIC
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (child->size_mode == LAYOUT_DYNAMIC && child->children)
|
||||
child->resize_needed = 1;
|
||||
@@ -108,12 +104,12 @@ void _relayout_dynamic(Area *a, int level)
|
||||
}
|
||||
}
|
||||
|
||||
// update position of children
|
||||
// Layout children
|
||||
if (a->children) {
|
||||
if (a->alignment == ALIGN_LEFT) {
|
||||
int pos = (panel_horizontal ? a->posx : a->posy) + a->bg->border.width + a->paddingxlr;
|
||||
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (!child->on_screen)
|
||||
continue;
|
||||
@@ -132,14 +128,14 @@ void _relayout_dynamic(Area *a, int level)
|
||||
}
|
||||
}
|
||||
|
||||
_relayout_dynamic(child, level+1);
|
||||
relayout_dynamic(child, level + 1);
|
||||
|
||||
pos += panel_horizontal ? child->width + a->paddingx : child->height + a->paddingx;
|
||||
}
|
||||
} else if (a->alignment == ALIGN_RIGHT) {
|
||||
int pos = (panel_horizontal ? a->posx + a->width : a->posy + a->height) - a->bg->border.width - a->paddingxlr;
|
||||
|
||||
for (l = g_list_last(a->children); l ; l = l->prev) {
|
||||
for (GList *l = g_list_last(a->children); l; l = l->prev) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (!child->on_screen)
|
||||
continue;
|
||||
@@ -160,7 +156,7 @@ void _relayout_dynamic(Area *a, int level)
|
||||
}
|
||||
}
|
||||
|
||||
_relayout_dynamic(child, level+1);
|
||||
relayout_dynamic(child, level + 1);
|
||||
|
||||
pos -= a->paddingx;
|
||||
}
|
||||
@@ -168,7 +164,7 @@ void _relayout_dynamic(Area *a, int level)
|
||||
|
||||
int children_size = 0;
|
||||
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (!child->on_screen)
|
||||
continue;
|
||||
@@ -180,7 +176,7 @@ void _relayout_dynamic(Area *a, int level)
|
||||
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->children; l ; l = l->next) {
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (!child->on_screen)
|
||||
continue;
|
||||
@@ -199,7 +195,7 @@ void _relayout_dynamic(Area *a, int level)
|
||||
}
|
||||
}
|
||||
|
||||
_relayout_dynamic(child, level+1);
|
||||
relayout_dynamic(child, level + 1);
|
||||
|
||||
pos += panel_horizontal ? child->width + a->paddingx : child->height + a->paddingx;
|
||||
}
|
||||
@@ -208,79 +204,71 @@ void _relayout_dynamic(Area *a, int level)
|
||||
|
||||
if (a->_changed) {
|
||||
// pos/size changed
|
||||
a->redraw_needed = 1;
|
||||
a->redraw_needed = TRUE;
|
||||
if (a->_on_change_layout)
|
||||
a->_on_change_layout(a);
|
||||
}
|
||||
}
|
||||
|
||||
void relayout(Area *a)
|
||||
{
|
||||
relayout_fixed(a);
|
||||
relayout_dynamic(a, 1);
|
||||
}
|
||||
|
||||
void draw_tree(Area *a)
|
||||
{
|
||||
if (!a->on_screen)
|
||||
return;
|
||||
|
||||
// don't draw transparent objects (without foreground and without background)
|
||||
if (a->redraw_needed) {
|
||||
a->redraw_needed = 0;
|
||||
// force redraw of child
|
||||
//GList *l;
|
||||
//for (l = a->children ; l ; l = l->next)
|
||||
//((Area*)l->data)->redraw_needed = 1;
|
||||
|
||||
//printf("draw area posx %d, width %d\n", a->posx, a->width);
|
||||
draw(a);
|
||||
}
|
||||
|
||||
// draw current Area
|
||||
if (a->pix == 0)
|
||||
printf("empty area posx %d, width %d\n", a->posx, a->width);
|
||||
if (a->pix)
|
||||
XCopyArea(server.dsp, a->pix, ((Panel *)a->panel)->temp_pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
|
||||
|
||||
// and then draw child objects
|
||||
GList *l;
|
||||
for (l = a->children; l ; l = l->next)
|
||||
for (GList *l = a->children; l; l = l->next)
|
||||
draw_tree((Area *)l->data);
|
||||
}
|
||||
|
||||
|
||||
int relayout_with_constraint(Area *a, int maximum_size)
|
||||
{
|
||||
Area *child;
|
||||
int size, nb_by_content=0, nb_by_layout=0;
|
||||
int fixed_children_count = 0;
|
||||
int dynamic_children_count = 0;
|
||||
|
||||
if (panel_horizontal) {
|
||||
// detect free size for LAYOUT_DYNAMIC's Area
|
||||
size = a->width - (2 * (a->paddingxlr + a->bg->border.width));
|
||||
GList *l;
|
||||
for (l = a->children ; l ; l = l->next) {
|
||||
child = (Area*)l->data;
|
||||
// detect free size for LAYOUT_DYNAMIC Areas
|
||||
int size = a->width - (2 * (a->paddingxlr + a->bg->border.width));
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = (Area *)l->data;
|
||||
if (child->on_screen && child->size_mode == LAYOUT_FIXED) {
|
||||
size -= child->width;
|
||||
nb_by_content++;
|
||||
fixed_children_count++;
|
||||
}
|
||||
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC)
|
||||
nb_by_layout++;
|
||||
dynamic_children_count++;
|
||||
}
|
||||
//printf(" resize_by_layout Deb %d, %d\n", nb_by_content, nb_by_layout);
|
||||
if (nb_by_content+nb_by_layout)
|
||||
size -= ((nb_by_content+nb_by_layout-1) * a->paddingx);
|
||||
if (fixed_children_count + dynamic_children_count > 0)
|
||||
size -= (fixed_children_count + dynamic_children_count - 1) * a->paddingx;
|
||||
|
||||
int width=0, modulo=0, old_width;
|
||||
if (nb_by_layout) {
|
||||
width = size / nb_by_layout;
|
||||
modulo = size % nb_by_layout;
|
||||
if (width > maximum_size && maximum_size != 0) {
|
||||
int width = 0;
|
||||
int modulo = 0;
|
||||
if (dynamic_children_count > 0) {
|
||||
width = size / dynamic_children_count;
|
||||
modulo = size % dynamic_children_count;
|
||||
if (width > maximum_size && maximum_size > 0) {
|
||||
width = maximum_size;
|
||||
modulo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// resize LAYOUT_DYNAMIC objects
|
||||
for (l = a->children ; l ; l = l->next) {
|
||||
child = (Area*)l->data;
|
||||
// Resize LAYOUT_DYNAMIC objects
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = (Area *)l->data;
|
||||
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC) {
|
||||
old_width = child->width;
|
||||
int old_width = child->width;
|
||||
child->width = width;
|
||||
if (modulo) {
|
||||
child->width++;
|
||||
@@ -290,36 +278,35 @@ int relayout_with_constraint(Area *a, int maximum_size)
|
||||
child->_changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// detect free size for LAYOUT_DYNAMIC's Area
|
||||
size = a->height - (2 * (a->paddingxlr + a->bg->border.width));
|
||||
GList *l;
|
||||
for (l = a->children ; l ; l = l->next) {
|
||||
child = (Area*)l->data;
|
||||
int size = a->height - (2 * (a->paddingxlr + a->bg->border.width));
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = (Area *)l->data;
|
||||
if (child->on_screen && child->size_mode == LAYOUT_FIXED) {
|
||||
size -= child->height;
|
||||
nb_by_content++;
|
||||
fixed_children_count++;
|
||||
}
|
||||
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC)
|
||||
nb_by_layout++;
|
||||
dynamic_children_count++;
|
||||
}
|
||||
if (nb_by_content+nb_by_layout)
|
||||
size -= ((nb_by_content+nb_by_layout-1) * a->paddingx);
|
||||
if (fixed_children_count + dynamic_children_count > 0)
|
||||
size -= (fixed_children_count + dynamic_children_count - 1) * a->paddingx;
|
||||
|
||||
int height=0, modulo=0;
|
||||
if (nb_by_layout) {
|
||||
height = size / nb_by_layout;
|
||||
modulo = size % nb_by_layout;
|
||||
int height = 0;
|
||||
int modulo = 0;
|
||||
if (dynamic_children_count) {
|
||||
height = size / dynamic_children_count;
|
||||
modulo = size % dynamic_children_count;
|
||||
if (height > maximum_size && maximum_size != 0) {
|
||||
height = maximum_size;
|
||||
modulo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// resize LAYOUT_DYNAMIC objects
|
||||
for (l = a->children ; l ; l = l->next) {
|
||||
child = (Area*)l->data;
|
||||
// Resize LAYOUT_DYNAMIC objects
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = (Area *)l->data;
|
||||
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC) {
|
||||
int old_height = child->height;
|
||||
child->height = height;
|
||||
@@ -335,13 +322,11 @@ int relayout_with_constraint(Area *a, int maximum_size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void schedule_redraw(Area *a)
|
||||
{
|
||||
a->redraw_needed = 1;
|
||||
a->redraw_needed = TRUE;
|
||||
|
||||
GList *l;
|
||||
for (l = a->children ; l ; l = l->next)
|
||||
for (GList *l = a->children; l; l = l->next)
|
||||
schedule_redraw((Area *)l->data);
|
||||
}
|
||||
|
||||
@@ -349,7 +334,7 @@ void hide(Area *a)
|
||||
{
|
||||
Area *parent = (Area *)a->parent;
|
||||
|
||||
a->on_screen = 0;
|
||||
a->on_screen = FALSE;
|
||||
if (parent)
|
||||
parent->resize_needed = 1;
|
||||
if (panel_horizontal)
|
||||
@@ -362,7 +347,7 @@ void show(Area *a)
|
||||
{
|
||||
Area *parent = (Area *)a->parent;
|
||||
|
||||
a->on_screen = 1;
|
||||
a->on_screen = TRUE;
|
||||
if (parent)
|
||||
parent->resize_needed = 1;
|
||||
a->resize_needed = 1;
|
||||
@@ -374,16 +359,13 @@ void draw(Area *a)
|
||||
XFreePixmap(server.dsp, a->pix);
|
||||
a->pix = XCreatePixmap(server.dsp, server.root_win, a->width, a->height, server.depth);
|
||||
|
||||
// add layer of root pixmap (or clear pixmap if real_transparency==true)
|
||||
// Add layer of root pixmap (or clear pixmap if real_transparency==true)
|
||||
if (server.real_transparency)
|
||||
clear_pixmap(a->pix, 0, 0, a->width, a->height);
|
||||
XCopyArea(server.dsp, ((Panel *)a->panel)->temp_pmap, a->pix, server.gc, a->posx, a->posy, a->width, a->height, 0, 0);
|
||||
|
||||
cairo_surface_t *cs;
|
||||
cairo_t *c;
|
||||
|
||||
cs = cairo_xlib_surface_create (server.dsp, a->pix, server.visual, a->width, a->height);
|
||||
c = cairo_create (cs);
|
||||
cairo_surface_t *cs = cairo_xlib_surface_create(server.dsp, a->pix, server.visual, a->width, a->height);
|
||||
cairo_t *c = cairo_create(cs);
|
||||
|
||||
draw_background(a, c);
|
||||
|
||||
@@ -394,19 +376,34 @@ void draw(Area *a)
|
||||
cairo_surface_destroy(cs);
|
||||
}
|
||||
|
||||
|
||||
void draw_background(Area *a, cairo_t *c)
|
||||
{
|
||||
if (a->bg->fill_color.alpha > 0.0 ||
|
||||
(panel_config.mouse_effects && (a->has_mouse_over_effect || a->has_mouse_press_effect))) {
|
||||
//printf(" draw_background (%d %d) RGBA (%lf, %lf, %lf, %lf)\n", a->posx, a->posy, pix->fill_color.rgb[0], pix->fill_color.rgb[1], pix->fill_color.rgb[2], pix->fill_color.alpha);
|
||||
if (a->mouse_state == MOUSE_OVER)
|
||||
cairo_set_source_rgba(c, a->bg->fill_color_hover.rgb[0], a->bg->fill_color_hover.rgb[1], a->bg->fill_color_hover.rgb[2], a->bg->fill_color_hover.alpha);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->fill_color_hover.rgb[0],
|
||||
a->bg->fill_color_hover.rgb[1],
|
||||
a->bg->fill_color_hover.rgb[2],
|
||||
a->bg->fill_color_hover.alpha);
|
||||
else if (a->mouse_state == MOUSE_DOWN)
|
||||
cairo_set_source_rgba(c, a->bg->fill_color_pressed.rgb[0], a->bg->fill_color_pressed.rgb[1], a->bg->fill_color_pressed.rgb[2], a->bg->fill_color_pressed.alpha);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->fill_color_pressed.rgb[0],
|
||||
a->bg->fill_color_pressed.rgb[1],
|
||||
a->bg->fill_color_pressed.rgb[2],
|
||||
a->bg->fill_color_pressed.alpha);
|
||||
else
|
||||
cairo_set_source_rgba(c, a->bg->fill_color.rgb[0], a->bg->fill_color.rgb[1], a->bg->fill_color.rgb[2], a->bg->fill_color.alpha);
|
||||
draw_rect(c, a->bg->border.width, a->bg->border.width, a->width-(2.0 * a->bg->border.width), a->height-(2.0*a->bg->border.width), a->bg->border.radius - a->bg->border.width/1.571);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->fill_color.rgb[0],
|
||||
a->bg->fill_color.rgb[1],
|
||||
a->bg->fill_color.rgb[2],
|
||||
a->bg->fill_color.alpha);
|
||||
draw_rect(c,
|
||||
a->bg->border.width,
|
||||
a->bg->border.width,
|
||||
a->width - (2.0 * a->bg->border.width),
|
||||
a->height - (2.0 * a->bg->border.width),
|
||||
a->bg->border.radius - a->bg->border.width / 1.571);
|
||||
cairo_fill(c);
|
||||
}
|
||||
|
||||
@@ -415,18 +412,34 @@ void draw_background (Area *a, cairo_t *c)
|
||||
|
||||
// draw border inside (x, y, width, height)
|
||||
if (a->mouse_state == MOUSE_OVER)
|
||||
cairo_set_source_rgba(c, a->bg->border_color_hover.rgb[0], a->bg->border_color_hover.rgb[1], a->bg->border_color_hover.rgb[2], a->bg->border_color_hover.alpha);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->border_color_hover.rgb[0],
|
||||
a->bg->border_color_hover.rgb[1],
|
||||
a->bg->border_color_hover.rgb[2],
|
||||
a->bg->border_color_hover.alpha);
|
||||
else if (a->mouse_state == MOUSE_DOWN)
|
||||
cairo_set_source_rgba(c, a->bg->border_color_pressed.rgb[0], a->bg->border_color_pressed.rgb[1], a->bg->border_color_pressed.rgb[2], a->bg->border_color_pressed.alpha);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->border_color_pressed.rgb[0],
|
||||
a->bg->border_color_pressed.rgb[1],
|
||||
a->bg->border_color_pressed.rgb[2],
|
||||
a->bg->border_color_pressed.alpha);
|
||||
else
|
||||
cairo_set_source_rgba(c, a->bg->border.color.rgb[0], a->bg->border.color.rgb[1], a->bg->border.color.rgb[2], a->bg->border.color.alpha);
|
||||
draw_rect(c, a->bg->border.width/2.0, a->bg->border.width/2.0, a->width - a->bg->border.width, a->height - a->bg->border.width, a->bg->border.radius);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->border.color.rgb[0],
|
||||
a->bg->border.color.rgb[1],
|
||||
a->bg->border.color.rgb[2],
|
||||
a->bg->border.color.alpha);
|
||||
draw_rect(c,
|
||||
a->bg->border.width / 2.0,
|
||||
a->bg->border.width / 2.0,
|
||||
a->width - a->bg->border.width,
|
||||
a->height - a->bg->border.width,
|
||||
a->bg->border.radius);
|
||||
|
||||
cairo_stroke(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void remove_area(Area *a)
|
||||
{
|
||||
Area *area = (Area *)a;
|
||||
@@ -443,7 +456,6 @@ void remove_area(Area *a)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void add_area(Area *a, Area *parent)
|
||||
{
|
||||
g_assert_null(a->parent);
|
||||
@@ -455,15 +467,13 @@ void add_area(Area *a, Area *parent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void free_area(Area *a)
|
||||
{
|
||||
if (!a)
|
||||
return;
|
||||
|
||||
GList *l0;
|
||||
for (l0 = a->children; l0 ; l0 = l0->next)
|
||||
free_area (l0->data);
|
||||
for (GList *l = a->children; l; l = l->next)
|
||||
free_area(l->data);
|
||||
|
||||
if (a->children) {
|
||||
g_list_free(a->children);
|
||||
@@ -478,7 +488,6 @@ void free_area (Area *a)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mouse_over(Area *area, int pressed)
|
||||
{
|
||||
if (mouse_over_area == area && !area)
|
||||
@@ -506,7 +515,7 @@ void mouse_over(Area *area, int pressed)
|
||||
|
||||
mouse_over_area->mouse_state = new_state;
|
||||
schedule_redraw(mouse_over_area);
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
|
||||
void mouse_out()
|
||||
@@ -515,17 +524,6 @@ void mouse_out()
|
||||
return;
|
||||
mouse_over_area->mouse_state = MOUSE_NORMAL;
|
||||
schedule_redraw(mouse_over_area);
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
mouse_over_area = NULL;
|
||||
}
|
||||
|
||||
void init_background(Background *bg)
|
||||
{
|
||||
memset(bg, 0, sizeof(Background));
|
||||
}
|
||||
|
||||
void relayout(Area *a)
|
||||
{
|
||||
_relayout_fixed(a);
|
||||
_relayout_dynamic(a, 1);
|
||||
}
|
||||
|
||||
@@ -147,21 +147,23 @@ typedef struct Background {
|
||||
|
||||
typedef enum Layout {
|
||||
LAYOUT_DYNAMIC,
|
||||
LAYOUT_FIXED
|
||||
LAYOUT_FIXED,
|
||||
} Layout;
|
||||
|
||||
typedef enum Alignment {
|
||||
ALIGN_LEFT = 0,
|
||||
ALIGN_CENTER = 1,
|
||||
ALIGN_RIGHT = 2
|
||||
ALIGN_RIGHT = 2,
|
||||
} Alignment;
|
||||
|
||||
typedef enum MouseState {
|
||||
MOUSE_NORMAL = 0,
|
||||
MOUSE_OVER = 1,
|
||||
MOUSE_DOWN = 2
|
||||
MOUSE_DOWN = 2,
|
||||
} MouseState;
|
||||
|
||||
struct Panel;
|
||||
|
||||
typedef struct Area {
|
||||
// Position relative to the panel window
|
||||
int posx, posy;
|
||||
@@ -202,7 +204,7 @@ typedef struct Area {
|
||||
|
||||
// Called on resize, obj = pointer to the Area
|
||||
// Returns 1 if the new size is different than the previous size.
|
||||
int (*_resize)(void *obj);
|
||||
gboolean (*_resize)(void *obj);
|
||||
|
||||
// Implemented only to override the default layout algorithm for this widget.
|
||||
// For example, if this widget is a cell in a table, its position and size should be computed here.
|
||||
@@ -213,7 +215,6 @@ typedef struct Area {
|
||||
char *(*_get_tooltip_text)(void *obj);
|
||||
} Area;
|
||||
|
||||
|
||||
// Initializes the Background member to default values.
|
||||
void init_background(Background *bg);
|
||||
|
||||
@@ -222,10 +223,12 @@ void init_background(Background *bg);
|
||||
// Called on startup to initialize the positions of all Areas in the Area tree.
|
||||
// Parameters:
|
||||
// * obj: pointer to Area
|
||||
// * pos: offset in pixels from left/top
|
||||
void initialize_positions(void *obj, int pos);
|
||||
// * offset: offset in pixels from left/top, relative to the window
|
||||
void initialize_positions(void *obj, int offset);
|
||||
|
||||
// Relayouts the Area and its children. Normally called on the root of the tree (i.e. the Panel).
|
||||
void relayout(Area *a);
|
||||
|
||||
// Distributes the Area's size to its children, repositioning them as needed.
|
||||
// If maximum_size > 0, it is an upper limit for the child size.
|
||||
int relayout_with_constraint(Area *a, int maximum_size);
|
||||
@@ -234,15 +237,20 @@ int relayout_with_constraint(Area *a, int maximum_size);
|
||||
|
||||
// Sets the redraw_needed flag on the area and its descendants
|
||||
void schedule_redraw(Area *a);
|
||||
|
||||
// Recreates the Area pixmap and draws the background and the foreground
|
||||
void draw(Area *a);
|
||||
|
||||
// Draws the background of the Area
|
||||
void draw_background(Area *a, cairo_t *c);
|
||||
|
||||
// Explores the entire Area subtree (only if the on_screen flag set)
|
||||
// and draws the areas with the redraw_needed flag set
|
||||
void draw_tree(Area *a);
|
||||
|
||||
// Clears the on_screen flag, sets the size to zero and triggers a parent resize
|
||||
void hide(Area *a);
|
||||
|
||||
// Sets the on_screen flag and triggers a parent and area resize
|
||||
void show(Area *a);
|
||||
|
||||
|
||||
@@ -37,40 +37,44 @@
|
||||
#include <librsvg/rsvg.h>
|
||||
#endif
|
||||
|
||||
|
||||
void copy_file(const char *pathSrc, const char *pathDest)
|
||||
void copy_file(const char *path_src, const char *path_dest)
|
||||
{
|
||||
if (g_str_equal(pathSrc, pathDest))
|
||||
if (g_str_equal(path_src, path_dest))
|
||||
return;
|
||||
|
||||
FILE *fileSrc, *fileDest;
|
||||
char buffer[100];
|
||||
FILE *file_src, *file_dest;
|
||||
char buffer[4096];
|
||||
int nb;
|
||||
|
||||
fileSrc = fopen(pathSrc, "rb");
|
||||
if (fileSrc == NULL) return;
|
||||
file_src = fopen(path_src, "rb");
|
||||
if (file_src == NULL)
|
||||
return;
|
||||
|
||||
fileDest = fopen(pathDest, "wb");
|
||||
if (fileDest == NULL) return;
|
||||
file_dest = fopen(path_dest, "wb");
|
||||
if (file_dest == NULL) {
|
||||
fclose(file_src);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((nb = fread(buffer, 1, sizeof(buffer), fileSrc)) > 0) {
|
||||
if ( nb != fwrite(buffer, 1, nb, fileDest)) {
|
||||
printf("Error while copying file %s to %s\n", pathSrc, pathDest);
|
||||
while ((nb = fread(buffer, 1, sizeof(buffer), file_src)) > 0) {
|
||||
if (nb != fwrite(buffer, 1, nb, file_dest)) {
|
||||
printf("Error while copying file %s to %s\n", path_src, path_dest);
|
||||
}
|
||||
}
|
||||
|
||||
fclose (fileDest);
|
||||
fclose (fileSrc);
|
||||
fclose(file_dest);
|
||||
fclose(file_src);
|
||||
}
|
||||
|
||||
|
||||
int parse_line(const char *line, char **key, char **value)
|
||||
{
|
||||
char *a, *b;
|
||||
|
||||
/* Skip useless lines */
|
||||
if ((line[0] == '#') || (line[0] == '\n')) return 0;
|
||||
if (!(a = strchr (line, '='))) return 0;
|
||||
if ((line[0] == '#') || (line[0] == '\n'))
|
||||
return 0;
|
||||
if (!(a = strchr(line, '=')))
|
||||
return 0;
|
||||
|
||||
/* overwrite '=' with '\0' */
|
||||
a[0] = '\0';
|
||||
@@ -78,7 +82,8 @@ int parse_line (const char *line, char **key, char **value)
|
||||
a++;
|
||||
|
||||
/* overwrite '\n' with '\0' if '\n' present */
|
||||
if ((b = strchr (a, '\n'))) b[0] = '\0';
|
||||
if ((b = strchr(a, '\n')))
|
||||
b[0] = '\0';
|
||||
|
||||
*value = strdup(a);
|
||||
|
||||
@@ -87,13 +92,10 @@ int parse_line (const char *line, char **key, char **value)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void tint_exec(const char *command)
|
||||
{
|
||||
if (command) {
|
||||
pid_t pid;
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
if (fork() == 0) {
|
||||
// change for the fork the signal mask
|
||||
// sigset_t sigset;
|
||||
// sigprocmask(SIG_SETMASK, &sigset, 0);
|
||||
@@ -107,9 +109,7 @@ void tint_exec(const char *command)
|
||||
char *expand_tilde(char *s)
|
||||
{
|
||||
const gchar *home = g_get_home_dir();
|
||||
if (home &&
|
||||
(strcmp(s, "~") == 0 ||
|
||||
strstr(s, "~/") == s)) {
|
||||
if (home && (strcmp(s, "~") == 0 || strstr(s, "~/") == s)) {
|
||||
char *result = calloc(strlen(home) + strlen(s), 1);
|
||||
strcat(result, home);
|
||||
strcat(result, s + 1);
|
||||
@@ -129,8 +129,7 @@ char *contract_tilde(char *s)
|
||||
strcat(home_slash, home);
|
||||
strcat(home_slash, "/");
|
||||
|
||||
if ((strcmp(s, home) == 0 ||
|
||||
strstr(s, home_slash) == s)) {
|
||||
if ((strcmp(s, home) == 0 || strstr(s, home_slash) == s)) {
|
||||
char *result = calloc(strlen(s) - strlen(home) + 2, 1);
|
||||
strcat(result, "~");
|
||||
strcat(result, s + strlen(home));
|
||||
@@ -146,43 +145,42 @@ int hex_char_to_int (char c)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (c >= '0' && c <= '9') r = c - '0';
|
||||
else if (c >= 'a' && c <= 'f') r = c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F') r = c - 'A' + 10;
|
||||
else r = 0;
|
||||
if (c >= '0' && c <= '9')
|
||||
r = c - '0';
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
r = c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
r = c - 'A' + 10;
|
||||
else
|
||||
r = 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int hex_to_rgb(char *hex, int *r, int *g, int *b)
|
||||
{
|
||||
int len;
|
||||
if (hex == NULL || hex[0] != '#')
|
||||
return (0);
|
||||
|
||||
if (hex == NULL || hex[0] != '#') return (0);
|
||||
|
||||
len = strlen (hex);
|
||||
int len = strlen(hex);
|
||||
if (len == 3 + 1) {
|
||||
*r = hex_char_to_int(hex[1]);
|
||||
*g = hex_char_to_int(hex[2]);
|
||||
*b = hex_char_to_int(hex[3]);
|
||||
}
|
||||
else if (len == 6 + 1) {
|
||||
} else if (len == 6 + 1) {
|
||||
*r = hex_char_to_int(hex[1]) * 16 + hex_char_to_int(hex[2]);
|
||||
*g = hex_char_to_int(hex[3]) * 16 + hex_char_to_int(hex[4]);
|
||||
*b = hex_char_to_int(hex[5]) * 16 + hex_char_to_int(hex[6]);
|
||||
}
|
||||
else if (len == 12 + 1) {
|
||||
} else if (len == 12 + 1) {
|
||||
*r = hex_char_to_int(hex[1]) * 16 + hex_char_to_int(hex[2]);
|
||||
*g = hex_char_to_int(hex[5]) * 16 + hex_char_to_int(hex[6]);
|
||||
*b = hex_char_to_int(hex[9]) * 16 + hex_char_to_int(hex[10]);
|
||||
}
|
||||
else return 0;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void get_color(char *hex, double *rgb)
|
||||
{
|
||||
int r, g, b;
|
||||
@@ -194,20 +192,21 @@ void get_color (char *hex, double *rgb)
|
||||
rgb[2] = (b / 255.0);
|
||||
}
|
||||
|
||||
|
||||
void extract_values(const char *value, char **value1, char **value2, char **value3)
|
||||
{
|
||||
char *b = 0, *c = 0;
|
||||
|
||||
if (*value1) free (*value1);
|
||||
if (*value2) free (*value2);
|
||||
if (*value3) free (*value3);
|
||||
if (*value1)
|
||||
free(*value1);
|
||||
if (*value2)
|
||||
free(*value2);
|
||||
if (*value3)
|
||||
free(*value3);
|
||||
|
||||
if ((b = strchr(value, ' '))) {
|
||||
b[0] = '\0';
|
||||
b++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
*value2 = 0;
|
||||
*value3 = 0;
|
||||
}
|
||||
@@ -218,8 +217,7 @@ void extract_values (const char *value, char **value1, char **value2, char **val
|
||||
if ((c = strchr(b, ' '))) {
|
||||
c[0] = '\0';
|
||||
c++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
c = 0;
|
||||
*value3 = 0;
|
||||
}
|
||||
@@ -233,7 +231,6 @@ void extract_values (const char *value, char **value1, char **value2, char **val
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright)
|
||||
{
|
||||
unsigned int x, y;
|
||||
@@ -249,16 +246,19 @@ void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright
|
||||
argb = data[id];
|
||||
a = (argb >> 24) & 0xff;
|
||||
// transparent => nothing to do.
|
||||
if (a == 0) continue;
|
||||
if (a == 0)
|
||||
continue;
|
||||
r = (argb >> 16) & 0xff;
|
||||
g = (argb >> 8) & 0xff;
|
||||
b = (argb)&0xff;
|
||||
|
||||
// convert RGB to HSB
|
||||
cmax = (r > g) ? r : g;
|
||||
if (b > cmax) cmax = b;
|
||||
if (b > cmax)
|
||||
cmax = b;
|
||||
cmin = (r < g) ? r : g;
|
||||
if (b < cmin) cmin = b;
|
||||
if (b < cmin)
|
||||
cmin = b;
|
||||
brightness = ((float)cmax) / 255.0f;
|
||||
if (cmax != 0)
|
||||
saturation = ((float)(cmax - cmin)) / ((float)cmax);
|
||||
@@ -283,11 +283,15 @@ void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright
|
||||
|
||||
// adjust
|
||||
saturation += satur;
|
||||
if (saturation < 0.0) saturation = 0.0;
|
||||
if (saturation > 1.0) saturation = 1.0;
|
||||
if (saturation < 0.0)
|
||||
saturation = 0.0;
|
||||
if (saturation > 1.0)
|
||||
saturation = 1.0;
|
||||
brightness += bright;
|
||||
if (brightness < 0.0) brightness = 0.0;
|
||||
if (brightness > 1.0) brightness = 1.0;
|
||||
if (brightness < 0.0)
|
||||
brightness = 0.0;
|
||||
if (brightness > 1.0)
|
||||
brightness = 1.0;
|
||||
if (alpha != 100)
|
||||
a = (a * alpha) / 100;
|
||||
|
||||
@@ -343,7 +347,7 @@ void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright
|
||||
}
|
||||
}
|
||||
|
||||
void createHeuristicMask(DATA32* data, int w, int h)
|
||||
void create_heuristic_mask(DATA32 *data, int w, int h)
|
||||
{
|
||||
// first we need to find the mask color, therefore we check all 4 edge pixel and take the color which
|
||||
// appears most often (we only need to check three edges, the 4th is implicitly clear)
|
||||
@@ -362,15 +366,14 @@ void createHeuristicMask(DATA32* data, int w, int h)
|
||||
unsigned char b = udata[4 * maskPos];
|
||||
unsigned char g = udata[4 * maskPos + 1];
|
||||
unsigned char r = udata[4 * maskPos + 1];
|
||||
int i;
|
||||
for (i=0; i<h*w; ++i) {
|
||||
for (int i = 0; i < h * w; ++i) {
|
||||
if (b - udata[0] == 0 && g - udata[1] == 0 && r - udata[2] == 0)
|
||||
udata[3] = 0;
|
||||
udata += 4;
|
||||
}
|
||||
}
|
||||
|
||||
int pixelEmpty(DATA32 argb)
|
||||
int pixel_empty(DATA32 argb)
|
||||
{
|
||||
|
||||
DATA32 a = (argb >> 24) & 0xff;
|
||||
@@ -381,22 +384,20 @@ int pixelEmpty(DATA32 argb)
|
||||
return rgb == 0;
|
||||
}
|
||||
|
||||
int imageEmpty(DATA32* data, int w, int h)
|
||||
int image_empty(DATA32 *data, int w, int h)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
||||
if (w > 0 && h > 0) {
|
||||
x = w / 2;
|
||||
y = h / 2;
|
||||
if (!pixelEmpty(data[y * w + x])) {
|
||||
int x = w / 2;
|
||||
int y = h / 2;
|
||||
if (!pixel_empty(data[y * w + x])) {
|
||||
// fprintf(stderr, "Non-empty pixel: [%u, %u] = %x\n", x, y, data[y * w + x]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
for (x = 0; x < w; x++) {
|
||||
if (!pixelEmpty(data[y * w + x])) {
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
if (!pixel_empty(data[y * w + x])) {
|
||||
// fprintf(stderr, "Non-empty pixel: [%u, %u] = %x\n", x, y, data[y * w + x]);
|
||||
return 0;
|
||||
}
|
||||
@@ -448,7 +449,13 @@ void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color
|
||||
int i, j;
|
||||
for (i = -shadow_size; i <= shadow_size; i++) {
|
||||
for (j = -shadow_size; j <= shadow_size; j++) {
|
||||
cairo_set_source_rgba(c, 0.0, 0.0, 0.0, 1.0 - (1.0 - shadow_edge_alpha) * sqrt((i*i + j*j)/(double)(shadow_size*shadow_size)));
|
||||
cairo_set_source_rgba(c,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0 -
|
||||
(1.0 - shadow_edge_alpha) *
|
||||
sqrt((i * i + j * j) / (double)(shadow_size * shadow_size)));
|
||||
pango_cairo_update_layout(c, layout);
|
||||
cairo_move_to(c, posx + i, posy + j);
|
||||
pango_cairo_show_layout(c, layout);
|
||||
@@ -520,7 +527,12 @@ Imlib_Image adjust_icon(Imlib_Image original, int alpha, int saturation, int bri
|
||||
imlib_context_set_image(copy);
|
||||
imlib_image_set_has_alpha(1);
|
||||
DATA32 *data = imlib_image_get_data();
|
||||
adjust_asb(data, imlib_image_get_width(), imlib_image_get_height(), alpha, (float)saturation/100, (float)brightness/100);
|
||||
adjust_asb(data,
|
||||
imlib_image_get_width(),
|
||||
imlib_image_get_height(),
|
||||
alpha,
|
||||
(float)saturation / 100,
|
||||
(float)brightness / 100);
|
||||
imlib_image_put_back_data(data);
|
||||
return copy;
|
||||
}
|
||||
@@ -539,16 +551,53 @@ void draw_rect(cairo_t *c, double x, double y, double w, double h, double r)
|
||||
cairo_rel_curve_to(c, -c1, 0, -r, -c1, -r, -r);
|
||||
cairo_rel_line_to(c, 0, -h + 2 * r);
|
||||
cairo_rel_curve_to(c, 0, -c1, r - c1, -r, r, -r);
|
||||
}
|
||||
else
|
||||
} else
|
||||
cairo_rectangle(c, x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
void clear_pixmap(Pixmap p, int x, int y, int w, int h)
|
||||
{
|
||||
Picture pict = XRenderCreatePicture(server.dsp, p, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
|
||||
XRenderColor col = { .red=0, .green=0, .blue=0, .alpha=0 };
|
||||
XRenderColor col;
|
||||
col.red = col.green = col.blue = col.alpha = 0;
|
||||
XRenderFillRectangle(server.dsp, PictOpSrc, pict, &col, x, y, w, h);
|
||||
XRenderFreePicture(server.dsp, pict);
|
||||
}
|
||||
|
||||
void get_text_size2(PangoFontDescription *font,
|
||||
int *height_ink,
|
||||
int *height,
|
||||
int *width,
|
||||
int panel_height,
|
||||
int panel_width,
|
||||
char *text,
|
||||
int len,
|
||||
PangoWrapMode wrap,
|
||||
PangoEllipsizeMode ellipsis)
|
||||
{
|
||||
PangoRectangle rect_ink, rect;
|
||||
|
||||
Pixmap pmap = XCreatePixmap(server.dsp, server.root_win, panel_height, panel_width, server.depth);
|
||||
|
||||
cairo_surface_t *cs = cairo_xlib_surface_create(server.dsp, pmap, server.visual, panel_height, panel_width);
|
||||
cairo_t *c = cairo_create(cs);
|
||||
|
||||
PangoLayout *layout = pango_cairo_create_layout(c);
|
||||
pango_layout_set_width(layout, panel_width * PANGO_SCALE);
|
||||
pango_layout_set_height(layout, panel_height * PANGO_SCALE);
|
||||
pango_layout_set_wrap(layout, wrap);
|
||||
pango_layout_set_ellipsize(layout, ellipsis);
|
||||
pango_layout_set_font_description(layout, font);
|
||||
pango_layout_set_text(layout, text, len);
|
||||
|
||||
pango_layout_get_pixel_extents(layout, &rect_ink, &rect);
|
||||
*height_ink = rect_ink.height;
|
||||
*height = rect.height;
|
||||
*width = rect.width;
|
||||
// printf("dimension : %d - %d\n", rect_ink.height, rect.height);
|
||||
|
||||
g_object_unref(layout);
|
||||
cairo_destroy(c);
|
||||
cairo_surface_destroy(cs);
|
||||
XFreePixmap(server.dsp, pmap);
|
||||
}
|
||||
|
||||
@@ -18,71 +18,83 @@
|
||||
#define BLUE "\033[1;34m"
|
||||
#define RESET "\033[0m"
|
||||
|
||||
/*
|
||||
void fxfree(void** ptr){
|
||||
if (*ptr){
|
||||
free(*ptr);
|
||||
*ptr=NULL;
|
||||
}
|
||||
}
|
||||
FXint fxmalloc(void** ptr,unsigned long size){
|
||||
*ptr=NULL;
|
||||
if (size!=0){
|
||||
if ((*ptr=malloc(size))==NULL) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
*/
|
||||
|
||||
// mouse actions
|
||||
enum { NONE=0, CLOSE, TOGGLE, ICONIFY, SHADE, TOGGLE_ICONIFY, MAXIMIZE_RESTORE, MAXIMIZE, RESTORE, DESKTOP_LEFT, DESKTOP_RIGHT, NEXT_TASK, PREV_TASK };
|
||||
typedef enum MouseAction {
|
||||
NONE = 0,
|
||||
CLOSE,
|
||||
TOGGLE,
|
||||
ICONIFY,
|
||||
SHADE,
|
||||
TOGGLE_ICONIFY,
|
||||
MAXIMIZE_RESTORE,
|
||||
MAXIMIZE,
|
||||
RESTORE,
|
||||
DESKTOP_LEFT,
|
||||
DESKTOP_RIGHT,
|
||||
NEXT_TASK,
|
||||
PREV_TASK
|
||||
} MouseAction;
|
||||
|
||||
#define ALLDESKTOP 0xFFFFFFFF
|
||||
|
||||
// Copies a file to another path
|
||||
void copy_file(const char *path_src, const char *path_dest);
|
||||
|
||||
// copy file source to file dest
|
||||
void copy_file(const char *pathSrc, const char *pathDest);
|
||||
|
||||
// extract key = value
|
||||
// Parses lines with the format 'key = value' into key and value.
|
||||
// Strips key and value.
|
||||
// Values may contain spaces and the equal sign.
|
||||
// Returns 1 if both key and value could be read, zero otherwise.
|
||||
int parse_line(const char *line, char **key, char **value);
|
||||
|
||||
// execute a command by calling fork
|
||||
void extract_values(const char *value, char **value1, char **value2, char **value3);
|
||||
|
||||
// Executes a command in a shell.
|
||||
void tint_exec(const char *command);
|
||||
|
||||
// Returns a copy of s in which "~" is expanded to the path to the user's home directory.
|
||||
// The returned string must be freed by the caller.
|
||||
// The caller takes ownership of the string.
|
||||
char *expand_tilde(char *s);
|
||||
|
||||
// The opposite of expand_tilde: replaces the path to the user's home directory with "~".
|
||||
// The returned string must be freed by the caller.
|
||||
// The caller takes ownership of the string.
|
||||
char *contract_tilde(char *s);
|
||||
|
||||
// conversion
|
||||
// Color
|
||||
int hex_char_to_int(char c);
|
||||
int hex_to_rgb(char *hex, int *r, int *g, int *b);
|
||||
void get_color(char *hex, double *rgb);
|
||||
|
||||
void extract_values (const char *value, char **value1, char **value2, char **value3);
|
||||
Imlib_Image load_image(const char *path, int cached);
|
||||
|
||||
// adjust Alpha/Saturation/Brightness on an ARGB icon
|
||||
// alpha from 0 to 100, satur from 0 to 1, bright from 0 to 1.
|
||||
// Adjusts the alpha/saturation/brightness on an ARGB image.
|
||||
// Parameters: alpha from 0 to 100, satur from 0 to 1, bright from 0 to 1.
|
||||
void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright);
|
||||
void createHeuristicMask(DATA32* data, int w, int h);
|
||||
int imageEmpty(DATA32* data, int w, int h);
|
||||
Imlib_Image adjust_icon(Imlib_Image original, int alpha, int saturation, int brightness);
|
||||
|
||||
void create_heuristic_mask(DATA32 *data, int w, int h);
|
||||
|
||||
int image_empty(DATA32 *data, int w, int h);
|
||||
|
||||
// Renders the current Imlib image to a drawable. Wrapper around imlib_render_image_on_drawable.
|
||||
void render_image(Drawable d, int x, int y);
|
||||
|
||||
void get_text_size2(PangoFontDescription *font,
|
||||
int *height_ink,
|
||||
int *height,
|
||||
int *width,
|
||||
int panel_height,
|
||||
int panel_with,
|
||||
char *text,
|
||||
int len,
|
||||
PangoWrapMode wrap,
|
||||
PangoEllipsizeMode ellipsis);
|
||||
|
||||
void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, int font_shadow);
|
||||
|
||||
Imlib_Image load_image(const char *path, int cached);
|
||||
|
||||
Imlib_Image adjust_icon(Imlib_Image original, int alpha, int saturation, int brightness);
|
||||
|
||||
// draw rounded rectangle
|
||||
// Draws a rounded rectangle
|
||||
void draw_rect(cairo_t *c, double x, double y, double w, double h, double r);
|
||||
|
||||
// clear pixmap with transparent color
|
||||
// Clears the pixmap (with transparent color)
|
||||
void clear_pixmap(Pixmap p, int x, int y, int w, int h);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
/* partial change history:
|
||||
*
|
||||
* 2004-10-10 mbp: Lift out character type dependencies into macros.
|
||||
@@ -37,40 +36,31 @@
|
||||
|
||||
#include "strnatcmp.h"
|
||||
|
||||
|
||||
/* These are defined as macros to make it easier to adapt this code to
|
||||
* different characters types or comparison functions. */
|
||||
static inline int
|
||||
nat_isdigit(nat_char a)
|
||||
static inline int nat_isdigit(nat_char a)
|
||||
{
|
||||
return isdigit((unsigned char)a);
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
nat_isspace(nat_char a)
|
||||
static inline int nat_isspace(nat_char a)
|
||||
{
|
||||
return isspace((unsigned char)a);
|
||||
}
|
||||
|
||||
|
||||
static inline nat_char
|
||||
nat_toupper(nat_char a)
|
||||
static inline nat_char nat_toupper(nat_char a)
|
||||
{
|
||||
return toupper((unsigned char)a);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
compare_right(nat_char const *a, nat_char const *b)
|
||||
static int compare_right(nat_char const *a, nat_char const *b)
|
||||
{
|
||||
int bias = 0;
|
||||
|
||||
/* The longest run of digits wins. That aside, the greatest
|
||||
value wins, but we can't know that it will until we've scanned
|
||||
both numbers to know that they have the same magnitude, so we
|
||||
remember it in BIAS. */
|
||||
* value wins, but we can't know that it will until we've scanned
|
||||
* both numbers to know that they have the same magnitude, so we
|
||||
* remember it in BIAS. */
|
||||
for (;; a++, b++) {
|
||||
if (!nat_isdigit(*a) && !nat_isdigit(*b))
|
||||
return bias;
|
||||
@@ -91,12 +81,9 @@ compare_right(nat_char const *a, nat_char const *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
compare_left(nat_char const *a, nat_char const *b)
|
||||
static int compare_left(nat_char const *a, nat_char const *b)
|
||||
{
|
||||
/* Compare two left-aligned numbers: the first to have a
|
||||
different value wins. */
|
||||
/* Compare two left-aligned numbers: the first to have a different value wins. */
|
||||
for (;; a++, b++) {
|
||||
if (!nat_isdigit(*a) && !nat_isdigit(*b))
|
||||
return 0;
|
||||
@@ -113,7 +100,6 @@ compare_left(nat_char const *a, nat_char const *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
|
||||
{
|
||||
int ai, bi;
|
||||
@@ -123,7 +109,8 @@ static int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
|
||||
assert(a && b);
|
||||
ai = bi = 0;
|
||||
while (1) {
|
||||
ca = a[ai]; cb = b[bi];
|
||||
ca = a[ai];
|
||||
cb = b[bi];
|
||||
|
||||
/* skip over leading spaces or zeros */
|
||||
while (nat_isspace(ca))
|
||||
@@ -146,8 +133,7 @@ static int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
|
||||
}
|
||||
|
||||
if (!ca && !cb) {
|
||||
/* The strings compare the same. Perhaps the caller
|
||||
will want to call strcmp to break the tie. */
|
||||
/* The strings compare the same. Perhaps the caller will want to call strcmp to break the tie. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -161,18 +147,18 @@ static int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
|
||||
else if (ca > cb)
|
||||
return +1;
|
||||
|
||||
++ai; ++bi;
|
||||
++ai;
|
||||
++bi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int strnatcmp(nat_char const *a, nat_char const *b) {
|
||||
int strnatcmp(nat_char const *a, nat_char const *b)
|
||||
{
|
||||
return strnatcmp0(a, b, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Compare, recognizing numeric string and ignoring case. */
|
||||
int strnatcasecmp(nat_char const *a, nat_char const *b) {
|
||||
int strnatcasecmp(nat_char const *a, nat_char const *b)
|
||||
{
|
||||
return strnatcmp0(a, b, 1);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
/* CUSTOMIZATION SECTION
|
||||
*
|
||||
* You can change this typedef, but must then also change the inline
|
||||
|
||||
@@ -26,7 +26,6 @@ GSList* timeout_list;
|
||||
struct timeval next_timeout;
|
||||
GHashTable *multi_timeouts;
|
||||
|
||||
|
||||
// functions and structs for multi timeouts
|
||||
typedef struct {
|
||||
int current_count;
|
||||
@@ -51,7 +50,6 @@ void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(void
|
||||
gint compare_timeouts(gconstpointer t1, gconstpointer t2);
|
||||
int timespec_subtract(struct timespec *result, struct timespec *x, struct timespec *y);
|
||||
|
||||
|
||||
int align_with_existing_timeouts(timeout *t);
|
||||
void create_multi_timeout(timeout *t1, timeout *t2);
|
||||
void append_multi_timeout(timeout *t1, timeout *t2);
|
||||
@@ -84,17 +82,17 @@ void cleanup_timeout()
|
||||
}
|
||||
}
|
||||
|
||||
/** Implementation notes for timeouts: The timeouts are kept in a GSList sorted by their
|
||||
* expiration time.
|
||||
* That means that update_next_timeout() only have to consider the first timeout in the list,
|
||||
* and callback_timeout_expired() only have to consider the timeouts as long as the expiration time
|
||||
* is in the past to the current time.
|
||||
* As time measurement we use clock_gettime(CLOCK_MONOTONIC) because this refers to a timer, which
|
||||
* reference point lies somewhere in the past and cannot be changed, but just queried.
|
||||
* If a single shot timer is installed it will be automatically deleted. I.e. the returned value
|
||||
* of add_timeout will not be valid anymore. You do not need to call stop_timeout for these timeouts,
|
||||
* however it's save to call it.
|
||||
**/
|
||||
// Implementation notes for timeouts
|
||||
//
|
||||
// The timeouts are kept in a GSList sorted by their expiration time.
|
||||
// That means that update_next_timeout() only have to consider the first timeout in the list,
|
||||
// and callback_timeout_expired() only have to consider the timeouts as long as the expiration time
|
||||
// is in the past to the current time.
|
||||
// As time measurement we use clock_gettime(CLOCK_MONOTONIC) because this refers to a timer, which
|
||||
// reference point lies somewhere in the past and cannot be changed, but just queried.
|
||||
// If a single shot timer is installed it will be automatically deleted. I.e. the returned value
|
||||
// of add_timeout will not be valid anymore. You do not need to call stop_timeout for these timeouts,
|
||||
// however it's save to call it.
|
||||
|
||||
timeout *add_timeout(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout **self)
|
||||
{
|
||||
@@ -104,7 +102,6 @@ timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*)
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
void change_timeout(timeout **t, int value_msec, int interval_msec, void (*_callback)(), void *arg)
|
||||
{
|
||||
if (!((timeout_list && g_slist_find(timeout_list, *t)) ||
|
||||
@@ -119,7 +116,6 @@ void change_timeout(timeout **t, int value_msec, int interval_msec, void(*_callb
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void update_next_timeout()
|
||||
{
|
||||
if (timeout_list) {
|
||||
@@ -130,17 +126,14 @@ void update_next_timeout()
|
||||
if (timespec_subtract(&next_timeout2, &t->timeout_expires, &cur_time)) {
|
||||
next_timeout.tv_sec = 0;
|
||||
next_timeout.tv_usec = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
next_timeout.tv_sec = next_timeout2.tv_sec;
|
||||
next_timeout.tv_usec = next_timeout2.tv_nsec / 1000;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
next_timeout.tv_sec = -1;
|
||||
}
|
||||
|
||||
|
||||
void callback_timeout_expired()
|
||||
{
|
||||
struct timespec cur_time;
|
||||
@@ -170,14 +163,12 @@ void callback_timeout_expired()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stop_timeout(timeout *t)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
// if not in the list, it was deleted in callback_timeout_expired
|
||||
if ((timeout_list && g_slist_find(timeout_list, t)) ||
|
||||
(multi_timeouts && g_hash_table_lookup(multi_timeouts, t))) {
|
||||
if ((timeout_list && g_slist_find(timeout_list, t)) || (multi_timeouts && g_hash_table_lookup(multi_timeouts, t))) {
|
||||
if (multi_timeouts && t->multi_timeout)
|
||||
remove_from_multi_timeout(t);
|
||||
if (timeout_list)
|
||||
@@ -188,7 +179,6 @@ void stop_timeout(timeout* t)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void (*_callback)(), void *arg, timeout *t)
|
||||
{
|
||||
t->interval_msec = interval_msec;
|
||||
@@ -205,14 +195,11 @@ void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), v
|
||||
timeout_list = g_slist_insert_sorted(timeout_list, t, compare_timeouts);
|
||||
}
|
||||
|
||||
|
||||
gint compare_timeouts(gconstpointer t1, gconstpointer t2)
|
||||
{
|
||||
return compare_timespecs(&((timeout*)t1)->timeout_expires,
|
||||
&((timeout*)t2)->timeout_expires);
|
||||
return compare_timespecs(&((const timeout *)t1)->timeout_expires, &((const timeout *)t2)->timeout_expires);
|
||||
}
|
||||
|
||||
|
||||
gint compare_timespecs(const struct timespec *t1, const struct timespec *t2)
|
||||
{
|
||||
if (t1->tv_sec < t2->tv_sec)
|
||||
@@ -224,8 +211,7 @@ gint compare_timespecs(const struct timespec* t1, const struct timespec* t2)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -251,7 +237,6 @@ int timespec_subtract(struct timespec* result, struct timespec* x, struct timesp
|
||||
return x->tv_sec < y->tv_sec;
|
||||
}
|
||||
|
||||
|
||||
struct timespec add_msec_to_timespec(struct timespec ts, int msec)
|
||||
{
|
||||
ts.tv_sec += msec / 1000;
|
||||
@@ -263,7 +248,6 @@ struct timespec add_msec_to_timespec(struct timespec ts, int msec)
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
int align_with_existing_timeouts(timeout *t)
|
||||
{
|
||||
GSList *it = timeout_list;
|
||||
@@ -271,7 +255,7 @@ int align_with_existing_timeouts(timeout *t)
|
||||
timeout *t2 = it->data;
|
||||
if (t2->interval_msec > 0) {
|
||||
if (t->interval_msec % t2->interval_msec == 0 || t2->interval_msec % t->interval_msec == 0) {
|
||||
if (multi_timeouts == 0)
|
||||
if (!multi_timeouts)
|
||||
multi_timeouts = g_hash_table_new(0, 0);
|
||||
if (!t->multi_timeout && !t2->multi_timeout) {
|
||||
// both timeouts can be aligned, but there is no multi timeout for them
|
||||
@@ -288,7 +272,6 @@ int align_with_existing_timeouts(timeout *t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int calc_multi_timeout_interval(multi_timeout_handler *mth)
|
||||
{
|
||||
GSList *it = mth->timeout_list;
|
||||
@@ -304,7 +287,6 @@ int calc_multi_timeout_interval(multi_timeout_handler* mth)
|
||||
return min_interval;
|
||||
}
|
||||
|
||||
|
||||
void create_multi_timeout(timeout *t1, timeout *t2)
|
||||
{
|
||||
multi_timeout *mt1 = calloc(1, sizeof(multi_timeout));
|
||||
@@ -333,7 +315,6 @@ void create_multi_timeout(timeout* t1, timeout* t2)
|
||||
update_multi_timeout_values(mth);
|
||||
}
|
||||
|
||||
|
||||
void append_multi_timeout(timeout *t1, timeout *t2)
|
||||
{
|
||||
if (t2->multi_timeout) {
|
||||
@@ -354,7 +335,6 @@ void append_multi_timeout(timeout* t1, timeout* t2)
|
||||
update_multi_timeout_values(mth);
|
||||
}
|
||||
|
||||
|
||||
void update_multi_timeout_values(multi_timeout_handler *mth)
|
||||
{
|
||||
int interval = calc_multi_timeout_interval(mth);
|
||||
@@ -382,7 +362,6 @@ void update_multi_timeout_values(multi_timeout_handler* mth)
|
||||
add_timeout_intern(next_timeout_msec, interval, callback_multi_timeout, mth, mth->parent_timeout);
|
||||
}
|
||||
|
||||
|
||||
void callback_multi_timeout(void *arg)
|
||||
{
|
||||
multi_timeout_handler *mth = arg;
|
||||
@@ -405,7 +384,6 @@ void callback_multi_timeout(void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void remove_from_multi_timeout(timeout *t)
|
||||
{
|
||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t);
|
||||
@@ -430,13 +408,15 @@ void remove_from_multi_timeout(timeout* t)
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
timespec_subtract(&diff_time, &t->timeout_expires, &cur_time);
|
||||
int msec_to_expiration = diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000;
|
||||
add_timeout_intern(msec_to_expiration, last_timeout->interval_msec, last_timeout->_callback, last_timeout->arg, last_timeout);
|
||||
}
|
||||
else
|
||||
add_timeout_intern(msec_to_expiration,
|
||||
last_timeout->interval_msec,
|
||||
last_timeout->_callback,
|
||||
last_timeout->arg,
|
||||
last_timeout);
|
||||
} else
|
||||
update_multi_timeout_values(mth);
|
||||
}
|
||||
|
||||
|
||||
void stop_multi_timeout(timeout *t)
|
||||
{
|
||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t);
|
||||
@@ -452,6 +432,7 @@ void stop_multi_timeout(timeout* t)
|
||||
}
|
||||
|
||||
double profiling_get_time_old_time = 0;
|
||||
|
||||
double profiling_get_time()
|
||||
{
|
||||
struct timespec cur_time;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**************************************************************************
|
||||
/*************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 Andreas.Fink (Andreas.Fink85@gmail.com)
|
||||
*
|
||||
@@ -15,7 +15,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
@@ -23,59 +22,51 @@
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
// Single shot timers (i.e. timers with interval_msec == 0) are deleted automatically as soon as they expire,
|
||||
// i.e. you do not need to stop them, however it is safe to call stop_timeout for these timers.
|
||||
// You can pass the address of the variable storing the pointer to the timer as 'self' in add_timeout, in which
|
||||
// case it is used to clear the pointer if the timer is destroyed automatically. This enforces the timeout pointers
|
||||
// to be either valid or NULL.
|
||||
// Periodic timeouts are aligned to each other whenever possible, i.e. one interval_msec is an
|
||||
// integral multiple of the other.
|
||||
|
||||
extern struct timeval next_timeout;
|
||||
|
||||
|
||||
typedef struct _timeout timeout;
|
||||
|
||||
|
||||
// timer functions
|
||||
/**
|
||||
* Single shot timers (i.e. timers with interval_msec == 0) are deleted automatically as soon as they expire,
|
||||
* i.e. you do not need to stop them, however it is safe to call stop_timeout for these timers.
|
||||
* You can pass the address of the variable storing the pointer to the timer as 'self' in add_timeout, in which
|
||||
* case it is used to clear the pointer if the timer is destroyed automatically. This enforces the timeout pointers
|
||||
* to be either valid or NULL.
|
||||
* Periodic timeouts are aligned to each other whenever possible, i.e. one interval_msec is an
|
||||
* integral multiple of the other.
|
||||
**/
|
||||
|
||||
/** Initializes default global data. **/
|
||||
// Initializes default global data.
|
||||
void default_timeout();
|
||||
|
||||
/** Cleans up: stops all timers and frees memory. **/
|
||||
// Cleans up: stops all timers and frees memory.
|
||||
void cleanup_timeout();
|
||||
|
||||
/** Installs a timer with the first timeout after 'value_msec' and then an optional periodic timeout every
|
||||
* 'interval_msec' (set it to 0 to prevent periodic timeouts).
|
||||
* '_callback' is the function called when the timer reaches the timeout.
|
||||
* 'arg' is the argument passed to the callback function.
|
||||
* 'self' is an optional pointer to a timeout* variable. If non-NULL, the variable is set to NULL when the timer
|
||||
* is destroyed (with stop_timeout, cleanup_timeout or when the timer expires and it is single-shot).
|
||||
* Returns a pointer to the timer, which is needed for stopping/changing it.
|
||||
**/
|
||||
// Installs a timer with the first timeout after 'value_msec' and then an optional periodic timeout every
|
||||
// 'interval_msec' (set it to 0 to prevent periodic timeouts).
|
||||
// '_callback' is the function called when the timer reaches the timeout.
|
||||
// 'arg' is the argument passed to the callback function.
|
||||
// 'self' is an optional pointer to a timeout* variable. If non-NULL, the variable is set to NULL when the timer
|
||||
// is destroyed (with stop_timeout, cleanup_timeout or when the timer expires and it is single-shot).
|
||||
// Returns a pointer to the timer, which is needed for stopping/changing it.
|
||||
timeout *add_timeout(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout **self);
|
||||
|
||||
/** Changes timer 't'. If it does not exist, a new timer is created, with self set to 't'. **/
|
||||
// Changes timer 't'. If it does not exist, a new timer is created, with self set to 't'.
|
||||
void change_timeout(timeout **t, int value_msec, int interval_msec, void (*_callback)(void *), void *arg);
|
||||
|
||||
/** stops the timeout 't' **/
|
||||
// Stops the timer 't'
|
||||
void stop_timeout(timeout *t);
|
||||
|
||||
/** update_next_timeout updates next_timeout to the value, when the next installed timeout will expire **/
|
||||
// Updates next_timeout to the value, when the next installed timeout will expire
|
||||
void update_next_timeout();
|
||||
|
||||
/** Callback of all expired timeouts **/
|
||||
// Callback of all expired timeouts
|
||||
void callback_timeout_expired();
|
||||
|
||||
/** Returns -1 if t1 < t2, 0 if t1 == t2, 1 if t1 > t2 **/
|
||||
// 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);
|
||||
|
||||
/** Returns the time difference in seconds between the current time and the last time this function was called.
|
||||
* At the first call returns zero.
|
||||
**/
|
||||
// Returns the time difference in seconds between the current time and the last time this function was called.
|
||||
// At the first call returns zero.
|
||||
double profiling_get_time();
|
||||
|
||||
#endif // TIMER_H
|
||||
|
||||
@@ -36,7 +36,8 @@ static int ueventfd = -1;
|
||||
static struct sockaddr_nl nls;
|
||||
static GList *notifiers = NULL;
|
||||
|
||||
static const char* has_prefix(const char *str, const char *end, const char *prefix, size_t prefixlen) {
|
||||
static const char *has_prefix(const char *str, const char *end, const char *prefix, size_t prefixlen)
|
||||
{
|
||||
if ((end - str) < prefixlen)
|
||||
return NULL;
|
||||
|
||||
@@ -48,36 +49,38 @@ static const char* has_prefix(const char *str, const char *end, const char *pref
|
||||
|
||||
#define HAS_CONST_PREFIX(str, end, prefix) has_prefix((str), end, prefix, sizeof(prefix) - 1)
|
||||
|
||||
static void uevent_param_free(gpointer data) {
|
||||
static void uevent_param_free(gpointer data)
|
||||
{
|
||||
struct uevent_parameter *param = data;
|
||||
free(param->key);
|
||||
free(param->val);
|
||||
free(param);
|
||||
}
|
||||
|
||||
static void uevent_free(struct uevent *ev) {
|
||||
static void uevent_free(struct uevent *ev)
|
||||
{
|
||||
free(ev->path);
|
||||
free(ev->subsystem);
|
||||
g_list_free_full(ev->params, uevent_param_free);
|
||||
free(ev);
|
||||
}
|
||||
|
||||
static struct uevent *uevent_new(char *buffer, int size) {
|
||||
struct uevent *ev;
|
||||
const char* s = buffer;
|
||||
const char* end = s + size;
|
||||
static struct uevent *uevent_new(char *buffer, int size)
|
||||
{
|
||||
gboolean first = TRUE;
|
||||
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
|
||||
ev = calloc(1, sizeof(*ev));
|
||||
struct uevent *ev = calloc(1, sizeof(*ev));
|
||||
if (!ev)
|
||||
return NULL;
|
||||
|
||||
/* ensure nul termination required by strlen() */
|
||||
buffer[size - 1] = '\0';
|
||||
|
||||
const char *s = buffer;
|
||||
const char *end = s + size;
|
||||
for (; s < end; s += strlen(s) + 1) {
|
||||
if (first) {
|
||||
const char *p = strchr(s, '@');
|
||||
@@ -121,11 +124,13 @@ static struct uevent *uevent_new(char *buffer, int size) {
|
||||
return ev;
|
||||
}
|
||||
|
||||
void uevent_register_notifier(struct uevent_notify *nb) {
|
||||
void uevent_register_notifier(struct uevent_notify *nb)
|
||||
{
|
||||
notifiers = g_list_append(notifiers, nb);
|
||||
}
|
||||
|
||||
void uevent_unregister_notifier(struct uevent_notify *nb) {
|
||||
void uevent_unregister_notifier(struct uevent_notify *nb)
|
||||
{
|
||||
GList *l = notifiers;
|
||||
|
||||
while (l != NULL) {
|
||||
@@ -139,21 +144,19 @@ void uevent_unregister_notifier(struct uevent_notify *nb) {
|
||||
}
|
||||
}
|
||||
|
||||
void uevent_handler() {
|
||||
struct uevent *ev;
|
||||
char buf[512];
|
||||
GList *l;
|
||||
|
||||
void uevent_handler()
|
||||
{
|
||||
if (ueventfd < 0)
|
||||
return;
|
||||
|
||||
char buf[512];
|
||||
int len = recv(ueventfd, buf, sizeof(buf), MSG_DONTWAIT);
|
||||
if (len < 0)
|
||||
return;
|
||||
|
||||
ev = uevent_new(buf, len);
|
||||
struct uevent *ev = uevent_new(buf, len);
|
||||
if (ev) {
|
||||
for (l = notifiers; l != NULL; l = l->next) {
|
||||
for (GList *l = notifiers; l; l = l->next) {
|
||||
struct uevent_notify *nb = l->data;
|
||||
|
||||
if (!(ev->action & nb->action))
|
||||
@@ -169,7 +172,8 @@ void uevent_handler() {
|
||||
}
|
||||
}
|
||||
|
||||
int uevent_init() {
|
||||
int uevent_init()
|
||||
{
|
||||
/* Open hotplug event netlink socket */
|
||||
memset(&nls, 0, sizeof(struct sockaddr_nl));
|
||||
nls.nl_family = AF_NETLINK;
|
||||
@@ -194,7 +198,8 @@ int uevent_init() {
|
||||
return ueventfd;
|
||||
}
|
||||
|
||||
void uevent_cleanup() {
|
||||
void uevent_cleanup()
|
||||
{
|
||||
if (ueventfd >= 0)
|
||||
close(ueventfd);
|
||||
}
|
||||
|
||||
@@ -35,97 +35,88 @@
|
||||
#include "panel.h"
|
||||
#include "taskbar.h"
|
||||
|
||||
|
||||
|
||||
void set_active (Window win)
|
||||
void activate_window(Window win)
|
||||
{
|
||||
send_event32(win, server.atom._NET_ACTIVE_WINDOW, 2, CurrentTime, 0);
|
||||
}
|
||||
|
||||
|
||||
void set_desktop (int desktop)
|
||||
void change_desktop(int desktop)
|
||||
{
|
||||
send_event32(server.root_win, server.atom._NET_CURRENT_DESKTOP, desktop, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
void windows_set_desktop (Window win, int desktop)
|
||||
void change_window_desktop(Window win, int desktop)
|
||||
{
|
||||
send_event32(win, server.atom._NET_WM_DESKTOP, desktop, 2, 0);
|
||||
}
|
||||
|
||||
|
||||
void set_close (Window win)
|
||||
void close_window(Window win)
|
||||
{
|
||||
send_event32(win, server.atom._NET_CLOSE_WINDOW, 0, 2, 0);
|
||||
}
|
||||
|
||||
|
||||
void window_toggle_shade (Window win)
|
||||
void toggle_window_shade(Window win)
|
||||
{
|
||||
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_SHADED, 0);
|
||||
}
|
||||
|
||||
|
||||
void window_maximize_restore (Window win)
|
||||
void toggle_window_maximized(Window win)
|
||||
{
|
||||
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_MAXIMIZED_VERT, 0);
|
||||
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||
}
|
||||
|
||||
|
||||
int window_is_hidden (Window win)
|
||||
gboolean window_is_hidden(Window win)
|
||||
{
|
||||
Window window;
|
||||
Atom *at;
|
||||
int count, i;
|
||||
int count;
|
||||
|
||||
at = server_get_property (win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
// do not add transient_for windows if the transient window is already in the taskbar
|
||||
window = win;
|
||||
while (XGetTransientForHint(server.dsp, window, &window)) {
|
||||
if (task_get_tasks(window)) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
XFree(at);
|
||||
|
||||
at = server_get_property(win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_WINDOW_TYPE_DOCK || at[i] == server.atom._NET_WM_WINDOW_TYPE_DESKTOP || at[i] == server.atom._NET_WM_WINDOW_TYPE_TOOLBAR || at[i] == server.atom._NET_WM_WINDOW_TYPE_MENU || at[i] == server.atom._NET_WM_WINDOW_TYPE_SPLASH) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_WINDOW_TYPE_DOCK || at[i] == server.atom._NET_WM_WINDOW_TYPE_DESKTOP ||
|
||||
at[i] == server.atom._NET_WM_WINDOW_TYPE_TOOLBAR || at[i] == server.atom._NET_WM_WINDOW_TYPE_MENU ||
|
||||
at[i] == server.atom._NET_WM_WINDOW_TYPE_SPLASH) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
XFree(at);
|
||||
|
||||
for (i=0 ; i < nb_panel ; i++) {
|
||||
if (panel1[i].main_win == win) {
|
||||
return 1;
|
||||
for (int i = 0; i < num_panels; i++) {
|
||||
if (panels[i].main_win == win) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// specification
|
||||
// Windows with neither _NET_WM_WINDOW_TYPE nor WM_TRANSIENT_FOR set
|
||||
// MUST be taken as top-level window.
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int window_get_desktop (Window win)
|
||||
int get_window_desktop(Window win)
|
||||
{
|
||||
return get_property32(win, server.atom._NET_WM_DESKTOP, XA_CARDINAL);
|
||||
}
|
||||
|
||||
|
||||
int window_get_monitor (Window win)
|
||||
int get_window_monitor(Window win)
|
||||
{
|
||||
int i, x, y;
|
||||
Window src;
|
||||
@@ -136,14 +127,12 @@ int window_get_monitor (Window win)
|
||||
int match_bottom = 0;
|
||||
// There is an ambiguity when a window is right on the edge between screens.
|
||||
// In that case, prefer the monitor which is on the right and bottom of the window's top-left corner.
|
||||
for (i = 0; i < server.nb_monitor; i++) {
|
||||
for (i = 0; i < server.num_monitors; i++) {
|
||||
if (x >= server.monitor[i].x && x <= (server.monitor[i].x + server.monitor[i].width))
|
||||
if (y >= server.monitor[i].y && y <= (server.monitor[i].y + server.monitor[i].height)) {
|
||||
int current_right = x < (server.monitor[i].x + server.monitor[i].width);
|
||||
int current_bottom = y < (server.monitor[i].y + server.monitor[i].height);
|
||||
if (best_match < 0 ||
|
||||
(!match_right && current_right) ||
|
||||
(!match_bottom && current_bottom)) {
|
||||
if (best_match < 0 || (!match_right && current_right) || (!match_bottom && current_bottom)) {
|
||||
best_match = i;
|
||||
}
|
||||
}
|
||||
@@ -155,7 +144,7 @@ int window_get_monitor (Window win)
|
||||
return best_match;
|
||||
}
|
||||
|
||||
void window_get_coordinates (Window win, int *x, int *y, int *w, int *h)
|
||||
void get_window_coordinates(Window win, int *x, int *y, int *w, int *h)
|
||||
{
|
||||
int dummy_int;
|
||||
unsigned ww, wh, bw, bh;
|
||||
@@ -166,70 +155,62 @@ void window_get_coordinates (Window win, int *x, int *y, int *w, int *h)
|
||||
*h = wh + bh;
|
||||
}
|
||||
|
||||
int window_is_iconified (Window win)
|
||||
gboolean window_is_iconified(Window win)
|
||||
{
|
||||
// EWMH specification : minimization of windows use _NET_WM_STATE_HIDDEN.
|
||||
// WM_STATE is not accurate for shaded window and in multi_desktop mode.
|
||||
Atom *at;
|
||||
int count, i;
|
||||
at = server_get_property (win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
int count;
|
||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_STATE_HIDDEN) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
XFree(at);
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int window_is_urgent (Window win)
|
||||
gboolean window_is_urgent(Window win)
|
||||
{
|
||||
Atom *at;
|
||||
int count, i;
|
||||
int count;
|
||||
|
||||
at = server_get_property (win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_STATE_DEMANDS_ATTENTION) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
XFree(at);
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int window_is_skip_taskbar (Window win)
|
||||
gboolean window_is_skip_taskbar(Window win)
|
||||
{
|
||||
Atom *at;
|
||||
int count, i;
|
||||
int count;
|
||||
|
||||
at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (i=0; i<count; i++) {
|
||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
XFree(at);
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GSList *server_get_name_of_desktop ()
|
||||
GSList *get_desktop_names()
|
||||
{
|
||||
int count, j;
|
||||
int count;
|
||||
GSList *list = NULL;
|
||||
gchar *data_ptr, *ptr;
|
||||
data_ptr = server_get_property (server.root_win, server.atom._NET_DESKTOP_NAMES, server.atom.UTF8_STRING, &count);
|
||||
gchar *data_ptr = server_get_property(server.root_win, server.atom._NET_DESKTOP_NAMES, server.atom.UTF8_STRING, &count);
|
||||
if (data_ptr) {
|
||||
list = g_slist_append(list, g_strdup(data_ptr));
|
||||
for (j = 0; j < count-1; j++) {
|
||||
for (int j = 0; j < count - 1; j++) {
|
||||
if (*(data_ptr + j) == '\0') {
|
||||
ptr = (gchar*)data_ptr + j + 1;
|
||||
gchar *ptr = (gchar *)data_ptr + j + 1;
|
||||
list = g_slist_append(list, g_strdup(ptr));
|
||||
}
|
||||
}
|
||||
@@ -238,25 +219,21 @@ GSList *server_get_name_of_desktop ()
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
int server_get_current_desktop ()
|
||||
int get_current_desktop()
|
||||
{
|
||||
return get_property32(server.root_win, server.atom._NET_CURRENT_DESKTOP, XA_CARDINAL);
|
||||
}
|
||||
|
||||
|
||||
Window window_get_active ()
|
||||
Window get_active_window()
|
||||
{
|
||||
return get_property32(server.root_win, server.atom._NET_ACTIVE_WINDOW, XA_WINDOW);
|
||||
}
|
||||
|
||||
|
||||
int window_is_active (Window win)
|
||||
gboolean window_is_active(Window win)
|
||||
{
|
||||
return (win == get_property32(server.root_win, server.atom._NET_ACTIVE_WINDOW, XA_WINDOW));
|
||||
}
|
||||
|
||||
|
||||
int get_icon_count(gulong *data, int num)
|
||||
{
|
||||
int count, pos, w, h;
|
||||
@@ -267,14 +244,14 @@ int get_icon_count (gulong *data, int num)
|
||||
w = data[pos++];
|
||||
h = data[pos++];
|
||||
pos += w * h;
|
||||
if (pos > num || w <= 0 || h <= 0) break;
|
||||
if (pos > num || w <= 0 || h <= 0)
|
||||
break;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
gulong *get_best_icon(gulong *data, int icon_count, int num, int *iw, int *ih, int best_icon_size)
|
||||
{
|
||||
int width[icon_count], height[icon_count], pos, i, w, h;
|
||||
@@ -286,7 +263,8 @@ gulong *get_best_icon (gulong *data, int icon_count, int num, int *iw, int *ih,
|
||||
while (i--) {
|
||||
w = data[pos++];
|
||||
h = data[pos++];
|
||||
if (pos + w * h > num) break;
|
||||
if (pos + w * h > num)
|
||||
break;
|
||||
|
||||
width[i] = w;
|
||||
height[i] = h;
|
||||
@@ -319,44 +297,3 @@ gulong *get_best_icon (gulong *data, int icon_count, int num, int *iw, int *ih,
|
||||
*ih = height[icon_num];
|
||||
return icon_data[icon_num];
|
||||
}
|
||||
|
||||
|
||||
void get_text_size2(PangoFontDescription *font,
|
||||
int *height_ink,
|
||||
int *height,
|
||||
int *width,
|
||||
int panel_height,
|
||||
int panel_width,
|
||||
char *text,
|
||||
int len,
|
||||
PangoWrapMode wrap,
|
||||
PangoEllipsizeMode ellipsis)
|
||||
{
|
||||
PangoRectangle rect_ink, rect;
|
||||
|
||||
Pixmap pmap = XCreatePixmap (server.dsp, server.root_win, panel_height, panel_width, server.depth);
|
||||
|
||||
cairo_surface_t *cs = cairo_xlib_surface_create (server.dsp, pmap, server.visual, panel_height, panel_width);
|
||||
cairo_t *c = cairo_create (cs);
|
||||
|
||||
PangoLayout *layout = pango_cairo_create_layout (c);
|
||||
pango_layout_set_width(layout, panel_width * PANGO_SCALE);
|
||||
pango_layout_set_height(layout, panel_height * PANGO_SCALE);
|
||||
pango_layout_set_wrap(layout, wrap);
|
||||
pango_layout_set_ellipsize(layout, ellipsis);
|
||||
pango_layout_set_font_description (layout, font);
|
||||
pango_layout_set_text (layout, text, len);
|
||||
|
||||
pango_layout_get_pixel_extents(layout, &rect_ink, &rect);
|
||||
*height_ink = rect_ink.height;
|
||||
*height = rect.height;
|
||||
*width = rect.width;
|
||||
//printf("dimension : %d - %d\n", rect_ink.height, rect.height);
|
||||
|
||||
g_object_unref (layout);
|
||||
cairo_destroy (c);
|
||||
cairo_surface_destroy (cs);
|
||||
XFreePixmap (server.dsp, pmap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,38 +11,30 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <pango/pangocairo.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
GSList *get_desktop_names();
|
||||
int get_current_desktop();
|
||||
void change_desktop(int desktop);
|
||||
|
||||
Window get_active_window();
|
||||
|
||||
gboolean window_is_iconified(Window win);
|
||||
gboolean window_is_urgent(Window win);
|
||||
gboolean window_is_hidden(Window win);
|
||||
gboolean window_is_active(Window win);
|
||||
gboolean window_is_skip_taskbar(Window win);
|
||||
int get_window_desktop(Window win);
|
||||
int get_window_monitor(Window win);
|
||||
|
||||
void activate_window(Window win);
|
||||
void close_window(Window win);
|
||||
void get_window_coordinates(Window win, int *x, int *y, int *w, int *h);
|
||||
void toggle_window_maximized(Window win);
|
||||
void toggle_window_shade(Window win);
|
||||
void change_window_desktop(Window win, int desktop);
|
||||
|
||||
void set_active (Window win);
|
||||
void set_desktop (int desktop);
|
||||
void set_close (Window win);
|
||||
int server_get_current_desktop ();
|
||||
GSList *server_get_name_of_desktop ();
|
||||
void window_get_coordinates (Window win, int *x, int *y, int *w, int *h);
|
||||
int window_is_iconified (Window win);
|
||||
int window_is_urgent (Window win);
|
||||
int window_is_hidden (Window win);
|
||||
int window_is_active (Window win);
|
||||
int window_is_skip_taskbar (Window win);
|
||||
int get_icon_count(gulong *data, int num);
|
||||
gulong *get_best_icon(gulong *data, int icon_count, int num, int *iw, int *ih, int best_icon_size);
|
||||
void window_maximize_restore (Window win);
|
||||
void window_toggle_shade (Window win);
|
||||
int window_get_desktop (Window win);
|
||||
void windows_set_desktop (Window win, int desktop);
|
||||
int window_get_monitor (Window win);
|
||||
Window window_get_active ();
|
||||
|
||||
void get_text_size2(PangoFontDescription *font,
|
||||
int *height_ink,
|
||||
int *height,
|
||||
int *width,
|
||||
int panel_height,
|
||||
int panel_with,
|
||||
char *text,
|
||||
int len,
|
||||
PangoWrapMode wrap,
|
||||
PangoEllipsizeMode ellipsis);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -160,3 +160,4 @@ src/battery/linux.c
|
||||
src/battery/openbsd.c
|
||||
src/util/uevent.c
|
||||
src/util/uevent.h
|
||||
.clang-format
|
||||
|
||||
Reference in New Issue
Block a user