Cleanup indentation with clang-format and changed a few variable names
This commit is contained in:
parent
c0e62e2e79
commit
4a6937826c
51 changed files with 4145 additions and 3789 deletions
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,10 +34,10 @@
|
|||
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;
|
||||
static timeout *battery_timeout;
|
||||
|
||||
static char buf_bat_percentage[10];
|
||||
static char buf_bat_time[20];
|
||||
|
@ -54,7 +54,7 @@ char *battery_uwheel_command;
|
|||
char *battery_dwheel_command;
|
||||
int battery_found;
|
||||
|
||||
void update_battery_tick(void* arg)
|
||||
void update_battery_tick(void *arg)
|
||||
{
|
||||
if (!battery_enabled)
|
||||
return;
|
||||
|
@ -64,7 +64,7 @@ void update_battery_tick(void* arg)
|
|||
gboolean old_ac_connected = battery_state.ac_connected;
|
||||
int16_t old_hours = battery_state.time.hours;
|
||||
int8_t old_minutes = battery_state.time.minutes;
|
||||
|
||||
|
||||
if (!battery_found) {
|
||||
init_battery();
|
||||
old_ac_connected = battery_state.ac_connected;
|
||||
|
@ -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,13 +196,14 @@ void init_battery()
|
|||
update_battery();
|
||||
}
|
||||
|
||||
char* battery_get_tooltip(void* obj) {
|
||||
char *battery_get_tooltip(void *obj)
|
||||
{
|
||||
return battery_os_tooltip();
|
||||
}
|
||||
|
||||
void init_battery_panel(void *p)
|
||||
{
|
||||
Panel *panel = (Panel*)p;
|
||||
Panel *panel = (Panel *)p;
|
||||
Battery *battery = &panel->battery;
|
||||
|
||||
if (!battery_enabled)
|
||||
|
@ -217,28 +214,25 @@ 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;
|
||||
battery->area.panel = 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.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_press_effect = battery->area.has_mouse_over_effect;
|
||||
battery->area.size_mode = LAYOUT_FIXED;
|
||||
battery->area._resize = resize_battery;
|
||||
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_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,13 +251,12 @@ int update_battery() {
|
|||
return err;
|
||||
}
|
||||
|
||||
|
||||
void draw_battery (void *obj, cairo_t *c)
|
||||
void draw_battery(void *obj, cairo_t *c)
|
||||
{
|
||||
Battery *battery = obj;
|
||||
PangoLayout *layout;
|
||||
|
||||
layout = pango_cairo_create_layout (c);
|
||||
layout = pango_cairo_create_layout(c);
|
||||
|
||||
// draw layout
|
||||
pango_layout_set_font_description(layout, bat1_font_desc);
|
||||
|
@ -273,10 +266,10 @@ void draw_battery (void *obj, cairo_t *c)
|
|||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
||||
pango_layout_set_text(layout, buf_bat_percentage, strlen(buf_bat_percentage));
|
||||
|
||||
cairo_set_source_rgba(c, battery->font.rgb[0], battery->font.rgb[1], battery->font.rgb[2], battery->font.alpha);
|
||||
cairo_set_source_rgba(c, battery->font.rgb[0], battery->font.rgb[1], battery->font.rgb[2], battery->font.alpha);
|
||||
|
||||
pango_cairo_update_layout(c, layout);
|
||||
draw_text(layout, c, 0, battery->bat1_posy, &battery->font, ((Panel*)battery->area.panel)->font_shadow);
|
||||
draw_text(layout, c, 0, battery->bat1_posy, &battery->font, ((Panel *)battery->area.panel)->font_shadow);
|
||||
|
||||
pango_layout_set_font_description(layout, bat2_font_desc);
|
||||
pango_layout_set_indent(layout, 0);
|
||||
|
@ -286,14 +279,13 @@ void draw_battery (void *obj, cairo_t *c)
|
|||
pango_layout_set_width(layout, battery->area.width * PANGO_SCALE);
|
||||
|
||||
pango_cairo_update_layout(c, layout);
|
||||
draw_text(layout, c, 0, battery->bat2_posy, &battery->font, ((Panel*)battery->area.panel)->font_shadow);
|
||||
draw_text(layout, c, 0, battery->bat2_posy, &battery->font, ((Panel *)battery->area.panel)->font_shadow);
|
||||
pango_cairo_show_layout(c, layout);
|
||||
|
||||
g_object_unref(layout);
|
||||
}
|
||||
|
||||
|
||||
int resize_battery(void *obj)
|
||||
gboolean resize_battery(void *obj)
|
||||
{
|
||||
Battery *battery = obj;
|
||||
Panel *panel = battery->area.panel;
|
||||
|
@ -301,28 +293,39 @@ 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) {
|
||||
strcpy(buf_bat_time, "Full");
|
||||
} 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,11 +333,10 @@ 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) {
|
||||
battery->area.height = new_size;
|
||||
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;
|
||||
ret = 1;
|
||||
|
@ -347,19 +349,19 @@ void battery_action(int button)
|
|||
{
|
||||
char *command = 0;
|
||||
switch (button) {
|
||||
case 1:
|
||||
case 1:
|
||||
command = battery_lclick_command;
|
||||
break;
|
||||
case 2:
|
||||
case 2:
|
||||
command = battery_mclick_command;
|
||||
break;
|
||||
case 3:
|
||||
case 3:
|
||||
command = battery_rclick_command;
|
||||
break;
|
||||
case 4:
|
||||
case 4:
|
||||
command = battery_uwheel_command;
|
||||
break;
|
||||
case 5:
|
||||
case 5:
|
||||
command = battery_dwheel_command;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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,21 +60,23 @@ extern char *battery_rclick_command;
|
|||
extern char *battery_uwheel_command;
|
||||
extern char *battery_dwheel_command;
|
||||
|
||||
static inline gchar* chargestate2str(enum chargestate state) {
|
||||
switch(state) {
|
||||
case BATTERY_CHARGING:
|
||||
return "Charging";
|
||||
case BATTERY_DISCHARGING:
|
||||
return "Discharging";
|
||||
case BATTERY_FULL:
|
||||
return "Full";
|
||||
case BATTERY_UNKNOWN:
|
||||
default:
|
||||
return "Unknown";
|
||||
static inline gchar *chargestate2str(enum chargestate state)
|
||||
{
|
||||
switch (state) {
|
||||
case BATTERY_CHARGING:
|
||||
return "Charging";
|
||||
case BATTERY_DISCHARGING:
|
||||
return "Discharging";
|
||||
case BATTERY_FULL:
|
||||
return "Full";
|
||||
case BATTERY_UNKNOWN:
|
||||
default:
|
||||
return "Unknown";
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -94,7 +90,7 @@ void default_battery();
|
|||
// freed memory
|
||||
void cleanup_battery();
|
||||
|
||||
void update_battery_tick(void* arg);
|
||||
void update_battery_tick(void *arg);
|
||||
int update_battery();
|
||||
|
||||
void init_battery();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -111,6 +107,6 @@ void battery_action(int button);
|
|||
gboolean battery_os_init();
|
||||
void battery_os_free();
|
||||
int battery_os_update(struct batstate *state);
|
||||
char* battery_os_tooltip();
|
||||
char *battery_os_tooltip();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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,26 +24,29 @@
|
|||
#include "common.h"
|
||||
#include "battery.h"
|
||||
|
||||
gboolean battery_os_init() {
|
||||
gboolean battery_os_init()
|
||||
{
|
||||
int sysctl_out = 0;
|
||||
size_t len = sizeof(sysctl_out);
|
||||
|
||||
return (sysctlbyname("hw.acpi.battery.state", &sysctl_out, &len, NULL, 0) == 0) ||
|
||||
(sysctlbyname("hw.acpi.battery.time", &sysctl_out, &len, NULL, 0) == 0) ||
|
||||
(sysctlbyname("hw.acpi.battery.life", &sysctl_out, &len, NULL, 0) == 0);
|
||||
(sysctlbyname("hw.acpi.battery.time", &sysctl_out, &len, NULL, 0) == 0) ||
|
||||
(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;
|
||||
|
||||
if (sysctlbyname("hw.acpi.battery.state", &sysctl_out, &len, NULL, 0) == 0) {
|
||||
switch(sysctl_out) {
|
||||
switch (sysctl_out) {
|
||||
case 1:
|
||||
state->state = BATTERY_DISCHARGING;
|
||||
break;
|
||||
|
@ -71,11 +74,12 @@ int battery_os_update(struct batstate *state) {
|
|||
|
||||
if (sysctlbyname("hw.acpi.acline", &sysctl_out, &len, NULL, 0) == 0)
|
||||
state->ac_connected = sysctl_out;
|
||||
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
char* battery_os_tooltip() {
|
||||
char *battery_os_tooltip()
|
||||
{
|
||||
GString *tooltip = g_string_new("");
|
||||
gchar *result;
|
||||
|
||||
|
|
|
@ -33,65 +33,63 @@ enum psy_type {
|
|||
|
||||
struct psy_battery {
|
||||
/* generic properties */
|
||||
gchar* name;
|
||||
gint64 timestamp;
|
||||
gchar *name;
|
||||
gint64 timestamp;
|
||||
/* sysfs files */
|
||||
gchar* path_present;
|
||||
gchar* path_energy_now;
|
||||
gchar* path_energy_full;
|
||||
gchar* path_power_now;
|
||||
gchar* path_status;
|
||||
gchar *path_present;
|
||||
gchar *path_energy_now;
|
||||
gchar *path_energy_full;
|
||||
gchar *path_power_now;
|
||||
gchar *path_status;
|
||||
/* sysfs hints */
|
||||
gboolean energy_in_uamp;
|
||||
gboolean power_in_uamp;
|
||||
gboolean energy_in_uamp;
|
||||
gboolean power_in_uamp;
|
||||
/* values */
|
||||
gboolean present;
|
||||
gint energy_now;
|
||||
gint energy_full;
|
||||
gint power_now;
|
||||
enum chargestate status;
|
||||
gboolean present;
|
||||
gint energy_now;
|
||||
gint energy_full;
|
||||
gint power_now;
|
||||
enum chargestate status;
|
||||
};
|
||||
|
||||
struct psy_mains {
|
||||
/* generic properties */
|
||||
gchar* name;
|
||||
gchar *name;
|
||||
/* sysfs files */
|
||||
gchar* path_online;
|
||||
gchar *path_online;
|
||||
/* values */
|
||||
gboolean online;
|
||||
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;
|
||||
|
@ -260,15 +266,15 @@ gboolean battery_os_init() {
|
|||
while ((entryname = g_dir_read_name(directory))) {
|
||||
enum psy_type type = power_supply_get_type(entryname);
|
||||
|
||||
switch(type) {
|
||||
case PSY_BATTERY:
|
||||
add_battery(entryname);
|
||||
break;
|
||||
case PSY_MAINS:
|
||||
add_mains(entryname);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (type) {
|
||||
case PSY_BATTERY:
|
||||
add_battery(entryname);
|
||||
break;
|
||||
case PSY_MAINS:
|
||||
add_mains(entryname);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
unit);
|
||||
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,
|
||||
unit);
|
||||
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;
|
||||
|
@ -50,8 +49,7 @@ static char buf_time[256];
|
|||
static char buf_date[256];
|
||||
static char buf_tooltip[512];
|
||||
int clock_enabled;
|
||||
static timeout* clock_timeout;
|
||||
|
||||
static timeout *clock_timeout;
|
||||
|
||||
void default_clock()
|
||||
{
|
||||
|
@ -104,19 +102,18 @@ void cleanup_clock()
|
|||
clock_timeout = NULL;
|
||||
}
|
||||
|
||||
|
||||
void update_clocks_sec(void* arg)
|
||||
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)
|
||||
void update_clocks_min(void *arg)
|
||||
{
|
||||
// remember old_sec because after suspend/hibernate the clock should be updated directly, and not
|
||||
// on next minute change
|
||||
|
@ -125,26 +122,29 @@ 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");
|
||||
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");
|
||||
struct tm *result = localtime(&time_clock.tv_sec);
|
||||
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)
|
||||
char *clock_get_tooltip(void *obj)
|
||||
{
|
||||
strftime(buf_tooltip, sizeof(buf_tooltip), time_tooltip_format, clock_gettime_for_tz(time_tooltip_timezone));
|
||||
return strdup(buf_tooltip);
|
||||
|
@ -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,12 +170,11 @@ void init_clock()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void init_clock_panel(void *p)
|
||||
{
|
||||
Panel *panel =(Panel*)p;
|
||||
Panel *panel = (Panel *)p;
|
||||
Clock *clock = &panel->clock;
|
||||
|
||||
|
||||
if (!time1_font_desc)
|
||||
time1_font_desc = pango_font_description_from_string(DEFAULT_FONT);
|
||||
if (!time2_font_desc)
|
||||
|
@ -185,20 +183,18 @@ 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_dwheel_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;
|
||||
clock->area._resize = resize_clock;
|
||||
clock->area.size_mode = LAYOUT_FIXED;
|
||||
clock->area._resize = resize_clock;
|
||||
// check consistency
|
||||
if (!time1_format)
|
||||
return;
|
||||
|
||||
clock->area.resize_needed = 1;
|
||||
clock->area.on_screen = 1;
|
||||
clock->area.resize_needed = 1;
|
||||
clock->area.on_screen = TRUE;
|
||||
|
||||
if (time_tooltip_format) {
|
||||
clock->area._get_tooltip_text = clock_get_tooltip;
|
||||
|
@ -206,83 +202,94 @@ void init_clock_panel(void *p)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void draw_clock (void *obj, cairo_t *c)
|
||||
void draw_clock(void *obj, cairo_t *c)
|
||||
{
|
||||
Clock *clock = obj;
|
||||
PangoLayout *layout;
|
||||
|
||||
layout = pango_cairo_create_layout (c);
|
||||
layout = pango_cairo_create_layout(c);
|
||||
|
||||
// draw layout
|
||||
pango_layout_set_font_description (layout, time1_font_desc);
|
||||
pango_layout_set_width (layout, clock->area.width * PANGO_SCALE);
|
||||
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
|
||||
pango_layout_set_font_description(layout, time1_font_desc);
|
||||
pango_layout_set_width(layout, clock->area.width * PANGO_SCALE);
|
||||
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
|
||||
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
||||
pango_layout_set_text (layout, buf_time, strlen(buf_time));
|
||||
pango_layout_set_text(layout, buf_time, strlen(buf_time));
|
||||
|
||||
cairo_set_source_rgba (c, clock->font.rgb[0], clock->font.rgb[1], clock->font.rgb[2], clock->font.alpha);
|
||||
cairo_set_source_rgba(c, clock->font.rgb[0], clock->font.rgb[1], clock->font.rgb[2], clock->font.alpha);
|
||||
|
||||
pango_cairo_update_layout (c, layout);
|
||||
draw_text(layout, c, 0, clock->time1_posy, &clock->font, ((Panel*)clock->area.panel)->font_shadow);
|
||||
pango_cairo_update_layout(c, layout);
|
||||
draw_text(layout, c, 0, clock->time1_posy, &clock->font, ((Panel *)clock->area.panel)->font_shadow);
|
||||
|
||||
if (time2_format) {
|
||||
pango_layout_set_font_description (layout, time2_font_desc);
|
||||
pango_layout_set_font_description(layout, time2_font_desc);
|
||||
pango_layout_set_indent(layout, 0);
|
||||
pango_layout_set_text (layout, buf_date, strlen(buf_date));
|
||||
pango_layout_set_width (layout, clock->area.width * PANGO_SCALE);
|
||||
pango_layout_set_text(layout, buf_date, strlen(buf_date));
|
||||
pango_layout_set_width(layout, clock->area.width * PANGO_SCALE);
|
||||
|
||||
pango_cairo_update_layout (c, layout);
|
||||
draw_text(layout, c, 0, clock->time2_posy, &clock->font, ((Panel*)clock->area.panel)->font_shadow);
|
||||
pango_cairo_update_layout(c, layout);
|
||||
draw_text(layout, c, 0, clock->time2_posy, &clock->font, ((Panel *)clock->area.panel)->font_shadow);
|
||||
}
|
||||
|
||||
g_object_unref (layout);
|
||||
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);
|
||||
}
|
||||
|
||||
if (panel_horizontal) {
|
||||
int new_size = (time_width > date_width) ? time_width : date_width;
|
||||
new_size += (2*clock->area.paddingxlr) + (2*clock->area.bg->border.width);
|
||||
if (new_size > clock->area.width || new_size < (clock->area.width-6)) {
|
||||
// we try to limit the number of resizes
|
||||
new_size += (2 * clock->area.paddingxlr) + (2 * clock->area.bg->border.width);
|
||||
if (new_size > clock->area.width || new_size < (clock->area.width - 6)) {
|
||||
// we try to limit the number of resizes
|
||||
clock->area.width = new_size + 1;
|
||||
clock->time1_posy = (clock->area.height - time_height) / 2;
|
||||
if (time2_format) {
|
||||
clock->time1_posy -= (date_height)/2;
|
||||
clock->time1_posy -= (date_height) / 2;
|
||||
clock->time2_posy = clock->time1_posy + time_height;
|
||||
}
|
||||
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
|
||||
clock->area.height = new_size;
|
||||
// we try to limit the number of resizes
|
||||
clock->area.height = new_size;
|
||||
clock->time1_posy = (clock->area.height - time_height) / 2;
|
||||
if (time2_format) {
|
||||
clock->time1_posy -= (date_height)/2;
|
||||
clock->time1_posy -= (date_height) / 2;
|
||||
clock->time2_posy = clock->time1_posy + time_height;
|
||||
}
|
||||
ret = 1;
|
||||
|
@ -292,27 +299,25 @@ int resize_clock (void *obj)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void clock_action(int button)
|
||||
{
|
||||
char *command = 0;
|
||||
switch (button) {
|
||||
case 1:
|
||||
case 1:
|
||||
command = clock_lclick_command;
|
||||
break;
|
||||
case 2:
|
||||
case 2:
|
||||
command = clock_mclick_command;
|
||||
break;
|
||||
case 3:
|
||||
case 3:
|
||||
command = clock_rclick_command;
|
||||
break;
|
||||
case 4:
|
||||
case 4:
|
||||
command = clock_uwheel_command;
|
||||
break;
|
||||
case 5:
|
||||
case 5:
|
||||
command = clock_dwheel_command;
|
||||
break;
|
||||
}
|
||||
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();
|
||||
|
||||
|
@ -50,9 +47,9 @@ void cleanup_clock();
|
|||
void init_clock();
|
||||
void init_clock_panel(void *panel);
|
||||
|
||||
void draw_clock (void *obj, cairo_t *c);
|
||||
void draw_clock(void *obj, cairo_t *c);
|
||||
|
||||
int resize_clock (void *obj);
|
||||
gboolean resize_clock(void *obj);
|
||||
|
||||
void clock_action(int button);
|
||||
|
||||
|
|
907
src/config.c
907
src/config.c
File diff suppressed because it is too large
Load diff
|
@ -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>
|
||||
|
@ -33,20 +32,21 @@
|
|||
|
||||
void init_freespace_panel(void *p)
|
||||
{
|
||||
Panel *panel = (Panel*)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,9 +70,10 @@ int freespace_get_max_size(Panel *p) {
|
|||
return size;
|
||||
}
|
||||
|
||||
int resize_freespace(void *obj) {
|
||||
FreeSpace *freespace = (FreeSpace*)obj;
|
||||
Panel *panel = (Panel*)freespace->area.panel;
|
||||
gboolean resize_freespace(void *obj)
|
||||
{
|
||||
FreeSpace *freespace = (FreeSpace *)obj;
|
||||
Panel *panel = (Panel *)freespace->area.panel;
|
||||
if (!freespace->area.on_screen)
|
||||
return 0;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -160,7 +167,7 @@ int read_desktop_file(const char *path, DesktopEntry *entry)
|
|||
}
|
||||
}
|
||||
}
|
||||
fclose (fp);
|
||||
fclose(fp);
|
||||
// From this point:
|
||||
// entry->name, entry->icon, entry->exec will never be empty strings (can be NULL though)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -76,8 +75,8 @@ IconTheme *make_theme(char *name)
|
|||
return theme;
|
||||
}
|
||||
|
||||
//TODO Use UTF8 when parsing the file
|
||||
IconTheme *load_theme_from_index(char *file_name, char *name)
|
||||
// TODO Use UTF8 when parsing the file
|
||||
IconTheme *load_theme_from_index(const char *file_name, const char *name)
|
||||
{
|
||||
IconTheme *theme;
|
||||
FILE *f;
|
||||
|
@ -168,9 +167,8 @@ IconTheme *load_theme_from_index(char *file_name, char *name)
|
|||
current_dir = NULL;
|
||||
line[line_len - 1] = '\0';
|
||||
char *dir_name = line + 1;
|
||||
GSList* dir_item = theme->list_directories;
|
||||
while (dir_item != NULL)
|
||||
{
|
||||
GSList *dir_item = theme->list_directories;
|
||||
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,12 +224,11 @@ 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)) {
|
||||
gchar *path = (gchar*) location->data;
|
||||
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)) {
|
||||
if (!theme) {
|
||||
|
@ -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,9 +253,8 @@ 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)) {
|
||||
gchar *path = (gchar*) location->data;
|
||||
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)) {
|
||||
g_free(file_name);
|
||||
|
@ -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,15 +297,14 @@ void free_themes(IconThemeWrapper *themes)
|
|||
{
|
||||
if (!themes)
|
||||
return;
|
||||
GSList *l;
|
||||
for (l = themes->themes; l ; l = l->next) {
|
||||
IconTheme *theme = (IconTheme*) l->data;
|
||||
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) {
|
||||
IconTheme *theme = (IconTheme*) l->data;
|
||||
for (GSList *l = themes->themes_fallback; l; l = l->next) {
|
||||
IconTheme *theme = (IconTheme *)l->data;
|
||||
free_icon_theme(theme);
|
||||
free(theme);
|
||||
}
|
||||
|
@ -328,21 +321,24 @@ void test_launcher_read_theme_file()
|
|||
return;
|
||||
}
|
||||
printf("Loaded theme: %s\n", theme->name);
|
||||
GSList* item = theme->list_inherits;
|
||||
while (item != NULL)
|
||||
{
|
||||
printf("Inherits:%s\n", (char*)item->data);
|
||||
GSList *item = theme->list_inherits;
|
||||
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");
|
||||
|
@ -350,7 +346,7 @@ void test_launcher_read_theme_file()
|
|||
|
||||
gboolean str_list_contains(const GSList *list, const char *value)
|
||||
{
|
||||
const GSList* item = list;
|
||||
const GSList *item = list;
|
||||
while (item != NULL) {
|
||||
if (g_str_equal(item->data, value)) {
|
||||
return TRUE;
|
||||
|
@ -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;
|
||||
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,13 +386,13 @@ void load_themes_helper(const char *name, GSList **themes, GSList **queued)
|
|||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
free(queued_name);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
// Free the queue
|
||||
GSList *l;
|
||||
for (l = queue; l ; l = l->next)
|
||||
for (l = queue; l; l = l->next)
|
||||
free(l->data);
|
||||
g_slist_free(queue);
|
||||
}
|
||||
|
@ -420,14 +415,13 @@ IconThemeWrapper *load_themes(const char *icon_theme_name)
|
|||
// Load wrapper->themes_fallback
|
||||
const GSList *location;
|
||||
for (location = get_icon_locations(); location; location = g_slist_next(location)) {
|
||||
gchar *path = (gchar*) location->data;
|
||||
gchar *path = (gchar *)location->data;
|
||||
GDir *d = g_dir_open(path, 0, NULL);
|
||||
if (d) {
|
||||
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);
|
||||
|
@ -438,7 +432,7 @@ IconThemeWrapper *load_themes(const char *icon_theme_name)
|
|||
|
||||
// Free the queued list
|
||||
GSList *l;
|
||||
for (l = queued; l ; l = l->next)
|
||||
for (l = queued; l; l = l->next)
|
||||
free(l->data);
|
||||
g_slist_free(queued);
|
||||
|
||||
|
@ -482,8 +476,8 @@ int directory_size_distance(IconThemeDir *dir, int size)
|
|||
gint compare_theme_directories(gconstpointer a, gconstpointer b, gpointer size_query)
|
||||
{
|
||||
int size = GPOINTER_TO_INT(size_query);
|
||||
const IconThemeDir *da = (const IconThemeDir*)a;
|
||||
const IconThemeDir *db = (const IconThemeDir*)b;
|
||||
const IconThemeDir *da = (const IconThemeDir *)a;
|
||||
const IconThemeDir *db = (const IconThemeDir *)b;
|
||||
return abs(da->size - size) - abs(db->size - size);
|
||||
}
|
||||
|
||||
|
@ -509,9 +503,8 @@ 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)) {
|
||||
char *extension = (char*) ext->data;
|
||||
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) {
|
||||
extensions = g_slist_append(extensions, "");
|
||||
|
@ -540,33 +533,33 @@ 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,
|
||||
compare_theme_directories,
|
||||
GINT_TO_POINTER(size));
|
||||
((IconTheme *)theme->data)->list_directories =
|
||||
g_slist_sort_with_data(((IconTheme *)theme->data)->list_directories,
|
||||
compare_theme_directories,
|
||||
GINT_TO_POINTER(size));
|
||||
GSList *dir;
|
||||
for (dir = ((IconTheme*)theme->data)->list_directories; dir; dir = g_slist_next(dir)) {
|
||||
for (dir = ((IconTheme *)theme->data)->list_directories; dir; dir = g_slist_next(dir)) {
|
||||
// Closest match
|
||||
gboolean possible = directory_size_distance((IconThemeDir*)dir->data, size) < minimal_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 &&
|
||||
(next_larger_size == -1 || ((IconThemeDir*)dir->data)->size < next_larger_size) &&
|
||||
(!next_larger_theme ? 1 : theme == next_larger_theme));
|
||||
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)) {
|
||||
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;
|
||||
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;
|
||||
file_name = realloc(file_name, file_name_size);
|
||||
}
|
||||
file_name[0] = 0;
|
||||
|
@ -578,27 +571,28 @@ 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;
|
||||
}
|
||||
best_file_name = strdup(file_name);
|
||||
minimal_size = directory_size_distance((IconThemeDir*)dir->data, size);
|
||||
minimal_size = directory_size_distance((IconThemeDir *)dir->data, size);
|
||||
best_file_theme = theme;
|
||||
if (DEBUG_ICON_SEARCH)
|
||||
printf("best_file_name = %s; minimal_size = %d\n", best_file_name, minimal_size);
|
||||
}
|
||||
// Next larger match
|
||||
if (((IconThemeDir*)dir->data)->size >= size &&
|
||||
(next_larger_size == -1 || ((IconThemeDir*)dir->data)->size < next_larger_size) &&
|
||||
if (((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 (next_larger) {
|
||||
free(next_larger);
|
||||
next_larger = NULL;
|
||||
}
|
||||
next_larger = strdup(file_name);
|
||||
next_larger_size = ((IconThemeDir*)dir->data)->size;
|
||||
next_larger_size = ((IconThemeDir *)dir->data)->size;
|
||||
next_larger_theme = theme;
|
||||
if (DEBUG_ICON_SEARCH)
|
||||
printf("next_larger = %s; next_larger_size = %d\n", next_larger, next_larger_size);
|
||||
|
@ -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)) {
|
||||
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);
|
||||
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;
|
||||
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)
|
||||
|
|
|
@ -17,7 +17,7 @@ typedef struct IconThemeWrapper {
|
|||
|
||||
typedef struct IconTheme {
|
||||
char *name;
|
||||
GSList *list_inherits; // each item is a char* (theme name)
|
||||
GSList *list_inherits; // each item is a char* (theme name)
|
||||
GSList *list_directories; // each item is an IconThemeDir*
|
||||
} IconTheme;
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@ void default_launcher()
|
|||
launcher_icon_bg = NULL;
|
||||
}
|
||||
|
||||
|
||||
void init_launcher()
|
||||
{
|
||||
if (launcher_enabled) {
|
||||
|
@ -83,10 +82,9 @@ void init_launcher()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void init_launcher_panel(void *p)
|
||||
{
|
||||
Panel *panel =(Panel*)p;
|
||||
Panel *panel = (Panel *)p;
|
||||
Launcher *launcher = &panel->launcher;
|
||||
|
||||
launcher->area.parent = 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,13 +120,13 @@ 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);
|
||||
}
|
||||
|
||||
for (l = panel_config.launcher.list_apps; l ; l = l->next) {
|
||||
for (l = panel_config.launcher.list_apps; l; l = l->next) {
|
||||
free(l->data);
|
||||
}
|
||||
g_slist_free(panel_config.launcher.list_apps);
|
||||
|
@ -144,13 +141,12 @@ void cleanup_launcher()
|
|||
launcher_enabled = 0;
|
||||
}
|
||||
|
||||
|
||||
void cleanup_launcher_theme(Launcher *launcher)
|
||||
{
|
||||
free_area(&launcher->area);
|
||||
GSList *l;
|
||||
for (l = launcher->list_icons; l ; l = l->next) {
|
||||
LauncherIcon *launcherIcon = (LauncherIcon*)l->data;
|
||||
for (l = launcher->list_icons; l; l = l->next) {
|
||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||
if (launcherIcon) {
|
||||
free_icon(launcherIcon->image);
|
||||
free_icon(launcherIcon->image_hover);
|
||||
|
@ -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;
|
||||
|
@ -187,7 +182,7 @@ int resize_launcher(void *obj)
|
|||
icon_size = launcher_max_icon_size;
|
||||
|
||||
// Resize icons if necessary
|
||||
for (l = launcher->list_icons; l ; l = l->next) {
|
||||
for (l = launcher->list_icons; l; l = l->next) {
|
||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||
if (launcherIcon->icon_size != icon_size || !launcherIcon->image) {
|
||||
launcherIcon->icon_size = icon_size;
|
||||
|
@ -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,46 +230,47 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
count = g_slist_length(launcher->list_icons);
|
||||
|
||||
if (panel_horizontal) {
|
||||
if (!count) {
|
||||
launcher->area.width = 0;
|
||||
} else {
|
||||
int height = launcher->area.height - 2*launcher->area.bg->border.width - 2*launcher->area.paddingy;
|
||||
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;
|
||||
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);
|
||||
icons_per_column = (height + launcher->area.paddingx) / (icon_size + launcher->area.paddingx);
|
||||
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);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (!count) {
|
||||
launcher->area.height = 0;
|
||||
} else {
|
||||
int width = launcher->area.width - 2*launcher->area.bg->border.width - 2*launcher->area.paddingy;
|
||||
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;
|
||||
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);
|
||||
icons_per_row = (width + launcher->area.paddingx) / (icon_size + launcher->area.paddingx);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -282,16 +279,16 @@ int resize_launcher(void *obj)
|
|||
posy = launcher->area.bg->border.width + launcher->area.paddingxlr;
|
||||
}
|
||||
|
||||
for (i=1, l = launcher->list_icons; l ; i++, l = l->next) {
|
||||
LauncherIcon *launcherIcon = (LauncherIcon*)l->data;
|
||||
|
||||
for (i = 1, l = launcher->list_icons; l; i++, l = l->next) {
|
||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||
|
||||
launcherIcon->y = posy;
|
||||
launcherIcon->x = posx;
|
||||
launcherIcon->area.posy = ((Area*)launcherIcon->area.parent)->posy + launcherIcon->y;
|
||||
launcherIcon->area.posx = ((Area*)launcherIcon->area.parent)->posx + launcherIcon->x;
|
||||
launcherIcon->area.posy = ((Area *)launcherIcon->area.parent)->posy + launcherIcon->y;
|
||||
launcherIcon->area.posx = ((Area *)launcherIcon->area.parent)->posx + launcherIcon->x;
|
||||
launcherIcon->area.width = launcherIcon->icon_size;
|
||||
launcherIcon->area.height = launcherIcon->icon_size;
|
||||
//printf("launcher %d : %d,%d\n", i, posx, posy);
|
||||
// printf("launcher %d : %d,%d\n", i, posx, posy);
|
||||
if (panel_horizontal) {
|
||||
if (i % icons_per_column) {
|
||||
posy += icon_size + launcher->area.paddingx;
|
||||
|
@ -316,22 +313,22 @@ int resize_launcher(void *obj)
|
|||
// in a stack; we need to layout them in a kind of table
|
||||
void launcher_icon_on_change_layout(void *obj)
|
||||
{
|
||||
LauncherIcon *launcherIcon = (LauncherIcon*)obj;
|
||||
launcherIcon->area.posy = ((Area*)launcherIcon->area.parent)->posy + launcherIcon->y;
|
||||
launcherIcon->area.posx = ((Area*)launcherIcon->area.parent)->posx + launcherIcon->x;
|
||||
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
||||
launcherIcon->area.posy = ((Area *)launcherIcon->area.parent)->posy + launcherIcon->y;
|
||||
launcherIcon->area.posx = ((Area *)launcherIcon->area.parent)->posx + launcherIcon->x;
|
||||
launcherIcon->area.width = launcherIcon->icon_size;
|
||||
launcherIcon->area.height = launcherIcon->icon_size;
|
||||
}
|
||||
|
||||
char* launcher_icon_get_tooltip_text(void *obj)
|
||||
char *launcher_icon_get_tooltip_text(void *obj)
|
||||
{
|
||||
LauncherIcon *launcherIcon = (LauncherIcon*)obj;
|
||||
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
||||
return strdup(launcherIcon->icon_tooltip);
|
||||
}
|
||||
|
||||
void draw_launcher_icon(void *obj, cairo_t *c)
|
||||
{
|
||||
LauncherIcon *launcherIcon = (LauncherIcon*)obj;
|
||||
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
||||
|
||||
Imlib_Image image;
|
||||
// Render
|
||||
|
@ -343,7 +340,7 @@ void draw_launcher_icon(void *obj, cairo_t *c)
|
|||
else
|
||||
image = launcherIcon->image;
|
||||
} else {
|
||||
image = launcherIcon->image;
|
||||
image = launcherIcon->image;
|
||||
}
|
||||
imlib_context_set_image(image);
|
||||
render_image(launcherIcon->area.pix, 0, 0);
|
||||
|
@ -353,19 +350,25 @@ 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);
|
||||
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);
|
||||
|
||||
imlib_context_set_image (icon_scaled);
|
||||
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);
|
||||
DATA32 *data = imlib_image_get_data();
|
||||
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);
|
||||
imlib_context_set_image(icon_scaled);
|
||||
} else {
|
||||
icon_scaled = imlib_create_image(icon_size, icon_size);
|
||||
imlib_context_set_image (icon_scaled);
|
||||
imlib_context_set_image(icon_scaled);
|
||||
imlib_context_set_color(255, 255, 255, 255);
|
||||
imlib_image_fill_rectangle(0, 0, icon_size, icon_size);
|
||||
}
|
||||
|
@ -380,18 +383,18 @@ void free_icon(Imlib_Image icon)
|
|||
}
|
||||
}
|
||||
|
||||
void launcher_action(LauncherIcon *icon, XEvent* evt)
|
||||
void launcher_action(LauncherIcon *icon, XEvent *evt)
|
||||
{
|
||||
char *cmd = calloc(strlen(icon->cmd) + 10, 1);
|
||||
sprintf(cmd, "(%s&)", icon->cmd);
|
||||
#if HAVE_SN
|
||||
SnLauncherContext* ctx = 0;
|
||||
SnLauncherContext *ctx = 0;
|
||||
Time time;
|
||||
if (startup_notifications) {
|
||||
ctx = sn_launcher_context_new(server.sn_dsp, server.screen);
|
||||
sn_launcher_context_set_name(ctx, icon->icon_tooltip);
|
||||
sn_launcher_context_set_description(ctx, "Application launched from tint2");
|
||||
sn_launcher_context_set_binary_name (ctx, icon->cmd);
|
||||
sn_launcher_context_set_binary_name(ctx, icon->cmd);
|
||||
// Get a timestamp from the X event
|
||||
if (evt->type == ButtonPress || evt->type == ButtonRelease) {
|
||||
time = evt->xbutton.time;
|
||||
|
@ -408,7 +411,7 @@ void launcher_action(LauncherIcon *icon, XEvent* evt)
|
|||
if (pid < 0) {
|
||||
fprintf(stderr, "Could not fork\n");
|
||||
} else if (pid == 0) {
|
||||
// Child process
|
||||
// Child process
|
||||
#if HAVE_SN
|
||||
if (startup_notifications) {
|
||||
sn_launcher_context_setup_child_process(ctx);
|
||||
|
@ -426,10 +429,10 @@ void launcher_action(LauncherIcon *icon, XEvent* evt)
|
|||
#endif // HAVE_SN
|
||||
exit(1);
|
||||
} else {
|
||||
// Parent process
|
||||
// Parent process
|
||||
#if HAVE_SN
|
||||
if (startup_notifications) {
|
||||
g_tree_insert(server.pids, GINT_TO_POINTER (pid), ctx);
|
||||
g_tree_insert(server.pids, GINT_TO_POINTER(pid), ctx);
|
||||
}
|
||||
#endif // HAVE_SN
|
||||
}
|
||||
|
@ -440,7 +443,7 @@ void launcher_action(LauncherIcon *icon, XEvent* evt)
|
|||
void launcher_load_icons(Launcher *launcher)
|
||||
{
|
||||
// Load apps (.desktop style launcher items)
|
||||
GSList* app = launcher->list_apps;
|
||||
GSList *app = launcher->list_apps;
|
||||
while (app != NULL) {
|
||||
DesktopEntry entry;
|
||||
read_desktop_file(app->data, &entry);
|
||||
|
@ -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;
|
||||
|
@ -469,25 +472,19 @@ void launcher_load_icons(Launcher *launcher)
|
|||
launcherIcon->icon_tooltip = entry.name ? strdup(entry.name) : strdup(entry.exec);
|
||||
free_desktop_entry(&entry);
|
||||
launcher->list_icons = g_slist_append(launcher->list_icons, launcherIcon);
|
||||
add_area(&launcherIcon->area, (Area*)launcher);
|
||||
add_area(&launcherIcon->area, (Area *)launcher);
|
||||
}
|
||||
app = g_slist_next(app);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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"));
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
typedef struct Launcher {
|
||||
// always start with area
|
||||
Area area;
|
||||
GSList *list_apps; // List of char*, each is a path to a app.desktop file
|
||||
GSList *list_icons; // List of LauncherIcon*
|
||||
GSList *list_apps; // List of char*, each is a path to a app.desktop file
|
||||
GSList *list_icons; // List of LauncherIcon*
|
||||
IconThemeWrapper *list_themes;
|
||||
} Launcher;
|
||||
|
||||
|
@ -41,7 +41,7 @@ extern int launcher_tooltip_enabled;
|
|||
extern int launcher_alpha;
|
||||
extern int launcher_saturation;
|
||||
extern int launcher_brightness;
|
||||
extern char *icon_theme_name_xsettings; // theme name
|
||||
extern char *icon_theme_name_xsettings; // theme name
|
||||
extern char *icon_theme_name_config;
|
||||
extern int launcher_icon_theme_override;
|
||||
extern XSettingsClient *xsettings_client;
|
||||
|
@ -57,14 +57,14 @@ void init_launcher_panel(void *panel);
|
|||
void cleanup_launcher();
|
||||
void cleanup_launcher_theme(Launcher *launcher);
|
||||
|
||||
int resize_launcher(void *obj);
|
||||
void draw_launcher (void *obj, cairo_t *c);
|
||||
gboolean resize_launcher(void *obj);
|
||||
void draw_launcher(void *obj, cairo_t *c);
|
||||
|
||||
// Populates the list_icons list
|
||||
void launcher_load_icons(Launcher *launcher);
|
||||
// Populates the list_themes list
|
||||
void launcher_load_themes(Launcher *launcher);
|
||||
void launcher_action(LauncherIcon *icon, XEvent* e);
|
||||
void launcher_action(LauncherIcon *icon, XEvent *e);
|
||||
|
||||
void test_launcher_read_desktop_file();
|
||||
void test_launcher_read_theme_file();
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Owen Taylor, Red Hat, Inc.
|
||||
|
@ -26,15 +26,14 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xmd.h> /* For CARD16 */
|
||||
#include <X11/Xmd.h> /* For CARD16 */
|
||||
|
||||
#include "xsettings-client.h"
|
||||
#include "server.h"
|
||||
#include "panel.h"
|
||||
#include "launcher.h"
|
||||
|
||||
struct _XSettingsClient
|
||||
{
|
||||
struct _XSettingsClient {
|
||||
Display *display;
|
||||
int screen;
|
||||
XSettingsNotifyFunc notify;
|
||||
|
@ -45,10 +44,9 @@ struct _XSettingsClient
|
|||
XSettingsList *settings;
|
||||
};
|
||||
|
||||
|
||||
void xsettings_notify_cb (const char *name, XSettingsAction action, XSettingsSetting *setting, void *data)
|
||||
void xsettings_notify_cb(const char *name, XSettingsAction action, XSettingsSetting *setting, void *data)
|
||||
{
|
||||
//printf("xsettings_notify_cb\n");
|
||||
// printf("xsettings_notify_cb\n");
|
||||
if ((action == XSETTINGS_ACTION_NEW || action == XSETTINGS_ACTION_CHANGED) && name != NULL && setting != NULL) {
|
||||
if (!strcmp(name, "Net/IconThemeName") && setting->type == XSETTINGS_TYPE_STRING) {
|
||||
if (icon_theme_name_xsettings) {
|
||||
|
@ -57,10 +55,10 @@ void xsettings_notify_cb (const char *name, XSettingsAction action, XSettingsSet
|
|||
free(icon_theme_name_xsettings);
|
||||
}
|
||||
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,8 +68,7 @@ void xsettings_notify_cb (const char *name, XSettingsAction action, XSettingsSet
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void notify_changes (XSettingsClient *client, XSettingsList *old_list)
|
||||
static void notify_changes(XSettingsClient *client, XSettingsList *old_list)
|
||||
{
|
||||
XSettingsList *old_iter = old_list;
|
||||
XSettingsList *new_iter = client->settings;
|
||||
|
@ -83,21 +80,19 @@ static void notify_changes (XSettingsClient *client, XSettingsList *old_list)
|
|||
int cmp;
|
||||
|
||||
if (old_iter && new_iter)
|
||||
cmp = strcmp (old_iter->setting->name, new_iter->setting->name);
|
||||
cmp = strcmp(old_iter->setting->name, new_iter->setting->name);
|
||||
else if (old_iter)
|
||||
cmp = -1;
|
||||
else
|
||||
cmp = 1;
|
||||
|
||||
if (cmp < 0) {
|
||||
client->notify (old_iter->setting->name, XSETTINGS_ACTION_DELETED, NULL, client->cb_data);
|
||||
}
|
||||
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 {
|
||||
client->notify (new_iter->setting->name, XSETTINGS_ACTION_NEW, new_iter->setting, client->cb_data);
|
||||
client->notify(old_iter->setting->name, XSETTINGS_ACTION_DELETED, NULL, client->cb_data);
|
||||
} 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 {
|
||||
client->notify(new_iter->setting->name, XSETTINGS_ACTION_NEW, new_iter->setting, client->cb_data);
|
||||
}
|
||||
|
||||
if (old_iter)
|
||||
|
@ -107,8 +102,7 @@ static void notify_changes (XSettingsClient *client, XSettingsList *old_list)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int ignore_errors (Display *display, XErrorEvent *event)
|
||||
static int ignore_errors(Display *display, XErrorEvent *event)
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
@ -117,11 +111,11 @@ static char local_byte_order = '\0';
|
|||
|
||||
#define BYTES_LEFT(buffer) ((buffer)->data + (buffer)->len - (buffer)->pos)
|
||||
|
||||
static XSettingsResult fetch_card16 (XSettingsBuffer *buffer, CARD16 *result)
|
||||
static XSettingsResult fetch_card16(XSettingsBuffer *buffer, CARD16 *result)
|
||||
{
|
||||
CARD16 x;
|
||||
|
||||
if (BYTES_LEFT (buffer) < 2)
|
||||
if (BYTES_LEFT(buffer) < 2)
|
||||
return XSETTINGS_ACCESS;
|
||||
|
||||
x = *(CARD16 *)buffer->pos;
|
||||
|
@ -135,25 +129,23 @@ static XSettingsResult fetch_card16 (XSettingsBuffer *buffer, CARD16 *result)
|
|||
return XSETTINGS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static XSettingsResult fetch_ushort (XSettingsBuffer *buffer, unsigned short *result)
|
||||
static XSettingsResult fetch_ushort(XSettingsBuffer *buffer, unsigned short *result)
|
||||
{
|
||||
CARD16 x;
|
||||
XSettingsResult r;
|
||||
XSettingsResult r;
|
||||
|
||||
r = fetch_card16 (buffer, &x);
|
||||
r = fetch_card16(buffer, &x);
|
||||
if (r == XSETTINGS_SUCCESS)
|
||||
*result = x;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static XSettingsResult fetch_card32 (XSettingsBuffer *buffer, CARD32 *result)
|
||||
static XSettingsResult fetch_card32(XSettingsBuffer *buffer, CARD32 *result)
|
||||
{
|
||||
CARD32 x;
|
||||
|
||||
if (BYTES_LEFT (buffer) < 4)
|
||||
if (BYTES_LEFT(buffer) < 4)
|
||||
return XSETTINGS_ACCESS;
|
||||
|
||||
x = *(CARD32 *)buffer->pos;
|
||||
|
@ -167,9 +159,9 @@ static XSettingsResult fetch_card32 (XSettingsBuffer *buffer, CARD32 *result)
|
|||
return XSETTINGS_SUCCESS;
|
||||
}
|
||||
|
||||
static XSettingsResult fetch_card8 (XSettingsBuffer *buffer, CARD8 *result)
|
||||
static XSettingsResult fetch_card8(XSettingsBuffer *buffer, CARD8 *result)
|
||||
{
|
||||
if (BYTES_LEFT (buffer) < 1)
|
||||
if (BYTES_LEFT(buffer) < 1)
|
||||
return XSETTINGS_ACCESS;
|
||||
|
||||
*result = *(CARD8 *)buffer->pos;
|
||||
|
@ -178,9 +170,9 @@ static XSettingsResult fetch_card8 (XSettingsBuffer *buffer, CARD8 *result)
|
|||
return XSETTINGS_SUCCESS;
|
||||
}
|
||||
|
||||
#define XSETTINGS_PAD(n,m) ((n + m - 1) & (~(m-1)))
|
||||
#define XSETTINGS_PAD(n, m) ((n + m - 1) & (~(m - 1)))
|
||||
|
||||
static XSettingsList *parse_settings (unsigned char *data, size_t len)
|
||||
static XSettingsList *parse_settings(unsigned char *data, size_t len)
|
||||
{
|
||||
XSettingsBuffer buffer;
|
||||
XSettingsResult result = XSETTINGS_SUCCESS;
|
||||
|
@ -190,26 +182,26 @@ static XSettingsList *parse_settings (unsigned char *data, size_t len)
|
|||
CARD32 i;
|
||||
XSettingsSetting *setting = NULL;
|
||||
|
||||
local_byte_order = xsettings_byte_order ();
|
||||
local_byte_order = xsettings_byte_order();
|
||||
|
||||
buffer.byte_order = local_byte_order;
|
||||
buffer.pos = buffer.data = data;
|
||||
buffer.len = len;
|
||||
|
||||
result = fetch_card8 (&buffer, (CARD8*)&buffer.byte_order);
|
||||
result = fetch_card8(&buffer, (CARD8 *)&buffer.byte_order);
|
||||
if (buffer.byte_order != MSBFirst && buffer.byte_order != LSBFirst) {
|
||||
fprintf (stderr, "Invalid byte order %x in XSETTINGS property\n", buffer.byte_order);
|
||||
fprintf(stderr, "Invalid byte order %x in XSETTINGS property\n", buffer.byte_order);
|
||||
result = XSETTINGS_FAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
buffer.pos += 3;
|
||||
|
||||
result = fetch_card32 (&buffer, &serial);
|
||||
result = fetch_card32(&buffer, &serial);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
|
||||
result = fetch_card32 (&buffer, &n_entries);
|
||||
result = fetch_card32(&buffer, &n_entries);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
|
||||
|
@ -219,131 +211,130 @@ static XSettingsList *parse_settings (unsigned char *data, size_t len)
|
|||
CARD32 v_int;
|
||||
size_t pad_len;
|
||||
|
||||
result = fetch_card8 (&buffer, &type);
|
||||
result = fetch_card8(&buffer, &type);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
|
||||
buffer.pos += 1;
|
||||
|
||||
result = fetch_card16 (&buffer, &name_len);
|
||||
result = fetch_card16(&buffer, &name_len);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
|
||||
pad_len = XSETTINGS_PAD(name_len, 4);
|
||||
if (BYTES_LEFT (&buffer) < pad_len) {
|
||||
if (BYTES_LEFT(&buffer) < pad_len) {
|
||||
result = XSETTINGS_ACCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
setting = calloc (1, sizeof *setting);
|
||||
setting = calloc(1, sizeof *setting);
|
||||
if (!setting) {
|
||||
result = XSETTINGS_NO_MEM;
|
||||
goto out;
|
||||
}
|
||||
setting->type = XSETTINGS_TYPE_INT; /* No allocated memory */
|
||||
|
||||
setting->name = calloc (name_len + 1, 1);
|
||||
setting->name = calloc(name_len + 1, 1);
|
||||
if (!setting->name) {
|
||||
result = XSETTINGS_NO_MEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy (setting->name, buffer.pos, name_len);
|
||||
memcpy(setting->name, buffer.pos, name_len);
|
||||
setting->name[name_len] = '\0';
|
||||
buffer.pos += pad_len;
|
||||
|
||||
result = fetch_card32 (&buffer, &v_int);
|
||||
result = fetch_card32(&buffer, &v_int);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
setting->last_change_serial = v_int;
|
||||
|
||||
switch (type) {
|
||||
case XSETTINGS_TYPE_INT:
|
||||
result = fetch_card32 (&buffer, &v_int);
|
||||
case XSETTINGS_TYPE_INT:
|
||||
result = fetch_card32(&buffer, &v_int);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
setting->data.v_int = (INT32)v_int;
|
||||
break;
|
||||
case XSETTINGS_TYPE_STRING:
|
||||
result = fetch_card32 (&buffer, &v_int);
|
||||
case XSETTINGS_TYPE_STRING:
|
||||
result = fetch_card32(&buffer, &v_int);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
|
||||
pad_len = XSETTINGS_PAD (v_int, 4);
|
||||
pad_len = XSETTINGS_PAD(v_int, 4);
|
||||
if (v_int + 1 == 0 || /* Guard against wrap-around */
|
||||
BYTES_LEFT (&buffer) < pad_len) {
|
||||
BYTES_LEFT(&buffer) < pad_len) {
|
||||
result = XSETTINGS_ACCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
setting->data.v_string = calloc (v_int + 1, 1);
|
||||
setting->data.v_string = calloc(v_int + 1, 1);
|
||||
if (!setting->data.v_string) {
|
||||
result = XSETTINGS_NO_MEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy (setting->data.v_string, buffer.pos, v_int);
|
||||
memcpy(setting->data.v_string, buffer.pos, v_int);
|
||||
setting->data.v_string[v_int] = '\0';
|
||||
buffer.pos += pad_len;
|
||||
break;
|
||||
case XSETTINGS_TYPE_COLOR:
|
||||
result = fetch_ushort (&buffer, &setting->data.v_color.red);
|
||||
case XSETTINGS_TYPE_COLOR:
|
||||
result = fetch_ushort(&buffer, &setting->data.v_color.red);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
result = fetch_ushort (&buffer, &setting->data.v_color.green);
|
||||
result = fetch_ushort(&buffer, &setting->data.v_color.green);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
result = fetch_ushort (&buffer, &setting->data.v_color.blue);
|
||||
result = fetch_ushort(&buffer, &setting->data.v_color.blue);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
result = fetch_ushort (&buffer, &setting->data.v_color.alpha);
|
||||
result = fetch_ushort(&buffer, &setting->data.v_color.alpha);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
/* Quietly ignore unknown types */
|
||||
break;
|
||||
}
|
||||
|
||||
setting->type = type;
|
||||
|
||||
result = xsettings_list_insert (&settings, setting);
|
||||
result = xsettings_list_insert(&settings, setting);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
goto out;
|
||||
|
||||
setting = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
out:
|
||||
|
||||
if (result != XSETTINGS_SUCCESS) {
|
||||
switch (result) {
|
||||
case XSETTINGS_NO_MEM:
|
||||
case XSETTINGS_NO_MEM:
|
||||
fprintf(stderr, "Out of memory reading XSETTINGS property\n");
|
||||
break;
|
||||
case XSETTINGS_ACCESS:
|
||||
case XSETTINGS_ACCESS:
|
||||
fprintf(stderr, "Invalid XSETTINGS property (read off end)\n");
|
||||
break;
|
||||
case XSETTINGS_DUPLICATE_ENTRY:
|
||||
fprintf (stderr, "Duplicate XSETTINGS entry for '%s'\n", setting->name);
|
||||
case XSETTINGS_FAILED:
|
||||
case XSETTINGS_SUCCESS:
|
||||
case XSETTINGS_NO_ENTRY:
|
||||
case XSETTINGS_DUPLICATE_ENTRY:
|
||||
fprintf(stderr, "Duplicate XSETTINGS entry for '%s'\n", setting->name);
|
||||
case XSETTINGS_FAILED:
|
||||
case XSETTINGS_SUCCESS:
|
||||
case XSETTINGS_NO_ENTRY:
|
||||
break;
|
||||
}
|
||||
|
||||
if (setting)
|
||||
xsettings_setting_free (setting);
|
||||
xsettings_setting_free(setting);
|
||||
|
||||
xsettings_list_free (settings);
|
||||
xsettings_list_free(settings);
|
||||
settings = NULL;
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
static void read_settings (XSettingsClient *client)
|
||||
static void read_settings(XSettingsClient *client)
|
||||
{
|
||||
Atom type;
|
||||
int format;
|
||||
|
@ -352,55 +343,67 @@ static void read_settings (XSettingsClient *client)
|
|||
unsigned char *data;
|
||||
int result;
|
||||
|
||||
int (*old_handler) (Display *, XErrorEvent *);
|
||||
int (*old_handler)(Display *, XErrorEvent *);
|
||||
|
||||
XSettingsList *old_list = client->settings;
|
||||
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);
|
||||
XSetErrorHandler (old_handler);
|
||||
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);
|
||||
XSetErrorHandler(old_handler);
|
||||
|
||||
if (result == Success && type == server.atom._XSETTINGS_SETTINGS) {
|
||||
if (format != 8) {
|
||||
fprintf (stderr, "Invalid format for XSETTINGS property %d", format);
|
||||
}
|
||||
else
|
||||
client->settings = parse_settings (data, n_items);
|
||||
XFree (data);
|
||||
fprintf(stderr, "Invalid format for XSETTINGS property %d", format);
|
||||
} else
|
||||
client->settings = parse_settings(data, n_items);
|
||||
XFree(data);
|
||||
}
|
||||
|
||||
notify_changes (client, old_list);
|
||||
xsettings_list_free (old_list);
|
||||
notify_changes(client, old_list);
|
||||
xsettings_list_free(old_list);
|
||||
}
|
||||
|
||||
|
||||
static void check_manager_window (XSettingsClient *client)
|
||||
static void check_manager_window(XSettingsClient *client)
|
||||
{
|
||||
if (client->manager_window && client->watch)
|
||||
client->watch (client->manager_window, False, 0, client->cb_data);
|
||||
client->watch(client->manager_window, False, 0, client->cb_data);
|
||||
|
||||
XGrabServer (client->display);
|
||||
XGrabServer(client->display);
|
||||
|
||||
client->manager_window = XGetSelectionOwner (server.dsp, server.atom._XSETTINGS_SCREEN);
|
||||
client->manager_window = XGetSelectionOwner(server.dsp, server.atom._XSETTINGS_SCREEN);
|
||||
if (client->manager_window)
|
||||
XSelectInput (server.dsp, client->manager_window, PropertyChangeMask | StructureNotifyMask);
|
||||
XSelectInput(server.dsp, client->manager_window, PropertyChangeMask | StructureNotifyMask);
|
||||
|
||||
XUngrabServer (client->display);
|
||||
XFlush (client->display);
|
||||
XUngrabServer(client->display);
|
||||
XFlush(client->display);
|
||||
|
||||
if (client->manager_window && client->watch)
|
||||
client->watch (client->manager_window, True, PropertyChangeMask | StructureNotifyMask, client->cb_data);
|
||||
client->watch(client->manager_window, True, PropertyChangeMask | StructureNotifyMask, client->cb_data);
|
||||
|
||||
read_settings (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;
|
||||
|
||||
client = calloc (1, sizeof *client);
|
||||
client = calloc(1, sizeof *client);
|
||||
if (!client)
|
||||
return NULL;
|
||||
|
||||
|
@ -414,68 +417,60 @@ XSettingsClient *xsettings_client_new (Display *display, int screen, XSettingsNo
|
|||
client->settings = NULL;
|
||||
|
||||
if (client->watch)
|
||||
client->watch (RootWindow (display, screen), True, StructureNotifyMask, client->cb_data);
|
||||
client->watch(RootWindow(display, screen), True, StructureNotifyMask, client->cb_data);
|
||||
|
||||
check_manager_window (client);
|
||||
check_manager_window(client);
|
||||
|
||||
if (client->manager_window == None) {
|
||||
printf("NO XSETTINGS manager, tint2 use config 'launcher_icon_theme'.\n");
|
||||
free (client);
|
||||
free(client);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
void xsettings_client_destroy (XSettingsClient *client)
|
||||
void xsettings_client_destroy(XSettingsClient *client)
|
||||
{
|
||||
if (client->watch)
|
||||
client->watch (RootWindow (client->display, client->screen), False, 0, client->cb_data);
|
||||
client->watch(RootWindow(client->display, client->screen), False, 0, client->cb_data);
|
||||
if (client->manager_window && client->watch)
|
||||
client->watch (client->manager_window, False, 0, client->cb_data);
|
||||
client->watch(client->manager_window, False, 0, client->cb_data);
|
||||
|
||||
xsettings_list_free (client->settings);
|
||||
free (client);
|
||||
xsettings_list_free(client->settings);
|
||||
free(client);
|
||||
}
|
||||
|
||||
|
||||
XSettingsResult xsettings_client_get_setting (XSettingsClient *client, const char *name, XSettingsSetting **setting)
|
||||
XSettingsResult xsettings_client_get_setting(XSettingsClient *client, const char *name, XSettingsSetting **setting)
|
||||
{
|
||||
XSettingsSetting *search = xsettings_list_lookup (client->settings, name);
|
||||
XSettingsSetting *search = xsettings_list_lookup(client->settings, name);
|
||||
if (search) {
|
||||
*setting = xsettings_setting_copy (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)
|
||||
Bool xsettings_client_process_event(XSettingsClient *client, XEvent *xev)
|
||||
{
|
||||
/* The checks here will not unlikely cause us to reread
|
||||
* the properties from the manager window a number of
|
||||
* times when the manager changes from A->B. But manager changes
|
||||
* are going to be pretty rare.
|
||||
*/
|
||||
if (xev->xany.window == RootWindow (server.dsp, server.screen)) {
|
||||
if (xev->xany.window == RootWindow(server.dsp, server.screen)) {
|
||||
if (xev->xany.type == ClientMessage && xev->xclient.message_type == server.atom.MANAGER) {
|
||||
check_manager_window (client);
|
||||
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);
|
||||
check_manager_window(client);
|
||||
return True;
|
||||
}
|
||||
else if (xev->xany.type == PropertyNotify) {
|
||||
read_settings (client);
|
||||
} else if (xev->xany.type == PropertyNotify) {
|
||||
read_settings(client);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Owen Taylor, Red Hat, Inc.
|
||||
|
@ -32,23 +32,22 @@ 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);
|
||||
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);
|
||||
void xsettings_client_destroy (XSettingsClient *client);
|
||||
Bool xsettings_client_process_event (XSettingsClient *client, XEvent *xev);
|
||||
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);
|
||||
|
||||
void xsettings_notify_cb (const char *name, XSettingsAction action, XSettingsSetting *setting, void *data);
|
||||
void xsettings_notify_cb(const char *name, XSettingsAction action, XSettingsSetting *setting, void *data);
|
||||
|
||||
XSettingsResult xsettings_client_get_setting (XSettingsClient *client, const char *name, XSettingsSetting **setting);
|
||||
XSettingsResult xsettings_client_get_setting(XSettingsClient *client, const char *name, XSettingsSetting **setting);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -24,31 +24,29 @@
|
|||
#include "stdlib.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xmd.h> /* For CARD32 */
|
||||
#include <X11/Xmd.h> /* For CARD32 */
|
||||
|
||||
#include "xsettings-common.h"
|
||||
|
||||
XSettingsSetting *
|
||||
xsettings_setting_copy (XSettingsSetting *setting)
|
||||
XSettingsSetting *xsettings_setting_copy(XSettingsSetting *setting)
|
||||
{
|
||||
XSettingsSetting *result;
|
||||
size_t str_len;
|
||||
|
||||
result = calloc (1, sizeof *result);
|
||||
result = calloc(1, sizeof *result);
|
||||
if (!result)
|
||||
return NULL;
|
||||
|
||||
str_len = strlen (setting->name);
|
||||
result->name = calloc (str_len + 1, 1);
|
||||
str_len = strlen(setting->name);
|
||||
result->name = calloc(str_len + 1, 1);
|
||||
if (!result->name)
|
||||
goto err;
|
||||
|
||||
memcpy (result->name, setting->name, str_len + 1);
|
||||
memcpy(result->name, setting->name, str_len + 1);
|
||||
|
||||
result->type = setting->type;
|
||||
|
||||
switch (setting->type)
|
||||
{
|
||||
switch (setting->type) {
|
||||
case XSETTINGS_TYPE_INT:
|
||||
result->data.v_int = setting->data.v_int;
|
||||
break;
|
||||
|
@ -56,12 +54,12 @@ xsettings_setting_copy (XSettingsSetting *setting)
|
|||
result->data.v_color = setting->data.v_color;
|
||||
break;
|
||||
case XSETTINGS_TYPE_STRING:
|
||||
str_len = strlen (setting->data.v_string);
|
||||
result->data.v_string = calloc (str_len + 1, 1);
|
||||
str_len = strlen(setting->data.v_string);
|
||||
result->data.v_string = calloc(str_len + 1, 1);
|
||||
if (!result->data.v_string)
|
||||
goto err;
|
||||
|
||||
memcpy (result->data.v_string, setting->data.v_string, str_len + 1);
|
||||
memcpy(result->data.v_string, setting->data.v_string, str_len + 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -73,31 +71,28 @@ xsettings_setting_copy (XSettingsSetting *setting)
|
|||
|
||||
err:
|
||||
if (result->name)
|
||||
free (result->name);
|
||||
free (result);
|
||||
free(result->name);
|
||||
free(result);
|
||||
|
||||
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);
|
||||
new_node = calloc(1, sizeof *new_node);
|
||||
if (!new_node)
|
||||
goto error;
|
||||
|
||||
new_node->setting = xsettings_setting_copy (old_iter->setting);
|
||||
if (!new_node->setting)
|
||||
{
|
||||
free (new_node);
|
||||
new_node->setting = xsettings_setting_copy(old_iter->setting);
|
||||
if (!new_node->setting) {
|
||||
free(new_node);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -114,22 +109,19 @@ xsettings_list_copy (XSettingsList *list)
|
|||
return new;
|
||||
|
||||
error:
|
||||
xsettings_list_free (new);
|
||||
xsettings_list_free(new);
|
||||
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;
|
||||
|
||||
if (strcmp (setting_a->name, setting_b->name) != 0)
|
||||
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:
|
||||
|
@ -138,7 +130,7 @@ xsettings_setting_equal (XSettingsSetting *setting_a,
|
|||
setting_a->data.v_color.blue == setting_b->data.v_color.blue &&
|
||||
setting_a->data.v_color.alpha == setting_b->data.v_color.alpha);
|
||||
case XSETTINGS_TYPE_STRING:
|
||||
return strcmp (setting_a->data.v_string, setting_b->data.v_string) == 0;
|
||||
return strcmp(setting_a->data.v_string, setting_b->data.v_string) == 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -146,55 +138,48 @@ 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);
|
||||
free(setting->data.v_string);
|
||||
|
||||
if (setting->name)
|
||||
free (setting->name);
|
||||
free(setting->name);
|
||||
|
||||
free (setting);
|
||||
free(setting);
|
||||
}
|
||||
|
||||
void
|
||||
xsettings_list_free (XSettingsList *list)
|
||||
void xsettings_list_free(XSettingsList *list)
|
||||
{
|
||||
while (list)
|
||||
{
|
||||
while (list) {
|
||||
XSettingsList *next = list->next;
|
||||
|
||||
xsettings_setting_free (list->setting);
|
||||
free (list);
|
||||
xsettings_setting_free(list->setting);
|
||||
free(list);
|
||||
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
|
||||
XSettingsResult
|
||||
xsettings_list_insert (XSettingsList **list,
|
||||
XSettingsSetting *setting)
|
||||
XSettingsResult xsettings_list_insert(XSettingsList **list, XSettingsSetting *setting)
|
||||
{
|
||||
XSettingsList *node;
|
||||
XSettingsList *iter;
|
||||
XSettingsList *last = NULL;
|
||||
|
||||
node = calloc (1, sizeof *node);
|
||||
node = calloc(1, sizeof *node);
|
||||
if (!node)
|
||||
return XSETTINGS_NO_MEM;
|
||||
node->setting = setting;
|
||||
|
||||
iter = *list;
|
||||
while (iter)
|
||||
{
|
||||
int cmp = strcmp (setting->name, iter->setting->name);
|
||||
while (iter) {
|
||||
int cmp = strcmp(setting->name, iter->setting->name);
|
||||
|
||||
if (cmp < 0)
|
||||
break;
|
||||
else if (cmp == 0)
|
||||
{
|
||||
free (node);
|
||||
else if (cmp == 0) {
|
||||
free(node);
|
||||
return XSETTINGS_DUPLICATE_ENTRY;
|
||||
}
|
||||
|
||||
|
@ -212,25 +197,21 @@ 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
|
||||
*list = iter->next;
|
||||
|
||||
xsettings_setting_free (iter->setting);
|
||||
free (iter);
|
||||
xsettings_setting_free(iter->setting);
|
||||
free(iter);
|
||||
|
||||
return XSETTINGS_SUCCESS;
|
||||
}
|
||||
|
@ -242,16 +223,13 @@ 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)
|
||||
{
|
||||
if (strcmp (name, iter->setting->name) == 0)
|
||||
while (iter) {
|
||||
if (strcmp(name, iter->setting->name) == 0)
|
||||
return iter->setting;
|
||||
|
||||
iter = iter->next;
|
||||
|
@ -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;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Owen Taylor, Red Hat, Inc.
|
||||
|
@ -27,82 +27,72 @@
|
|||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct _XSettingsBuffer XSettingsBuffer;
|
||||
typedef struct _XSettingsColor XSettingsColor;
|
||||
typedef struct _XSettingsList XSettingsList;
|
||||
typedef struct _XSettingsBuffer XSettingsBuffer;
|
||||
typedef struct _XSettingsColor XSettingsColor;
|
||||
typedef struct _XSettingsList XSettingsList;
|
||||
typedef struct _XSettingsSetting XSettingsSetting;
|
||||
|
||||
/* Types of settings possible. Enum values correspond to
|
||||
* protocol values.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
XSETTINGS_TYPE_INT = 0,
|
||||
XSETTINGS_TYPE_STRING = 1,
|
||||
XSETTINGS_TYPE_COLOR = 2,
|
||||
XSETTINGS_TYPE_NONE = 0xff
|
||||
typedef enum {
|
||||
XSETTINGS_TYPE_INT = 0,
|
||||
XSETTINGS_TYPE_STRING = 1,
|
||||
XSETTINGS_TYPE_COLOR = 2,
|
||||
XSETTINGS_TYPE_NONE = 0xff
|
||||
} XSettingsType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
XSETTINGS_SUCCESS,
|
||||
XSETTINGS_NO_MEM,
|
||||
XSETTINGS_ACCESS,
|
||||
XSETTINGS_FAILED,
|
||||
XSETTINGS_NO_ENTRY,
|
||||
XSETTINGS_DUPLICATE_ENTRY
|
||||
typedef enum {
|
||||
XSETTINGS_SUCCESS,
|
||||
XSETTINGS_NO_MEM,
|
||||
XSETTINGS_ACCESS,
|
||||
XSETTINGS_FAILED,
|
||||
XSETTINGS_NO_ENTRY,
|
||||
XSETTINGS_DUPLICATE_ENTRY
|
||||
} XSettingsResult;
|
||||
|
||||
struct _XSettingsBuffer
|
||||
{
|
||||
char byte_order;
|
||||
size_t len;
|
||||
unsigned char *data;
|
||||
unsigned char *pos;
|
||||
struct _XSettingsBuffer {
|
||||
char byte_order;
|
||||
size_t len;
|
||||
unsigned char *data;
|
||||
unsigned char *pos;
|
||||
};
|
||||
|
||||
struct _XSettingsColor
|
||||
{
|
||||
unsigned short red, green, blue, alpha;
|
||||
struct _XSettingsColor {
|
||||
unsigned short red, green, blue, alpha;
|
||||
};
|
||||
|
||||
struct _XSettingsList
|
||||
{
|
||||
XSettingsSetting *setting;
|
||||
XSettingsList *next;
|
||||
struct _XSettingsList {
|
||||
XSettingsSetting *setting;
|
||||
XSettingsList *next;
|
||||
};
|
||||
|
||||
struct _XSettingsSetting
|
||||
{
|
||||
char *name;
|
||||
XSettingsType type;
|
||||
|
||||
union {
|
||||
int v_int;
|
||||
char *v_string;
|
||||
XSettingsColor v_color;
|
||||
} data;
|
||||
struct _XSettingsSetting {
|
||||
char *name;
|
||||
XSettingsType type;
|
||||
|
||||
unsigned long last_change_serial;
|
||||
union {
|
||||
int v_int;
|
||||
char *v_string;
|
||||
XSettingsColor v_color;
|
||||
} data;
|
||||
|
||||
unsigned long last_change_serial;
|
||||
};
|
||||
|
||||
XSettingsSetting *xsettings_setting_copy (XSettingsSetting *setting);
|
||||
void xsettings_setting_free (XSettingsSetting *setting);
|
||||
int xsettings_setting_equal (XSettingsSetting *setting_a,
|
||||
XSettingsSetting *setting_b);
|
||||
XSettingsSetting *xsettings_setting_copy(XSettingsSetting *setting);
|
||||
void xsettings_setting_free(XSettingsSetting *setting);
|
||||
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);
|
||||
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);
|
||||
|
||||
char xsettings_byte_order (void);
|
||||
char xsettings_byte_order(void);
|
||||
|
||||
#define XSETTINGS_PAD(n,m) ((n + m - 1) & (~(m-1)))
|
||||
#define XSETTINGS_PAD(n, m) ((n + m - 1) & (~(m - 1)))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
681
src/panel.c
681
src/panel.c
File diff suppressed because it is too large
Load diff
152
src/panel.h
152
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;
|
||||
// panel mode
|
||||
typedef enum TaskbarMode {
|
||||
SINGLE_DESKTOP = 0,
|
||||
MULTI_DESKTOP,
|
||||
} TaskbarMode;
|
||||
|
||||
typedef enum Layer {
|
||||
BOTTOM_LAYER,
|
||||
NORMAL_LAYER,
|
||||
TOP_LAYER,
|
||||
} Layer;
|
||||
|
||||
// panel position
|
||||
typedef enum PanelPosition {
|
||||
LEFT = 0x01,
|
||||
RIGHT = 0x02,
|
||||
CENTER = 0X04,
|
||||
TOP = 0X08,
|
||||
BOTTOM = 0x10,
|
||||
} PanelPosition;
|
||||
|
||||
typedef enum Strut {
|
||||
STRUT_MINIMUM,
|
||||
STRUT_FOLLOW_SIZE,
|
||||
STRUT_NONE,
|
||||
} Strut;
|
||||
|
||||
extern TaskbarMode taskbar_mode;
|
||||
extern gboolean wm_menu;
|
||||
extern gboolean panel_dock;
|
||||
extern Layer panel_layer;
|
||||
extern char *panel_window_name;
|
||||
|
||||
//panel position
|
||||
enum { LEFT=0x01, RIGHT=0x02, CENTER=0X04, TOP=0X08, BOTTOM=0x10 };
|
||||
extern int panel_position;
|
||||
extern int panel_horizontal;
|
||||
|
||||
extern int panel_refresh;
|
||||
extern int task_dragged;
|
||||
|
||||
//panel autohide
|
||||
enum { STRUT_MINIMUM, STRUT_FOLLOW_SIZE, STRUT_NONE };
|
||||
extern int panel_autohide;
|
||||
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 int panel_autohide_height; // for vertical panels this is of course the width
|
||||
extern Strut panel_strut_policy;
|
||||
extern char *panel_items_order;
|
||||
|
||||
extern int max_tick_urgent;
|
||||
|
||||
extern GArray* backgrounds;
|
||||
|
||||
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;
|
||||
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);
|
||||
|
@ -164,22 +158,22 @@ void set_panel_background(Panel *p);
|
|||
// detect witch panel
|
||||
Panel *get_panel(Window win);
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
Area *click_area(Panel *panel, int x, int y);
|
||||
|
||||
void autohide_show(void* p);
|
||||
void autohide_hide(void* p);
|
||||
void autohide_trigger_show(Panel* p);
|
||||
void autohide_trigger_hide(Panel* p);
|
||||
void autohide_show(void *p);
|
||||
void autohide_hide(void *p);
|
||||
void autohide_trigger_show(Panel *p);
|
||||
void autohide_trigger_hide(Panel *p);
|
||||
|
||||
#endif
|
||||
|
|
309
src/server.c
309
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,53 +31,55 @@
|
|||
|
||||
Server_global server;
|
||||
|
||||
void server_catch_error (Display *d, XErrorEvent *ev){}
|
||||
|
||||
void server_init_atoms ()
|
||||
void server_catch_error(Display *d, XErrorEvent *ev)
|
||||
{
|
||||
server.atom._XROOTPMAP_ID = XInternAtom (server.dsp, "_XROOTPMAP_ID", False);
|
||||
server.atom._XROOTMAP_ID = XInternAtom (server.dsp, "_XROOTMAP_ID", False);
|
||||
server.atom._NET_CURRENT_DESKTOP = XInternAtom (server.dsp, "_NET_CURRENT_DESKTOP", False);
|
||||
server.atom._NET_NUMBER_OF_DESKTOPS = XInternAtom (server.dsp, "_NET_NUMBER_OF_DESKTOPS", False);
|
||||
server.atom._NET_DESKTOP_NAMES = XInternAtom (server.dsp, "_NET_DESKTOP_NAMES", False);
|
||||
server.atom._NET_DESKTOP_GEOMETRY = XInternAtom (server.dsp, "_NET_DESKTOP_GEOMETRY", False);
|
||||
server.atom._NET_DESKTOP_VIEWPORT = XInternAtom (server.dsp, "_NET_DESKTOP_VIEWPORT", False);
|
||||
server.atom._NET_ACTIVE_WINDOW = XInternAtom (server.dsp, "_NET_ACTIVE_WINDOW", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE", False);
|
||||
server.atom._NET_WM_STATE_SKIP_PAGER = XInternAtom (server.dsp, "_NET_WM_STATE_SKIP_PAGER", False);
|
||||
server.atom._NET_WM_STATE_SKIP_TASKBAR = XInternAtom (server.dsp, "_NET_WM_STATE_SKIP_TASKBAR", False);
|
||||
server.atom._NET_WM_STATE_STICKY = XInternAtom (server.dsp, "_NET_WM_STATE_STICKY", False);
|
||||
server.atom._NET_WM_STATE_DEMANDS_ATTENTION = XInternAtom (server.dsp, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_DOCK = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE_DOCK", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_TOOLBAR = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_MENU = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE_MENU", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_SPLASH = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE_SPLASH", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_DIALOG = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_NORMAL = XInternAtom (server.dsp, "_NET_WM_WINDOW_TYPE_NORMAL", False);
|
||||
server.atom._NET_WM_DESKTOP = XInternAtom (server.dsp, "_NET_WM_DESKTOP", False);
|
||||
server.atom.WM_STATE = XInternAtom (server.dsp, "WM_STATE", False);
|
||||
server.atom._NET_WM_STATE = XInternAtom (server.dsp, "_NET_WM_STATE", False);
|
||||
server.atom._NET_WM_STATE_MAXIMIZED_VERT = XInternAtom (server.dsp, "_NET_WM_STATE_MAXIMIZED_VERT", False);
|
||||
server.atom._NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom (server.dsp, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
|
||||
server.atom._NET_WM_STATE_SHADED = XInternAtom (server.dsp, "_NET_WM_STATE_SHADED", False);
|
||||
server.atom._NET_WM_STATE_HIDDEN = XInternAtom (server.dsp, "_NET_WM_STATE_HIDDEN", False);
|
||||
server.atom._NET_WM_STATE_BELOW = XInternAtom (server.dsp, "_NET_WM_STATE_BELOW", False);
|
||||
server.atom._NET_WM_STATE_ABOVE = XInternAtom (server.dsp, "_NET_WM_STATE_ABOVE", False);
|
||||
server.atom._NET_WM_STATE_MODAL = XInternAtom (server.dsp, "_NET_WM_STATE_MODAL", False);
|
||||
server.atom._NET_CLIENT_LIST = XInternAtom (server.dsp, "_NET_CLIENT_LIST", False);
|
||||
server.atom._NET_WM_VISIBLE_NAME = XInternAtom (server.dsp, "_NET_WM_VISIBLE_NAME", False);
|
||||
server.atom._NET_WM_NAME = XInternAtom (server.dsp, "_NET_WM_NAME", False);
|
||||
server.atom._NET_WM_STRUT = XInternAtom (server.dsp, "_NET_WM_STRUT", False);
|
||||
server.atom._NET_WM_ICON = XInternAtom (server.dsp, "_NET_WM_ICON", False);
|
||||
server.atom._NET_WM_ICON_GEOMETRY = XInternAtom(server.dsp, "_NET_WM_ICON_GEOMETRY", False );
|
||||
server.atom._NET_WM_ICON_NAME = XInternAtom(server.dsp, "_NET_WM_ICON_NAME", False );
|
||||
server.atom._NET_CLOSE_WINDOW = XInternAtom (server.dsp, "_NET_CLOSE_WINDOW", False);
|
||||
server.atom.UTF8_STRING = XInternAtom (server.dsp, "UTF8_STRING", False);
|
||||
server.atom._NET_SUPPORTING_WM_CHECK = XInternAtom (server.dsp, "_NET_SUPPORTING_WM_CHECK", False);
|
||||
server.atom._NET_WM_CM_S0 = XInternAtom (server.dsp, "_NET_WM_CM_S0", False);
|
||||
server.atom._NET_SUPPORTING_WM_CHECK = XInternAtom (server.dsp, "_NET_WM_NAME", False);
|
||||
server.atom._NET_WM_STRUT_PARTIAL = XInternAtom (server.dsp, "_NET_WM_STRUT_PARTIAL", False);
|
||||
}
|
||||
|
||||
void server_init_atoms()
|
||||
{
|
||||
server.atom._XROOTPMAP_ID = XInternAtom(server.dsp, "_XROOTPMAP_ID", False);
|
||||
server.atom._XROOTMAP_ID = XInternAtom(server.dsp, "_XROOTMAP_ID", False);
|
||||
server.atom._NET_CURRENT_DESKTOP = XInternAtom(server.dsp, "_NET_CURRENT_DESKTOP", False);
|
||||
server.atom._NET_NUMBER_OF_DESKTOPS = XInternAtom(server.dsp, "_NET_NUMBER_OF_DESKTOPS", False);
|
||||
server.atom._NET_DESKTOP_NAMES = XInternAtom(server.dsp, "_NET_DESKTOP_NAMES", False);
|
||||
server.atom._NET_DESKTOP_GEOMETRY = XInternAtom(server.dsp, "_NET_DESKTOP_GEOMETRY", False);
|
||||
server.atom._NET_DESKTOP_VIEWPORT = XInternAtom(server.dsp, "_NET_DESKTOP_VIEWPORT", False);
|
||||
server.atom._NET_ACTIVE_WINDOW = XInternAtom(server.dsp, "_NET_ACTIVE_WINDOW", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE = XInternAtom(server.dsp, "_NET_WM_WINDOW_TYPE", False);
|
||||
server.atom._NET_WM_STATE_SKIP_PAGER = XInternAtom(server.dsp, "_NET_WM_STATE_SKIP_PAGER", False);
|
||||
server.atom._NET_WM_STATE_SKIP_TASKBAR = XInternAtom(server.dsp, "_NET_WM_STATE_SKIP_TASKBAR", False);
|
||||
server.atom._NET_WM_STATE_STICKY = XInternAtom(server.dsp, "_NET_WM_STATE_STICKY", False);
|
||||
server.atom._NET_WM_STATE_DEMANDS_ATTENTION = XInternAtom(server.dsp, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_DOCK = XInternAtom(server.dsp, "_NET_WM_WINDOW_TYPE_DOCK", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom(server.dsp, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_TOOLBAR = XInternAtom(server.dsp, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_MENU = XInternAtom(server.dsp, "_NET_WM_WINDOW_TYPE_MENU", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_SPLASH = XInternAtom(server.dsp, "_NET_WM_WINDOW_TYPE_SPLASH", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(server.dsp, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||
server.atom._NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(server.dsp, "_NET_WM_WINDOW_TYPE_NORMAL", False);
|
||||
server.atom._NET_WM_DESKTOP = XInternAtom(server.dsp, "_NET_WM_DESKTOP", False);
|
||||
server.atom.WM_STATE = XInternAtom(server.dsp, "WM_STATE", False);
|
||||
server.atom._NET_WM_STATE = XInternAtom(server.dsp, "_NET_WM_STATE", False);
|
||||
server.atom._NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(server.dsp, "_NET_WM_STATE_MAXIMIZED_VERT", False);
|
||||
server.atom._NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(server.dsp, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
|
||||
server.atom._NET_WM_STATE_SHADED = XInternAtom(server.dsp, "_NET_WM_STATE_SHADED", False);
|
||||
server.atom._NET_WM_STATE_HIDDEN = XInternAtom(server.dsp, "_NET_WM_STATE_HIDDEN", False);
|
||||
server.atom._NET_WM_STATE_BELOW = XInternAtom(server.dsp, "_NET_WM_STATE_BELOW", False);
|
||||
server.atom._NET_WM_STATE_ABOVE = XInternAtom(server.dsp, "_NET_WM_STATE_ABOVE", False);
|
||||
server.atom._NET_WM_STATE_MODAL = XInternAtom(server.dsp, "_NET_WM_STATE_MODAL", False);
|
||||
server.atom._NET_CLIENT_LIST = XInternAtom(server.dsp, "_NET_CLIENT_LIST", False);
|
||||
server.atom._NET_WM_VISIBLE_NAME = XInternAtom(server.dsp, "_NET_WM_VISIBLE_NAME", False);
|
||||
server.atom._NET_WM_NAME = XInternAtom(server.dsp, "_NET_WM_NAME", False);
|
||||
server.atom._NET_WM_STRUT = XInternAtom(server.dsp, "_NET_WM_STRUT", False);
|
||||
server.atom._NET_WM_ICON = XInternAtom(server.dsp, "_NET_WM_ICON", False);
|
||||
server.atom._NET_WM_ICON_GEOMETRY = XInternAtom(server.dsp, "_NET_WM_ICON_GEOMETRY", False);
|
||||
server.atom._NET_WM_ICON_NAME = XInternAtom(server.dsp, "_NET_WM_ICON_NAME", False);
|
||||
server.atom._NET_CLOSE_WINDOW = XInternAtom(server.dsp, "_NET_CLOSE_WINDOW", False);
|
||||
server.atom.UTF8_STRING = XInternAtom(server.dsp, "UTF8_STRING", False);
|
||||
server.atom._NET_SUPPORTING_WM_CHECK = XInternAtom(server.dsp, "_NET_SUPPORTING_WM_CHECK", False);
|
||||
server.atom._NET_WM_CM_S0 = XInternAtom(server.dsp, "_NET_WM_CM_S0", False);
|
||||
server.atom._NET_SUPPORTING_WM_CHECK = XInternAtom(server.dsp, "_NET_WM_NAME", False);
|
||||
server.atom._NET_WM_STRUT_PARTIAL = XInternAtom(server.dsp, "_NET_WM_STRUT_PARTIAL", False);
|
||||
server.atom.WM_NAME = XInternAtom(server.dsp, "WM_NAME", False);
|
||||
server.atom.__SWM_VROOT = XInternAtom(server.dsp, "__SWM_VROOT", False);
|
||||
server.atom._MOTIF_WM_HINTS = XInternAtom(server.dsp, "_MOTIF_WM_HINTS", False);
|
||||
|
@ -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,8 +139,7 @@ void cleanup_server()
|
|||
server.disable_transparency = 0;
|
||||
}
|
||||
|
||||
|
||||
void send_event32 (Window win, Atom at, long data1, long data2, long data3)
|
||||
void send_event32(Window win, Atom at, long data1, long data2, long data3)
|
||||
{
|
||||
XEvent event;
|
||||
|
||||
|
@ -159,11 +157,10 @@ void send_event32 (Window win, Atom at, long data1, long data2, long data3)
|
|||
event.xclient.data.l[3] = 0;
|
||||
event.xclient.data.l[4] = 0;
|
||||
|
||||
XSendEvent(server.dsp, server.root_win, False, SubstructureRedirectMask|SubstructureNotifyMask, &event);
|
||||
XSendEvent(server.dsp, server.root_win, False, SubstructureRedirectMask | SubstructureNotifyMask, &event);
|
||||
}
|
||||
|
||||
|
||||
int get_property32 (Window win, Atom at, Atom type)
|
||||
int get_property32(Window win, Atom at, Atom type)
|
||||
{
|
||||
Atom type_ret;
|
||||
int format_ret = 0, data = 0;
|
||||
|
@ -172,61 +169,82 @@ 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];
|
||||
XFree (prop_value);
|
||||
data = ((gulong *)prop_value)[0];
|
||||
XFree(prop_value);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void *server_get_property (Window win, Atom at, Atom type, int *num_results)
|
||||
void *server_get_property(Window win, Atom at, Atom type, int *num_results)
|
||||
{
|
||||
Atom type_ret;
|
||||
int format_ret = 0;
|
||||
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);
|
||||
Atom pixmap_atoms[] = {server.atom._XROOTPMAP_ID, server.atom._XROOTMAP_ID};
|
||||
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);
|
||||
ret = *((Pixmap *)res);
|
||||
XFree(res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
server.root_pmap = ret;
|
||||
|
||||
if (server.root_pmap == None)
|
||||
if (server.root_pmap == None) {
|
||||
fprintf(stderr, "tint2 : pixmap background detection failed\n");
|
||||
else {
|
||||
XGCValues gcv;
|
||||
} else {
|
||||
XGCValues gcv;
|
||||
gcv.ts_x_origin = 0;
|
||||
gcv.ts_y_origin = 0;
|
||||
gcv.fill_style = FillTiled;
|
||||
|
@ -237,89 +255,81 @@ 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
|
||||
// on some recent configs, XRRGetScreenResourcesCurrent returns a fantom monitor at last position
|
||||
{
|
||||
int i = res->ncrtc - 1;
|
||||
XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(server.dsp, res, res->crtcs[i]);
|
||||
XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(server.dsp, res, res->crtcs[i]);
|
||||
if (!(crtc_info->x || crtc_info->y || crtc_info->width || crtc_info->height)) {
|
||||
res->ncrtc -= 1;
|
||||
}
|
||||
XRRFreeCrtcInfo(crtc_info);
|
||||
}
|
||||
|
||||
printf("xRandr: Found crtc's: %d\n", res->ncrtc );
|
||||
printf("xRandr: Found crtc's: %d\n", res->ncrtc);
|
||||
server.monitor = calloc(res->ncrtc, sizeof(Monitor));
|
||||
for (i=0; i<res->ncrtc; ++i) {
|
||||
XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(server.dsp, res, res->crtcs[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) {
|
||||
XRROutputInfo* output_info = XRRGetOutputInfo(server.dsp, res, crtc_info->outputs[j]);
|
||||
server.monitor[i].names = calloc((crtc_info->noutput + 1), sizeof(gchar *));
|
||||
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,48 +339,48 @@ 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)
|
||||
next:
|
||||
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);
|
||||
server.monitor[0].height = DisplayHeight (server.dsp, server.screen);
|
||||
server.monitor[0].width = DisplayWidth(server.dsp, server.screen);
|
||||
server.monitor[0].height = DisplayHeight(server.dsp, server.screen);
|
||||
server.monitor[0].names = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
i+1,
|
||||
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,
|
||||
server.monitor[i].width,
|
||||
|
@ -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 };
|
||||
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;
|
||||
|
@ -421,7 +427,7 @@ void server_init_visual()
|
|||
}
|
||||
}
|
||||
}
|
||||
XFree (xvi);
|
||||
XFree(xvi);
|
||||
|
||||
// check composite manager
|
||||
server.composite_manager = XGetSelectionOwner(server.dsp, server.atom._NET_WM_CM_S0);
|
||||
|
@ -435,18 +441,17 @@ 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);
|
||||
XChangeWindowAttributes(server.dsp, server.composite_manager, CWEventMask, &attrs);
|
||||
|
||||
server.real_transparency = 1;
|
||||
server.depth = 32;
|
||||
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);
|
||||
|
|
32
src/server.h
32
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,20 +90,15 @@ typedef struct Global_atom
|
|||
Atom TARGETS;
|
||||
} Global_atom;
|
||||
|
||||
|
||||
|
||||
typedef struct Monitor
|
||||
{
|
||||
typedef struct Monitor {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
gchar** names;
|
||||
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,19 +127,17 @@ typedef struct
|
|||
#endif // HAVE_SN
|
||||
} Server_global;
|
||||
|
||||
|
||||
extern Server_global server;
|
||||
|
||||
|
||||
// freed memory
|
||||
void cleanup_server();
|
||||
|
||||
void send_event32 (Window win, Atom at, long data1, long data2, long data3);
|
||||
int get_property32 (Window win, Atom at, Atom type);
|
||||
void *server_get_property (Window win, Atom at, Atom type, int *num_results);
|
||||
Atom server_get_atom (char *atom_name);
|
||||
void server_catch_error (Display *d, XErrorEvent *ev);
|
||||
void server_init_atoms ();
|
||||
void send_event32(Window win, Atom at, long data1, long data2, long data3);
|
||||
int get_property32(Window win, Atom at, Atom type);
|
||||
void *server_get_property(Window win, Atom at, Atom type, int *num_results);
|
||||
Atom server_get_atom(char *atom_name);
|
||||
void server_catch_error(Display *d, XErrorEvent *ev);
|
||||
void server_init_atoms();
|
||||
void server_init_visual();
|
||||
|
||||
// detect root background
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,57 +16,59 @@
|
|||
#include <X11/extensions/Xdamage.h>
|
||||
|
||||
// XEMBED messages
|
||||
#define XEMBED_EMBEDDED_NOTIFY 0
|
||||
#define XEMBED_EMBEDDED_NOTIFY 0
|
||||
// Flags for _XEMBED_INFO
|
||||
#define XEMBED_MAPPED (1 << 0)
|
||||
#define XEMBED_MAPPED (1 << 0)
|
||||
|
||||
enum { SYSTRAY_SORT_ASCENDING, SYSTRAY_SORT_DESCENDING, SYSTRAY_SORT_LEFT2RIGHT, SYSTRAY_SORT_RIGHT2LEFT };
|
||||
typedef 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;
|
||||
timeout *render_timeout;
|
||||
gboolean empty;
|
||||
int pid;
|
||||
int chrono;
|
||||
struct timespec time_last_render;
|
||||
struct timespec time_last_render;
|
||||
int num_fast_renders;
|
||||
int reparented;
|
||||
int embedded;
|
||||
gboolean reparented;
|
||||
gboolean embedded;
|
||||
int bad_size_counter;
|
||||
timeout* resize_timeout;
|
||||
timeout *resize_timeout;
|
||||
struct timespec time_last_resize;
|
||||
char *name;
|
||||
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
|
||||
|
||||
|
|
|
@ -35,180 +35,184 @@
|
|||
#include "tooltip.h"
|
||||
#include "timer.h"
|
||||
|
||||
timeout* urgent_timeout;
|
||||
GSList* urgent_list;
|
||||
timeout *urgent_timeout;
|
||||
GSList *urgent_list;
|
||||
|
||||
char* task_get_tooltip(void* obj)
|
||||
char *task_get_tooltip(void *obj)
|
||||
{
|
||||
Task* t = obj;
|
||||
Task *t = (Task *)obj;
|
||||
return strdup(t->title);
|
||||
}
|
||||
|
||||
|
||||
Task *add_task (Window win)
|
||||
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);
|
||||
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;
|
||||
for (k = 0; k < TASK_STATE_COUNT; ++k) {
|
||||
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;
|
||||
GPtrArray *task_group = g_ptr_array_new();
|
||||
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;
|
||||
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->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_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;
|
||||
Window *key = calloc(1, sizeof(Window));
|
||||
*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]);
|
||||
for (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;
|
||||
}
|
||||
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;
|
||||
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);
|
||||
Task *task2;
|
||||
GPtrArray *task_group = g_hash_table_lookup(win_to_task_table, &win);
|
||||
for (i = 0; i < task_group->len; ++i) {
|
||||
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,70 +221,68 @@ int get_title(Task *tsk)
|
|||
} else {
|
||||
title = strdup("Untitled");
|
||||
}
|
||||
if (name) XFree (name);
|
||||
|
||||
if (tsk->title) {
|
||||
if (name)
|
||||
XFree(name);
|
||||
|
||||
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);
|
||||
for (i = 0; i < task_group->len; ++i) {
|
||||
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;
|
||||
gulong *tmp_data;
|
||||
|
||||
tmp_data = get_best_icon (data, get_icon_count (data, i), i, &w, &h, panel->g_task.icon_size1);
|
||||
tmp_data = get_best_icon(data, get_icon_count(data, i), i, &w, &h, panel->g_task.icon_size1);
|
||||
#ifdef __x86_64__
|
||||
DATA32 icon_data[w * h];
|
||||
int length = w * h;
|
||||
for (i = 0; i < length; ++i)
|
||||
icon_data[i] = tmp_data[i];
|
||||
img = imlib_create_image_using_copied_data (w, h, icon_data);
|
||||
img = imlib_create_image_using_copied_data(w, h, icon_data);
|
||||
#else
|
||||
img = imlib_create_image_using_data (w, h, (DATA32*)tmp_data);
|
||||
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
|
||||
|
@ -289,7 +291,7 @@ void get_icon (Task *tsk)
|
|||
uint border_width, bpp;
|
||||
uint w, h;
|
||||
|
||||
//printf(" get pixmap\n");
|
||||
// printf(" get pixmap\n");
|
||||
XGetGeometry(server.dsp, hints->icon_pixmap, &root, &icon_x, &icon_y, &w, &h, &border_width, &bpp);
|
||||
imlib_context_set_drawable(hints->icon_pixmap);
|
||||
img = imlib_create_image_from_drawable(hints->icon_mask, 0, 0, w, h, 0);
|
||||
|
@ -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);
|
||||
|
@ -334,116 +348,123 @@ void get_icon (Task *tsk)
|
|||
if (hints)
|
||||
XFree(hints);
|
||||
if (data)
|
||||
XFree (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];
|
||||
for (i = 0; i < task_group->len; ++i) {
|
||||
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)
|
||||
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);
|
||||
int width = 0, height;
|
||||
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);
|
||||
layout = pango_cairo_create_layout(c);
|
||||
pango_layout_set_font_description(layout, panel->g_task.font_desc);
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
|
||||
draw_text(layout, c, panel->g_task.text_posx, text_posy, config_text, panel->font_shadow);
|
||||
|
||||
g_object_unref (layout);
|
||||
g_object_unref(layout);
|
||||
}
|
||||
|
||||
if (panel->g_task.icon) {
|
||||
draw_task_icon (tsk, width);
|
||||
draw_task_icon(task, width);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void on_change_task (void *obj)
|
||||
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 + 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);
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
for (; l0; l0 = l0->next) {
|
||||
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;
|
||||
for (; l0 ; l0 = l0->next) {
|
||||
Task *tsk1 = l0->data;
|
||||
if (tsk1 == tsk) {
|
||||
if (l0->next == 0) l0 = lfirst_tsk;
|
||||
else l0 = l0->next;
|
||||
GList *l0 = taskbar->area.children;
|
||||
if (taskbarname_enabled)
|
||||
l0 = l0->next;
|
||||
GList *lfirst_task = l0;
|
||||
for (; l0; 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;
|
||||
for (; l0 ; l0 = l0->next) {
|
||||
tsk1 = l0->data;
|
||||
if (tsk1 == tsk) {
|
||||
if (l0 == lfirst_tsk) {
|
||||
l0 = g_list_last ( l0 );
|
||||
tsk2 = l0->data;
|
||||
Task *task2 = NULL;
|
||||
GList *l0 = taskbar->area.children;
|
||||
if (taskbarname_enabled)
|
||||
l0 = l0->next;
|
||||
GList *lfirst_task = l0;
|
||||
for (; l0; l0 = l0->next) {
|
||||
Task *task1 = l0->data;
|
||||
if (task1 == task) {
|
||||
if (l0 == lfirst_task) {
|
||||
l0 = g_list_last(l0);
|
||||
task2 = l0->data;
|
||||
}
|
||||
return tsk2;
|
||||
return task2;
|
||||
}
|
||||
tsk2 = tsk1;
|
||||
task2 = task1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void active_task()
|
||||
{
|
||||
if (task_active) {
|
||||
|
@ -525,8 +545,8 @@ void active_task()
|
|||
task_active = 0;
|
||||
}
|
||||
|
||||
Window w1 = window_get_active();
|
||||
//printf("Change active task %ld\n", w1);
|
||||
Window w1 = get_active_window();
|
||||
// printf("Change active task %ld\n", w1);
|
||||
|
||||
if (w1) {
|
||||
if (!task_get_tasks(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];
|
||||
for (i = 0; i < task_group->len; ++i) {
|
||||
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,43 +592,42 @@ 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;
|
||||
for (k = 0; k < TASK_STATE_COUNT; ++k) {
|
||||
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)
|
||||
void blink_urgent(void *arg)
|
||||
{
|
||||
GSList* urgent_task = urgent_list;
|
||||
GSList *urgent_task = urgent_list;
|
||||
while (urgent_task) {
|
||||
Task* t = urgent_task->data;
|
||||
if ( t->urgent_tick < max_tick_urgent) {
|
||||
Task *t = urgent_task->data;
|
||||
if (t->urgent_tick < max_tick_urgent) {
|
||||
if (t->urgent_tick++ % 2)
|
||||
set_task_state(t, TASK_URGENT);
|
||||
else
|
||||
|
@ -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;
|
||||
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;
|
||||
|
@ -35,7 +41,7 @@ typedef struct {
|
|||
int saturation[TASK_STATE_COUNT];
|
||||
int brightness[TASK_STATE_COUNT];
|
||||
int config_asb_mask;
|
||||
Background* background[TASK_STATE_COUNT];
|
||||
Background *background[TASK_STATE_COUNT];
|
||||
int config_background_mask;
|
||||
// starting position for text ~ task_padding + task_border + icon_size
|
||||
double text_posx, text_height;
|
||||
|
@ -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
|
||||
|
@ -54,8 +58,8 @@ typedef struct {
|
|||
|
||||
// TODO: group task with list of windows here
|
||||
Window win;
|
||||
int desktop;
|
||||
int current_state;
|
||||
int desktop;
|
||||
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 *task);
|
||||
|
||||
Task *add_task (Window win);
|
||||
void remove_task (Task *tsk);
|
||||
void draw_task(void *obj, cairo_t *c);
|
||||
void on_change_task(void *obj);
|
||||
|
||||
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;
|
||||
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;
|
||||
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,60 +184,81 @@ 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;
|
||||
if ((panel->g_task.config_asb_mask & (1<<TASK_NORMAL)) == 0) {
|
||||
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;
|
||||
panel->g_task.brightness[TASK_NORMAL] = 0;
|
||||
}
|
||||
if ((panel->g_task.config_asb_mask & (1<<TASK_ACTIVE)) == 0) {
|
||||
if ((panel->g_task.config_asb_mask & (1 << TASK_ACTIVE)) == 0) {
|
||||
panel->g_task.alpha[TASK_ACTIVE] = panel->g_task.alpha[TASK_NORMAL];
|
||||
panel->g_task.saturation[TASK_ACTIVE] = panel->g_task.saturation[TASK_NORMAL];
|
||||
panel->g_task.brightness[TASK_ACTIVE] = panel->g_task.brightness[TASK_NORMAL];
|
||||
}
|
||||
if ((panel->g_task.config_asb_mask & (1<<TASK_ICONIFIED)) == 0) {
|
||||
if ((panel->g_task.config_asb_mask & (1 << TASK_ICONIFIED)) == 0) {
|
||||
panel->g_task.alpha[TASK_ICONIFIED] = panel->g_task.alpha[TASK_NORMAL];
|
||||
panel->g_task.saturation[TASK_ICONIFIED] = panel->g_task.saturation[TASK_NORMAL];
|
||||
panel->g_task.brightness[TASK_ICONIFIED] = panel->g_task.brightness[TASK_NORMAL];
|
||||
}
|
||||
if ((panel->g_task.config_asb_mask & (1<<TASK_URGENT)) == 0) {
|
||||
if ((panel->g_task.config_asb_mask & (1 << TASK_URGENT)) == 0) {
|
||||
panel->g_task.alpha[TASK_URGENT] = panel->g_task.alpha[TASK_ACTIVE];
|
||||
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)
|
||||
for (j = 0; j < TASK_STATE_COUNT; ++j) {
|
||||
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_");
|
||||
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_");
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
@ -245,41 +270,38 @@ void init_taskbar_panel(void *p)
|
|||
panel->g_task.text_posx += panel->g_task.icon_size1 + panel->g_task.area.paddingx;
|
||||
panel->g_task.icon_posy = (panel->g_task.area.height - panel->g_task.icon_size1) / 2;
|
||||
}
|
||||
//printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width);
|
||||
// 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));
|
||||
remove_task(task_get_task(*(Window *)key));
|
||||
}
|
||||
|
||||
|
||||
Task *task_get_task (Window win)
|
||||
Task *task_get_task(Window win)
|
||||
{
|
||||
GPtrArray* task_group = task_get_tasks(win);
|
||||
GPtrArray *task_group = task_get_tasks(win);
|
||||
if (task_group)
|
||||
return g_ptr_array_index(task_group, 0);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
GPtrArray* task_get_tasks(Window win)
|
||||
GPtrArray *task_get_tasks(Window win)
|
||||
{
|
||||
if (win_to_task_table && taskbar_enabled)
|
||||
return g_hash_table_lookup(win_to_task_table, &win);
|
||||
|
@ -287,21 +309,22 @@ GPtrArray* task_get_tasks(Window win)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void task_refresh_tasklist ()
|
||||
void task_refresh_tasklist()
|
||||
{
|
||||
Window *win;
|
||||
int num_results, i;
|
||||
|
||||
if (!taskbar_enabled) return;
|
||||
win = server_get_property (server.root_win, server.atom._NET_CLIENT_LIST, XA_WINDOW, &num_results);
|
||||
if (!win) return;
|
||||
if (!taskbar_enabled)
|
||||
return;
|
||||
win = server_get_property(server.root_win, server.atom._NET_CLIENT_LIST, XA_WINDOW, &num_results);
|
||||
if (!win)
|
||||
return;
|
||||
|
||||
GList* win_list = g_hash_table_get_keys(win_to_task_table);
|
||||
GList* it;
|
||||
for (it=win_list; it; it=it->next) {
|
||||
GList *win_list = g_hash_table_get_keys(win_to_task_table);
|
||||
GList *it;
|
||||
for (it = win_list; it; it = it->next) {
|
||||
for (i = 0; i < num_results; i++)
|
||||
if (*((Window*)it->data) == win[i])
|
||||
if (*((Window *)it->data) == win[i])
|
||||
break;
|
||||
if (i == num_results)
|
||||
taskbar_remove_task(it->data, 0, 0);
|
||||
|
@ -310,122 +333,121 @@ void task_refresh_tasklist ()
|
|||
|
||||
// Add any new
|
||||
for (i = 0; i < num_results; i++)
|
||||
if (!task_get_task (win[i]))
|
||||
add_task (win[i]);
|
||||
if (!task_get_task(win[i]))
|
||||
add_task(win[i]);
|
||||
|
||||
XFree (win);
|
||||
XFree(win);
|
||||
}
|
||||
|
||||
|
||||
void draw_taskbar (void *obj, cairo_t *c)
|
||||
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;
|
||||
Taskbar *taskbar = (Taskbar *)obj;
|
||||
Panel *panel = (Panel *)taskbar->area.panel;
|
||||
int text_width;
|
||||
|
||||
//printf("resize_taskbar %d %d\n", taskbar->area.posx, taskbar->area.posy);
|
||||
// printf("resize_taskbar %d %d\n", taskbar->area.posx, taskbar->area.posy);
|
||||
if (panel_horizontal) {
|
||||
relayout_with_constraint(&taskbar->area, panel->g_task.maximum_width);
|
||||
|
||||
|
||||
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)
|
||||
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;
|
||||
for (k = 0; k < TASKBAR_STATE_COUNT; ++k) {
|
||||
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;
|
||||
for ( ; l ; 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;
|
||||
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,35 +553,34 @@ 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*)taskbar->area.panel)->area.resize_needed = 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)
|
||||
return;
|
||||
|
||||
GPtrArray* task_group = task_get_tasks(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,49 +11,51 @@
|
|||
#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];
|
||||
|
||||
gchar *name;
|
||||
int posy;
|
||||
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 {
|
||||
//always start with area
|
||||
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;
|
||||
|
||||
Background *background[TASKBAR_STATE_COUNT];
|
||||
Background *background_name[TASKBAR_STATE_COUNT];
|
||||
} GlobalTaskbar;
|
||||
|
||||
// default global data
|
||||
void default_taskbar();
|
||||
|
@ -64,15 +66,15 @@ void cleanup_taskbar();
|
|||
void init_taskbar();
|
||||
void init_taskbar_panel(void *p);
|
||||
|
||||
void draw_taskbar (void *obj, cairo_t *c);
|
||||
void draw_taskbar(void *obj, cairo_t *c);
|
||||
void taskbar_remove_task(gpointer key, gpointer value, gpointer user_data);
|
||||
Task *task_get_task (Window win);
|
||||
GPtrArray* task_get_tasks(Window win);
|
||||
void task_refresh_tasklist ();
|
||||
Task *task_get_task(Window win);
|
||||
GPtrArray *task_get_tasks(Window win);
|
||||
void task_refresh_tasklist();
|
||||
|
||||
int resize_taskbar(void *obj);
|
||||
void on_change_taskbar (void *obj);
|
||||
void set_taskbar_state(Taskbar *tskbar, int state);
|
||||
gboolean resize_taskbar(void *obj);
|
||||
void on_change_taskbar(void *obj);
|
||||
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,81 +37,76 @@ 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;
|
||||
Panel *panel = (Panel *)p;
|
||||
Taskbar *taskbar;
|
||||
int j;
|
||||
|
||||
|
||||
if (!taskbarname_enabled)
|
||||
return;
|
||||
|
||||
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)
|
||||
for (l = list; l; l = l->next)
|
||||
g_free(l->data);
|
||||
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)
|
||||
void draw_taskbarname(void *obj, cairo_t *c)
|
||||
{
|
||||
Taskbarname *taskbar_name = obj;
|
||||
Taskbar *taskbar = taskbar_name->area.parent;
|
||||
|
@ -121,54 +116,58 @@ void draw_taskbarname (void *obj, cairo_t *c)
|
|||
int state = (taskbar->desktop == server.desktop) ? TASKBAR_ACTIVE : TASKBAR_NORMAL;
|
||||
if (!panel_config.mouse_effects)
|
||||
taskbar_name->state_pix[state] = taskbar_name->area.pix;
|
||||
|
||||
|
||||
// draw content
|
||||
layout = pango_cairo_create_layout (c);
|
||||
pango_layout_set_font_description (layout, panel_config.taskbarname_font_desc);
|
||||
pango_layout_set_width (layout, taskbar_name->area.width * PANGO_SCALE);
|
||||
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
|
||||
layout = pango_cairo_create_layout(c);
|
||||
pango_layout_set_font_description(layout, panel_config.taskbarname_font_desc);
|
||||
pango_layout_set_width(layout, taskbar_name->area.width * PANGO_SCALE);
|
||||
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
|
||||
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
||||
pango_layout_set_text (layout, taskbar_name->name, strlen(taskbar_name->name));
|
||||
pango_layout_set_text(layout, taskbar_name->name, strlen(taskbar_name->name));
|
||||
|
||||
cairo_set_source_rgba (c, config_text->rgb[0], config_text->rgb[1], config_text->rgb[2], config_text->alpha);
|
||||
cairo_set_source_rgba(c, config_text->rgb[0], config_text->rgb[1], config_text->rgb[2], config_text->alpha);
|
||||
|
||||
pango_cairo_update_layout (c, layout);
|
||||
draw_text(layout, c, 0, taskbar_name->posy, config_text, ((Panel*)taskbar_name->area.panel)->font_shadow);
|
||||
pango_cairo_update_layout(c, layout);
|
||||
draw_text(layout, c, 0, taskbar_name->posy, config_text, ((Panel *)taskbar_name->area.panel)->font_shadow);
|
||||
|
||||
g_object_unref (layout);
|
||||
//printf("draw_taskbarname %s ******************************\n", taskbar_name->name);
|
||||
g_object_unref(layout);
|
||||
// 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);
|
||||
|
||||
if (panel_horizontal) {
|
||||
int new_size = name_width + (2* (taskbar_name->area.paddingxlr + taskbar_name->area.bg->border.width));
|
||||
int new_size = name_width + (2 * (taskbar_name->area.paddingxlr + taskbar_name->area.bg->border.width));
|
||||
if (new_size != taskbar_name->area.width) {
|
||||
taskbar_name->area.width = new_size;
|
||||
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;
|
||||
taskbar_name->area.height = new_size;
|
||||
taskbar_name->posy = (taskbar_name->area.height - name_height) / 2;
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
|
|
839
src/tint.c
839
src/tint.c
File diff suppressed because it is too large
Load diff
|
@ -37,15 +37,14 @@ void stop_tooltip_timeout();
|
|||
|
||||
Tooltip g_tooltip;
|
||||
|
||||
|
||||
void default_tooltip()
|
||||
{
|
||||
// give the tooltip some reasonable default values
|
||||
memset(&g_tooltip, 0, sizeof(Tooltip));
|
||||
|
||||
g_tooltip.font_color.rgb[0] = 1;
|
||||
g_tooltip.font_color.rgb[1] = 1;
|
||||
g_tooltip.font_color.rgb[2] = 1;
|
||||
g_tooltip.font_color.rgb[0] = 1;
|
||||
g_tooltip.font_color.rgb[1] = 1;
|
||||
g_tooltip.font_color.rgb[2] = 1;
|
||||
g_tooltip.font_color.alpha = 1;
|
||||
just_shown = 0;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -76,14 +74,14 @@ void init_tooltip()
|
|||
attr.colormap = server.colormap;
|
||||
attr.background_pixel = 0;
|
||||
attr.border_pixel = 0;
|
||||
unsigned long mask = CWEventMask|CWColormap|CWBorderPixel|CWBackPixel|CWOverrideRedirect;
|
||||
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)
|
||||
void tooltip_trigger_show(Area *area, Panel *p, XEvent *e)
|
||||
{
|
||||
// Position the tooltip in the center of the area
|
||||
x = area->posx + MIN(area->width / 3, 22) + e->xmotion.x_root - e->xmotion.x;
|
||||
|
@ -94,19 +92,17 @@ 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)
|
||||
void tooltip_show(void *arg)
|
||||
{
|
||||
int mx, my;
|
||||
Window w;
|
||||
XTranslateCoordinates( server.dsp, server.root_win, g_tooltip.panel->main_win, x, y, &mx, &my, &w);
|
||||
Area* area;
|
||||
XTranslateCoordinates(server.dsp, server.root_win, g_tooltip.panel->main_win, x, y, &mx, &my, &w);
|
||||
Area *area;
|
||||
area = click_area(g_tooltip.panel, mx, my);
|
||||
if (!g_tooltip.mapped && area->_get_tooltip_text) {
|
||||
tooltip_copy_text(area);
|
||||
|
@ -117,12 +113,11 @@ void tooltip_show(void* arg)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void tooltip_update_geometry()
|
||||
{
|
||||
cairo_surface_t *cs;
|
||||
cairo_t *c;
|
||||
PangoLayout* layout;
|
||||
PangoLayout *layout;
|
||||
cs = cairo_xlib_surface_create(server.dsp, g_tooltip.window, server.visual, width, height);
|
||||
c = cairo_create(cs);
|
||||
layout = pango_cairo_create_layout(c);
|
||||
|
@ -130,12 +125,12 @@ void tooltip_update_geometry()
|
|||
pango_layout_set_text(layout, g_tooltip.tooltip_text, -1);
|
||||
PangoRectangle r1, r2;
|
||||
pango_layout_get_pixel_extents(layout, &r1, &r2);
|
||||
width = 2*g_tooltip.bg->border.width + 2*g_tooltip.paddingx + r2.width;
|
||||
height = 2*g_tooltip.bg->border.width + 2*g_tooltip.paddingy + r2.height;
|
||||
width = 2 * g_tooltip.bg->border.width + 2 * g_tooltip.paddingx + r2.width;
|
||||
height = 2 * g_tooltip.bg->border.width + 2 * g_tooltip.paddingy + r2.height;
|
||||
|
||||
Panel* panel = g_tooltip.panel;
|
||||
Panel *panel = g_tooltip.panel;
|
||||
if (panel_horizontal && panel_position & BOTTOM)
|
||||
y = panel->posy-height;
|
||||
y = panel->posy - height;
|
||||
else if (panel_horizontal && panel_position & TOP)
|
||||
y = panel->posy + panel->area.height;
|
||||
else if (panel_position & LEFT)
|
||||
|
@ -148,51 +143,50 @@ void tooltip_update_geometry()
|
|||
cairo_surface_destroy(cs);
|
||||
}
|
||||
|
||||
|
||||
void tooltip_adjust_geometry()
|
||||
{
|
||||
// adjust coordinates and size to not go offscreen
|
||||
// it seems quite impossible that the height needs to be adjusted, but we do it anyway.
|
||||
|
||||
int min_x, min_y, max_width, max_height;
|
||||
Panel* panel = g_tooltip.panel;
|
||||
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 )
|
||||
return; // no adjustment needed
|
||||
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) {
|
||||
min_x=0;
|
||||
max_width=server.monitor[panel->monitor].width;
|
||||
max_height=server.monitor[panel->monitor].height-panel->area.height;
|
||||
min_x = 0;
|
||||
max_width = server.monitor[panel->monitor].width;
|
||||
max_height = server.monitor[panel->monitor].height - panel->area.height;
|
||||
if (panel_position & BOTTOM)
|
||||
min_y=0;
|
||||
min_y = 0;
|
||||
else
|
||||
min_y=panel->area.height;
|
||||
}
|
||||
else {
|
||||
max_width=server.monitor[panel->monitor].width-panel->area.width;
|
||||
min_y=0;
|
||||
max_height=server.monitor[panel->monitor].height;
|
||||
min_y = panel->area.height;
|
||||
} else {
|
||||
max_width = server.monitor[panel->monitor].width - panel->area.width;
|
||||
min_y = 0;
|
||||
max_height = server.monitor[panel->monitor].height;
|
||||
if (panel_position & LEFT)
|
||||
min_x=panel->area.width;
|
||||
min_x = panel->area.width;
|
||||
else
|
||||
min_x=0;
|
||||
min_x = 0;
|
||||
}
|
||||
|
||||
if (x+width > server.monitor[panel->monitor].x + server.monitor[panel->monitor].width)
|
||||
if (x + width > server.monitor[panel->monitor].x + server.monitor[panel->monitor].width)
|
||||
x = server.monitor[panel->monitor].x + server.monitor[panel->monitor].width - width;
|
||||
if ( y+height > server.monitor[panel->monitor].y + server.monitor[panel->monitor].height)
|
||||
if (y + height > server.monitor[panel->monitor].y + server.monitor[panel->monitor].height)
|
||||
y = server.monitor[panel->monitor].y + server.monitor[panel->monitor].height - height;
|
||||
|
||||
if (x<min_x)
|
||||
x=min_x;
|
||||
if (width>max_width)
|
||||
if (x < min_x)
|
||||
x = min_x;
|
||||
if (width > max_width)
|
||||
width = max_width;
|
||||
if (y<min_y)
|
||||
y=min_y;
|
||||
if (height>max_height)
|
||||
height=max_height;
|
||||
if (y < min_y)
|
||||
y = min_y;
|
||||
if (height > max_height)
|
||||
height = max_height;
|
||||
}
|
||||
|
||||
void tooltip_update()
|
||||
|
@ -205,7 +199,7 @@ void tooltip_update()
|
|||
tooltip_update_geometry();
|
||||
if (just_shown) {
|
||||
if (!panel_horizontal)
|
||||
y -= height/2; // center vertically
|
||||
y -= height / 2; // center vertically
|
||||
just_shown = 0;
|
||||
}
|
||||
tooltip_adjust_geometry();
|
||||
|
@ -214,65 +208,62 @@ void tooltip_update()
|
|||
// Stuff for drawing the tooltip
|
||||
cairo_surface_t *cs;
|
||||
cairo_t *c;
|
||||
PangoLayout* layout;
|
||||
PangoLayout *layout;
|
||||
cs = cairo_xlib_surface_create(server.dsp, g_tooltip.window, server.visual, width, height);
|
||||
c = cairo_create(cs);
|
||||
Color bc = g_tooltip.bg->fill_color;
|
||||
Color bc = g_tooltip.bg->fill_color;
|
||||
Border b = g_tooltip.bg->border;
|
||||
if (server.real_transparency) {
|
||||
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 {
|
||||
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 {
|
||||
cairo_rectangle(c, 0., 0, width, height);
|
||||
cairo_set_source_rgb(c, bc.rgb[0], bc.rgb[1], bc.rgb[2]);
|
||||
cairo_set_source_rgb(c, bc.rgb[0], bc.rgb[1], bc.rgb[2]);
|
||||
}
|
||||
cairo_fill(c);
|
||||
cairo_set_line_width(c, b.width);
|
||||
if (server.real_transparency)
|
||||
draw_rect(c, b.width/2.0, b.width/2.0, width - b.width, height - b.width, b.radius);
|
||||
draw_rect(c, b.width / 2.0, b.width / 2.0, width - b.width, height - b.width, b.radius);
|
||||
else
|
||||
cairo_rectangle(c, b.width/2.0, b.width/2.0, width-b.width, height-b.width);
|
||||
cairo_set_source_rgba(c, b.color.rgb[0], b.color.rgb[1], b.color.rgb[2], b.color.alpha);
|
||||
cairo_rectangle(c, b.width / 2.0, b.width / 2.0, width - b.width, height - b.width);
|
||||
cairo_set_source_rgba(c, b.color.rgb[0], b.color.rgb[1], b.color.rgb[2], b.color.alpha);
|
||||
cairo_stroke(c);
|
||||
|
||||
Color fc = g_tooltip.font_color;
|
||||
cairo_set_source_rgba(c, fc.rgb[0], fc.rgb[1], fc.rgb[2], fc.alpha);
|
||||
cairo_set_source_rgba(c, fc.rgb[0], fc.rgb[1], fc.rgb[2], fc.alpha);
|
||||
layout = pango_cairo_create_layout(c);
|
||||
pango_layout_set_font_description(layout, g_tooltip.font_desc);
|
||||
pango_layout_set_text(layout, g_tooltip.tooltip_text, -1);
|
||||
PangoRectangle r1, r2;
|
||||
pango_layout_get_pixel_extents(layout, &r1, &r2);
|
||||
pango_layout_set_width(layout, width*PANGO_SCALE);
|
||||
pango_layout_set_height(layout, height*PANGO_SCALE);
|
||||
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);
|
||||
pango_cairo_show_layout (c, layout);
|
||||
-r1.x / 2 + g_tooltip.bg->border.width + g_tooltip.paddingx,
|
||||
-r1.y / 2 + 1 + g_tooltip.bg->border.width + g_tooltip.paddingy);
|
||||
pango_cairo_show_layout(c, layout);
|
||||
|
||||
g_object_unref (layout);
|
||||
cairo_destroy (c);
|
||||
cairo_surface_destroy (cs);
|
||||
g_object_unref(layout);
|
||||
cairo_destroy(c);
|
||||
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)
|
||||
void tooltip_hide(void *arg)
|
||||
{
|
||||
if (g_tooltip.mapped) {
|
||||
g_tooltip.mapped = False;
|
||||
|
@ -281,26 +272,22 @@ 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)
|
||||
void tooltip_copy_text(Area *area)
|
||||
{
|
||||
free(g_tooltip.tooltip_text);
|
||||
if (area && area->_get_tooltip_text)
|
||||
|
|
|
@ -22,26 +22,24 @@
|
|||
#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;
|
||||
Panel* panel;
|
||||
Area *area; // never ever use the area attribut if you are not 100% sure that this area was not freed
|
||||
char *tooltip_text;
|
||||
Panel *panel;
|
||||
Window window;
|
||||
int show_timeout_msec;
|
||||
int hide_timeout_msec;
|
||||
Bool mapped;
|
||||
int paddingx;
|
||||
int paddingy;
|
||||
PangoFontDescription* font_desc;
|
||||
PangoFontDescription *font_desc;
|
||||
Color font_color;
|
||||
Background* bg;
|
||||
timeout* timeout;
|
||||
Background *bg;
|
||||
timeout *timeout;
|
||||
} Tooltip;
|
||||
|
||||
extern Tooltip g_tooltip;
|
||||
|
||||
|
||||
// default global data
|
||||
void default_tooltip();
|
||||
|
||||
|
@ -49,11 +47,11 @@ void default_tooltip();
|
|||
void cleanup_tooltip();
|
||||
|
||||
void init_tooltip();
|
||||
void tooltip_trigger_show(Area* area, Panel* p, XEvent *e);
|
||||
void tooltip_show(void* /*arg*/);
|
||||
void tooltip_trigger_show(Area *area, Panel *p, XEvent *e);
|
||||
void tooltip_show(void * /*arg*/);
|
||||
void tooltip_update();
|
||||
void tooltip_trigger_hide();
|
||||
void tooltip_hide(void* /*arg*/);
|
||||
void tooltip_copy_text(Area* area);
|
||||
void tooltip_hide(void * /*arg*/);
|
||||
void tooltip_copy_text(Area *area);
|
||||
|
||||
#endif // TOOLTIP_H
|
||||
|
|
292
src/util/area.c
292
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)
|
||||
{
|
||||
Area *a = (Area*)obj;
|
||||
|
||||
// initialize fixed position/size
|
||||
GList *l;
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
Area *child = ((Area*)l->data);
|
||||
memset(bg, 0, sizeof(Background));
|
||||
}
|
||||
|
||||
void initialize_positions(void *obj, int offset)
|
||||
{
|
||||
Area *a = (Area *)obj;
|
||||
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,17 +58,16 @@ void initialize_positions(void *obj, int pos)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void _relayout_fixed(Area *a)
|
||||
void relayout_fixed(Area *a)
|
||||
{
|
||||
if (!a->on_screen)
|
||||
return;
|
||||
|
||||
// Children are resized before the parent
|
||||
GList *l;
|
||||
for (l = a->children; l ; l = l->next)
|
||||
_relayout_fixed(l->data);
|
||||
|
||||
for (l = a->children; l; l = l->next)
|
||||
relayout_fixed(l->data);
|
||||
|
||||
// Recalculate size
|
||||
a->_changed = 0;
|
||||
if (a->resize_needed && a->size_mode == LAYOUT_FIXED) {
|
||||
|
@ -77,44 +77,40 @@ void _relayout_fixed(Area *a)
|
|||
if (a->_resize(a)) {
|
||||
// The size hash changed => resize needed for the parent
|
||||
if (a->parent)
|
||||
((Area*)a->parent)->resize_needed = 1;
|
||||
((Area *)a->parent)->resize_needed = 1;
|
||||
a->_changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
Area *child = ((Area*)l->data);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
Area *child = ((Area*)l->data);
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (!child->on_screen)
|
||||
continue;
|
||||
|
||||
|
@ -132,15 +128,15 @@ 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) {
|
||||
Area *child = ((Area*)l->data);
|
||||
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,8 +164,8 @@ void _relayout_dynamic(Area *a, int level)
|
|||
|
||||
int children_size = 0;
|
||||
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
Area *child = ((Area*)l->data);
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (!child->on_screen)
|
||||
continue;
|
||||
|
||||
|
@ -180,8 +176,8 @@ 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) {
|
||||
Area *child = ((Area*)l->data);
|
||||
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);
|
||||
a->_on_change_layout(a);
|
||||
}
|
||||
}
|
||||
|
||||
void relayout(Area *a)
|
||||
{
|
||||
relayout_fixed(a);
|
||||
relayout_dynamic(a, 1);
|
||||
}
|
||||
|
||||
void draw_tree (Area *a)
|
||||
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);
|
||||
XCopyArea(server.dsp, a->pix, ((Panel *)a->panel)->temp_pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
|
||||
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)
|
||||
draw_tree((Area*)l->data);
|
||||
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;
|
||||
if (panel_horizontal) {
|
||||
// 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,21 +322,19 @@ 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)
|
||||
schedule_redraw((Area*)l->data);
|
||||
for (GList *l = a->children; l; l = l->next)
|
||||
schedule_redraw((Area *)l->data);
|
||||
}
|
||||
|
||||
void hide(Area *a)
|
||||
{
|
||||
Area *parent = (Area*)a->parent;
|
||||
Area *parent = (Area *)a->parent;
|
||||
|
||||
a->on_screen = 0;
|
||||
a->on_screen = FALSE;
|
||||
if (parent)
|
||||
parent->resize_needed = 1;
|
||||
if (panel_horizontal)
|
||||
|
@ -360,9 +345,9 @@ void hide(Area *a)
|
|||
|
||||
void show(Area *a)
|
||||
{
|
||||
Area *parent = (Area*)a->parent;
|
||||
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);
|
||||
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,43 +376,74 @@ void draw(Area *a)
|
|||
cairo_surface_destroy(cs);
|
||||
}
|
||||
|
||||
|
||||
void draw_background (Area *a, cairo_t *c)
|
||||
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);
|
||||
}
|
||||
|
||||
if (a->bg->border.width > 0) {
|
||||
cairo_set_line_width (c, a->bg->border.width);
|
||||
cairo_set_line_width(c, a->bg->border.width);
|
||||
|
||||
// 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;
|
||||
Area *parent = (Area*)area->parent;
|
||||
Area *area = (Area *)a;
|
||||
Area *parent = (Area *)area->parent;
|
||||
|
||||
if (parent) {
|
||||
parent->children = g_list_remove(parent->children, area);
|
||||
|
@ -443,7 +456,6 @@ void remove_area(Area *a)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void add_area(Area *a, Area *parent)
|
||||
{
|
||||
g_assert_null(a->parent);
|
||||
|
@ -455,22 +467,20 @@ void add_area(Area *a, Area *parent)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void free_area (Area *a)
|
||||
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);
|
||||
a->children = 0;
|
||||
}
|
||||
if (a->pix) {
|
||||
XFreePixmap (server.dsp, a->pix);
|
||||
XFreePixmap(server.dsp, a->pix);
|
||||
a->pix = 0;
|
||||
}
|
||||
if (mouse_over_area == a) {
|
||||
|
@ -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.
|
||||
|
@ -210,10 +212,9 @@ typedef struct Area {
|
|||
|
||||
// Returns a copy of the tooltip to be displayed for this widget.
|
||||
// The caller takes ownership of the pointer.
|
||||
char* (*_get_tooltip_text)(void *obj);
|
||||
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,67 +37,69 @@
|
|||
#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];
|
||||
int nb;
|
||||
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)
|
||||
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';
|
||||
*key = strdup (line);
|
||||
*key = strdup(line);
|
||||
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);
|
||||
*value = strdup(a);
|
||||
|
||||
g_strstrip(*key);
|
||||
g_strstrip(*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);
|
||||
// sigprocmask(SIG_UNBLOCK, &sigset, 0);
|
||||
// sigset_t sigset;
|
||||
// sigprocmask(SIG_SETMASK, &sigset, 0);
|
||||
// sigprocmask(SIG_UNBLOCK, &sigset, 0);
|
||||
execl("/bin/sh", "/bin/sh", "-c", command, NULL);
|
||||
_exit(0);
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -142,98 +141,96 @@ char *contract_tilde(char *s)
|
|||
}
|
||||
}
|
||||
|
||||
int hex_char_to_int (char c)
|
||||
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 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) {
|
||||
*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) {
|
||||
*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;
|
||||
*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) {
|
||||
*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) {
|
||||
*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;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void get_color (char *hex, double *rgb)
|
||||
void get_color(char *hex, double *rgb)
|
||||
{
|
||||
int r, g, b;
|
||||
r = g = b = 0;
|
||||
hex_to_rgb (hex, &r, &g, &b);
|
||||
hex_to_rgb(hex, &r, &g, &b);
|
||||
|
||||
rgb[0] = (r / 255.0);
|
||||
rgb[1] = (g / 255.0);
|
||||
rgb[2] = (b / 255.0);
|
||||
}
|
||||
|
||||
|
||||
void extract_values (const char *value, char **value1, char **value2, char **value3)
|
||||
void extract_values(const char *value, char **value1, char **value2, char **value3)
|
||||
{
|
||||
char *b=0, *c=0;
|
||||
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, ' '))) {
|
||||
if ((b = strchr(value, ' '))) {
|
||||
b[0] = '\0';
|
||||
b++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
*value2 = 0;
|
||||
*value3 = 0;
|
||||
}
|
||||
*value1 = strdup (value);
|
||||
*value1 = strdup(value);
|
||||
g_strstrip(*value1);
|
||||
|
||||
if (b) {
|
||||
if ((c = strchr (b, ' '))) {
|
||||
if ((c = strchr(b, ' '))) {
|
||||
c[0] = '\0';
|
||||
c++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
c = 0;
|
||||
*value3 = 0;
|
||||
}
|
||||
*value2 = strdup (b);
|
||||
*value2 = strdup(b);
|
||||
g_strstrip(*value2);
|
||||
}
|
||||
|
||||
if (c) {
|
||||
*value3 = strdup (c);
|
||||
*value3 = strdup(c);
|
||||
g_strstrip(*value3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
@ -244,21 +241,24 @@ void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright
|
|||
float hue, saturation, brightness;
|
||||
float redc, greenc, bluec;
|
||||
|
||||
for(y = 0; y < h; y++) {
|
||||
for(id = y * w, x = 0; x < w; x++, id++) {
|
||||
for (y = 0; y < h; y++) {
|
||||
for (id = y * w, x = 0; x < w; x++, id++) {
|
||||
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;
|
||||
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,13 +283,17 @@ 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;
|
||||
a = (a * alpha) / 100;
|
||||
|
||||
// convert HSB to RGB
|
||||
if (saturation == 0) {
|
||||
|
@ -300,7 +304,7 @@ void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright
|
|||
p = brightness * (1.0f - saturation);
|
||||
q = brightness * (1.0f - saturation * f);
|
||||
t = brightness * (1.0f - (saturation * (1.0f - f)));
|
||||
switch ((int) h2) {
|
||||
switch ((int)h2) {
|
||||
case 0:
|
||||
r = (int)(brightness * 255.0f + 0.5f);
|
||||
g = (int)(t * 255.0f + 0.5f);
|
||||
|
@ -343,34 +347,33 @@ 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)
|
||||
unsigned int topLeft = data[0], topRight = data[w-1], bottomLeft = data[w*h-w], bottomRight = data[w*h-1];
|
||||
unsigned int topLeft = data[0], topRight = data[w - 1], bottomLeft = data[w * h - w], bottomRight = data[w * h - 1];
|
||||
int max = (topLeft == topRight) + (topLeft == bottomLeft) + (topLeft == bottomRight);
|
||||
int maskPos = 0;
|
||||
if ( max < (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight) ) {
|
||||
if (max < (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight)) {
|
||||
max = (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight);
|
||||
maskPos = w-1;
|
||||
maskPos = w - 1;
|
||||
}
|
||||
if ( max < (bottomLeft == topRight) + (bottomLeft == topLeft) + (bottomLeft == bottomRight) )
|
||||
maskPos = w*h-w;
|
||||
if (max < (bottomLeft == topRight) + (bottomLeft == topLeft) + (bottomLeft == bottomRight))
|
||||
maskPos = w * h - w;
|
||||
|
||||
// now mask out every pixel which has the same color as the edge pixels
|
||||
unsigned char* udata = (unsigned char*)data;
|
||||
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) {
|
||||
if ( b-udata[0] == 0 && g-udata[1] == 0 && r-udata[2] == 0 )
|
||||
unsigned char *udata = (unsigned char *)data;
|
||||
unsigned char b = udata[4 * maskPos];
|
||||
unsigned char g = udata[4 * maskPos + 1];
|
||||
unsigned char r = udata[4 * maskPos + 1];
|
||||
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,29 +384,27 @@ 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])) {
|
||||
//fprintf(stderr, "Non-empty pixel: [%u, %u] = %x\n", x, y, 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])) {
|
||||
//fprintf(stderr, "Non-empty pixel: [%u, %u] = %x\n", x, y, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//fprintf(stderr, "All pixels are empty\n");
|
||||
// fprintf(stderr, "All pixels are empty\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -430,7 +431,7 @@ void render_image(Drawable d, int x, int y)
|
|||
|
||||
Picture pict = XRenderCreatePicture(server.dsp, pixmap, XRenderFindStandardFormat(server.dsp, PictStandardARGB32), 0, 0);
|
||||
Picture pict_drawable = XRenderCreatePicture(server.dsp, d, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
|
||||
Picture pict_mask = XRenderCreatePicture(server.dsp, mask, XRenderFindStandardFormat(server.dsp, PictStandardARGB32), 0, 0);
|
||||
Picture pict_mask = XRenderCreatePicture(server.dsp, mask, XRenderFindStandardFormat(server.dsp, PictStandardARGB32), 0, 0);
|
||||
XRenderComposite(server.dsp, PictOpOver, pict, pict_mask, pict_drawable, 0, 0, 0, 0, x, y, w, h);
|
||||
|
||||
XRenderFreePicture(server.dsp, pict_mask);
|
||||
|
@ -448,17 +449,23 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
cairo_set_source_rgba (c, color->rgb[0], color->rgb[1], color->rgb[2], color->alpha);
|
||||
pango_cairo_update_layout (c, layout);
|
||||
cairo_move_to (c, posx, posy);
|
||||
pango_cairo_show_layout (c, layout);
|
||||
cairo_set_source_rgba(c, color->rgb[0], color->rgb[1], color->rgb[2], color->alpha);
|
||||
pango_cairo_update_layout(c, layout);
|
||||
cairo_move_to(c, posx, posy);
|
||||
pango_cairo_show_layout(c, layout);
|
||||
}
|
||||
|
||||
Imlib_Image load_image(const char *path, int cached)
|
||||
|
@ -477,8 +484,8 @@ Imlib_Image load_image(const char *path, int cached)
|
|||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
// Child
|
||||
GError* err = NULL;
|
||||
RsvgHandle* svg = rsvg_handle_new_from_file(path, &err);
|
||||
GError *err = NULL;
|
||||
RsvgHandle *svg = rsvg_handle_new_from_file(path, &err);
|
||||
|
||||
if (err != NULL) {
|
||||
fprintf(stderr, "Could not load svg image!: %s", err->message);
|
||||
|
@ -519,8 +526,13 @@ 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);
|
||||
DATA32 *data = imlib_image_get_data();
|
||||
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;
|
||||
}
|
||||
|
@ -530,25 +542,62 @@ void draw_rect(cairo_t *c, double x, double y, double w, double h, double r)
|
|||
if (r > 0.0) {
|
||||
double c1 = 0.55228475 * r;
|
||||
|
||||
cairo_move_to(c, x+r, y);
|
||||
cairo_rel_line_to(c, w-2*r, 0);
|
||||
cairo_move_to(c, x + r, y);
|
||||
cairo_rel_line_to(c, w - 2 * r, 0);
|
||||
cairo_rel_curve_to(c, c1, 0.0, r, c1, r, r);
|
||||
cairo_rel_line_to(c, 0, h-2*r);
|
||||
cairo_rel_curve_to(c, 0.0, c1, c1-r, r, -r, r);
|
||||
cairo_rel_line_to (c, -w +2*r, 0);
|
||||
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
|
||||
cairo_rel_line_to(c, 0, h - 2 * r);
|
||||
cairo_rel_curve_to(c, 0.0, c1, c1 - r, r, -r, r);
|
||||
cairo_rel_line_to(c, -w + 2 * r, 0);
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#define WM_CLASS_TINT "panel"
|
||||
#define WM_CLASS_TINT "panel"
|
||||
|
||||
#include <Imlib2.h>
|
||||
#include <pango/pangocairo.h>
|
||||
|
@ -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);
|
||||
// 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);
|
||||
|
||||
// extract key = value
|
||||
int parse_line (const char *line, char **key, char **value);
|
||||
void extract_values(const char *value, char **value1, char **value2, char **value3);
|
||||
|
||||
// execute a command by calling fork
|
||||
void tint_exec(const char* command);
|
||||
// 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
|
||||
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);
|
||||
|
||||
// adjust Alpha/Saturation/Brightness on an ARGB icon
|
||||
// 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);
|
||||
|
||||
void render_image(Drawable d, int x, int y);
|
||||
|
||||
void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, int font_shadow);
|
||||
// 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);
|
||||
|
||||
Imlib_Image load_image(const char *path, int cached);
|
||||
|
||||
// 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);
|
||||
Imlib_Image adjust_icon(Imlib_Image original, int alpha, int saturation, int brightness);
|
||||
|
||||
// draw rounded rectangle
|
||||
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);
|
||||
|
||||
// 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,142 +36,129 @@
|
|||
|
||||
#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);
|
||||
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);
|
||||
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);
|
||||
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. */
|
||||
for (;; a++, b++) {
|
||||
if (!nat_isdigit(*a) && !nat_isdigit(*b))
|
||||
return bias;
|
||||
else if (!nat_isdigit(*a))
|
||||
return -1;
|
||||
else if (!nat_isdigit(*b))
|
||||
return +1;
|
||||
else if (*a < *b) {
|
||||
if (!bias)
|
||||
bias = -1;
|
||||
} else if (*a > *b) {
|
||||
if (!bias)
|
||||
bias = +1;
|
||||
} else if (!*a && !*b)
|
||||
return bias;
|
||||
}
|
||||
int bias = 0;
|
||||
|
||||
return 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. */
|
||||
for (;; a++, b++) {
|
||||
if (!nat_isdigit(*a) && !nat_isdigit(*b))
|
||||
return bias;
|
||||
else if (!nat_isdigit(*a))
|
||||
return -1;
|
||||
else if (!nat_isdigit(*b))
|
||||
return +1;
|
||||
else if (*a < *b) {
|
||||
if (!bias)
|
||||
bias = -1;
|
||||
} else if (*a > *b) {
|
||||
if (!bias)
|
||||
bias = +1;
|
||||
} else if (!*a && !*b)
|
||||
return bias;
|
||||
}
|
||||
|
||||
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. */
|
||||
for (;; a++, b++) {
|
||||
if (!nat_isdigit(*a) && !nat_isdigit(*b))
|
||||
return 0;
|
||||
else if (!nat_isdigit(*a))
|
||||
return -1;
|
||||
else if (!nat_isdigit(*b))
|
||||
return +1;
|
||||
else if (*a < *b)
|
||||
return -1;
|
||||
else if (*a > *b)
|
||||
return +1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* 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;
|
||||
else if (!nat_isdigit(*a))
|
||||
return -1;
|
||||
else if (!nat_isdigit(*b))
|
||||
return +1;
|
||||
else if (*a < *b)
|
||||
return -1;
|
||||
else if (*a > *b)
|
||||
return +1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
|
||||
{
|
||||
int ai, bi;
|
||||
nat_char ca, cb;
|
||||
int fractional, result;
|
||||
|
||||
assert(a && b);
|
||||
ai = bi = 0;
|
||||
while (1) {
|
||||
ca = a[ai]; cb = b[bi];
|
||||
int ai, bi;
|
||||
nat_char ca, cb;
|
||||
int fractional, result;
|
||||
|
||||
/* skip over leading spaces or zeros */
|
||||
while (nat_isspace(ca))
|
||||
ca = a[++ai];
|
||||
assert(a && b);
|
||||
ai = bi = 0;
|
||||
while (1) {
|
||||
ca = a[ai];
|
||||
cb = b[bi];
|
||||
|
||||
while (nat_isspace(cb))
|
||||
cb = b[++bi];
|
||||
/* skip over leading spaces or zeros */
|
||||
while (nat_isspace(ca))
|
||||
ca = a[++ai];
|
||||
|
||||
/* process run of digits */
|
||||
if (nat_isdigit(ca) && nat_isdigit(cb)) {
|
||||
fractional = (ca == '0' || cb == '0');
|
||||
while (nat_isspace(cb))
|
||||
cb = b[++bi];
|
||||
|
||||
if (fractional) {
|
||||
if ((result = compare_left(a+ai, b+bi)) != 0)
|
||||
return result;
|
||||
} else {
|
||||
if ((result = compare_right(a+ai, b+bi)) != 0)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
/* process run of digits */
|
||||
if (nat_isdigit(ca) && nat_isdigit(cb)) {
|
||||
fractional = (ca == '0' || cb == '0');
|
||||
|
||||
if (!ca && !cb) {
|
||||
/* The strings compare the same. Perhaps the caller
|
||||
will want to call strcmp to break the tie. */
|
||||
return 0;
|
||||
}
|
||||
if (fractional) {
|
||||
if ((result = compare_left(a + ai, b + bi)) != 0)
|
||||
return result;
|
||||
} else {
|
||||
if ((result = compare_right(a + ai, b + bi)) != 0)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (fold_case) {
|
||||
ca = nat_toupper(ca);
|
||||
cb = nat_toupper(cb);
|
||||
}
|
||||
|
||||
if (ca < cb)
|
||||
return -1;
|
||||
else if (ca > cb)
|
||||
return +1;
|
||||
if (!ca && !cb) {
|
||||
/* The strings compare the same. Perhaps the caller will want to call strcmp to break the tie. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
++ai; ++bi;
|
||||
}
|
||||
if (fold_case) {
|
||||
ca = nat_toupper(ca);
|
||||
cb = nat_toupper(cb);
|
||||
}
|
||||
|
||||
if (ca < cb)
|
||||
return -1;
|
||||
else if (ca > cb)
|
||||
return +1;
|
||||
|
||||
++ai;
|
||||
++bi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int strnatcmp(nat_char const *a, nat_char const *b) {
|
||||
return strnatcmp0(a, b, 0);
|
||||
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) {
|
||||
return strnatcmp0(a, b, 1);
|
||||
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
|
||||
|
|
191
src/util/timer.c
191
src/util/timer.c
|
@ -22,10 +22,9 @@
|
|||
|
||||
#include "timer.h"
|
||||
|
||||
GSList* timeout_list;
|
||||
GSList *timeout_list;
|
||||
struct timeval next_timeout;
|
||||
GHashTable* multi_timeouts;
|
||||
|
||||
GHashTable *multi_timeouts;
|
||||
|
||||
// functions and structs for multi timeouts
|
||||
typedef struct {
|
||||
|
@ -34,32 +33,31 @@ typedef struct {
|
|||
} multi_timeout;
|
||||
|
||||
typedef struct {
|
||||
GSList* timeout_list;
|
||||
timeout* parent_timeout;
|
||||
GSList *timeout_list;
|
||||
timeout *parent_timeout;
|
||||
} multi_timeout_handler;
|
||||
|
||||
struct _timeout {
|
||||
int interval_msec;
|
||||
struct timespec timeout_expires;
|
||||
void (*_callback)(void*);
|
||||
void* arg;
|
||||
multi_timeout* multi_timeout;
|
||||
void (*_callback)(void *);
|
||||
void *arg;
|
||||
multi_timeout *multi_timeout;
|
||||
timeout **self;
|
||||
};
|
||||
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(void*), void* arg, timeout* t);
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout *t);
|
||||
gint compare_timeouts(gconstpointer t1, gconstpointer t2);
|
||||
int timespec_subtract(struct timespec* result, struct timespec* x, struct timespec* y);
|
||||
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);
|
||||
int calc_multi_timeout_interval(multi_timeout_handler* mth);
|
||||
void update_multi_timeout_values(multi_timeout_handler* mth);
|
||||
void callback_multi_timeout(void* mth);
|
||||
void remove_from_multi_timeout(timeout* t);
|
||||
void stop_multi_timeout(timeout* t);
|
||||
int align_with_existing_timeouts(timeout *t);
|
||||
void create_multi_timeout(timeout *t1, timeout *t2);
|
||||
void append_multi_timeout(timeout *t1, timeout *t2);
|
||||
int calc_multi_timeout_interval(multi_timeout_handler *mth);
|
||||
void update_multi_timeout_values(multi_timeout_handler *mth);
|
||||
void callback_multi_timeout(void *mth);
|
||||
void remove_from_multi_timeout(timeout *t);
|
||||
void stop_multi_timeout(timeout *t);
|
||||
|
||||
void default_timeout()
|
||||
{
|
||||
|
@ -70,7 +68,7 @@ void default_timeout()
|
|||
void cleanup_timeout()
|
||||
{
|
||||
while (timeout_list) {
|
||||
timeout* t = timeout_list->data;
|
||||
timeout *t = timeout_list->data;
|
||||
if (t->multi_timeout)
|
||||
stop_multi_timeout(t);
|
||||
if (t->self)
|
||||
|
@ -84,28 +82,27 @@ 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)
|
||||
timeout *add_timeout(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout **self)
|
||||
{
|
||||
timeout* t = calloc(1, sizeof(timeout));
|
||||
timeout *t = calloc(1, sizeof(timeout));
|
||||
t->self = self;
|
||||
add_timeout_intern(value_msec, interval_msec, _callback, arg, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
void change_timeout(timeout **t, int value_msec, int interval_msec, void(*_callback)(), void* arg)
|
||||
void change_timeout(timeout **t, int value_msec, int interval_msec, void (*_callback)(), void *arg)
|
||||
{
|
||||
if (!((timeout_list && g_slist_find(timeout_list, *t)) ||
|
||||
(multi_timeouts && g_hash_table_lookup(multi_timeouts, *t))))
|
||||
|
@ -119,32 +116,28 @@ void change_timeout(timeout **t, int value_msec, int interval_msec, void(*_callb
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void update_next_timeout()
|
||||
{
|
||||
if (timeout_list) {
|
||||
timeout* t = timeout_list->data;
|
||||
timeout *t = timeout_list->data;
|
||||
struct timespec cur_time;
|
||||
struct timespec next_timeout2 = { .tv_sec=next_timeout.tv_sec, .tv_nsec=next_timeout.tv_usec*1000 };
|
||||
struct timespec next_timeout2 = {.tv_sec = next_timeout.tv_sec, .tv_nsec = next_timeout.tv_usec * 1000};
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
if (timespec_subtract(&next_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;
|
||||
next_timeout.tv_usec = next_timeout2.tv_nsec / 1000;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
next_timeout.tv_sec = -1;
|
||||
}
|
||||
|
||||
|
||||
void callback_timeout_expired()
|
||||
{
|
||||
struct timespec cur_time;
|
||||
timeout* t;
|
||||
timeout *t;
|
||||
while (timeout_list) {
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
t = timeout_list->data;
|
||||
|
@ -170,14 +163,12 @@ void callback_timeout_expired()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void stop_timeout(timeout* t)
|
||||
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,8 +179,7 @@ void stop_timeout(timeout* t)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), void* arg, timeout *t)
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void (*_callback)(), void *arg, timeout *t)
|
||||
{
|
||||
t->interval_msec = interval_msec;
|
||||
t->_callback = _callback;
|
||||
|
@ -205,15 +195,12 @@ 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)
|
||||
gint compare_timespecs(const struct timespec *t1, const struct timespec *t2)
|
||||
{
|
||||
if (t1->tv_sec < t2->tv_sec)
|
||||
return -1;
|
||||
|
@ -224,12 +211,11 @@ gint compare_timespecs(const struct timespec* t1, const struct timespec* t2)
|
|||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int timespec_subtract(struct timespec* result, struct timespec* x, struct timespec* y)
|
||||
int timespec_subtract(struct timespec *result, struct timespec *x, struct timespec *y)
|
||||
{
|
||||
/* Perform the carry for the later subtraction by updating y. */
|
||||
if (x->tv_nsec < y->tv_nsec) {
|
||||
|
@ -251,27 +237,25 @@ 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;
|
||||
ts.tv_nsec += (msec % 1000)*1000000;
|
||||
if (ts.tv_nsec >= 1000000000) { // 10^9
|
||||
ts.tv_nsec += (msec % 1000) * 1000000;
|
||||
if (ts.tv_nsec >= 1000000000) { // 10^9
|
||||
ts.tv_sec++;
|
||||
ts.tv_nsec -= 1000000000;
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
int align_with_existing_timeouts(timeout *t)
|
||||
{
|
||||
GSList* it = timeout_list;
|
||||
GSList *it = timeout_list;
|
||||
while (it) {
|
||||
timeout* t2 = it->data;
|
||||
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,11 +272,10 @@ int align_with_existing_timeouts(timeout *t)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int calc_multi_timeout_interval(multi_timeout_handler* mth)
|
||||
int calc_multi_timeout_interval(multi_timeout_handler *mth)
|
||||
{
|
||||
GSList* it = mth->timeout_list;
|
||||
timeout* t = it->data;
|
||||
GSList *it = mth->timeout_list;
|
||||
timeout *t = it->data;
|
||||
int min_interval = t->interval_msec;
|
||||
it = it->next;
|
||||
while (it) {
|
||||
|
@ -304,13 +287,12 @@ int calc_multi_timeout_interval(multi_timeout_handler* mth)
|
|||
return min_interval;
|
||||
}
|
||||
|
||||
|
||||
void create_multi_timeout(timeout* t1, timeout* t2)
|
||||
void create_multi_timeout(timeout *t1, timeout *t2)
|
||||
{
|
||||
multi_timeout* mt1 = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout* mt2 = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout_handler* mth = calloc(1, sizeof(multi_timeout_handler));
|
||||
timeout* real_timeout = calloc(1, sizeof(timeout));
|
||||
multi_timeout *mt1 = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout *mt2 = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout_handler *mth = calloc(1, sizeof(multi_timeout_handler));
|
||||
timeout *real_timeout = calloc(1, sizeof(timeout));
|
||||
|
||||
mth->timeout_list = 0;
|
||||
mth->timeout_list = g_slist_prepend(mth->timeout_list, t1);
|
||||
|
@ -325,7 +307,7 @@ void create_multi_timeout(timeout* t1, timeout* t2)
|
|||
t2->multi_timeout = mt2;
|
||||
// set real_timeout->multi_timeout to something, such that we see in add_timeout_intern that
|
||||
// it is already a multi_timeout (we never use it, except of checking for 0 ptr)
|
||||
real_timeout->multi_timeout = (void*)real_timeout;
|
||||
real_timeout->multi_timeout = (void *)real_timeout;
|
||||
|
||||
timeout_list = g_slist_remove(timeout_list, t1);
|
||||
timeout_list = g_slist_remove(timeout_list, t2);
|
||||
|
@ -333,18 +315,17 @@ void create_multi_timeout(timeout* t1, timeout* t2)
|
|||
update_multi_timeout_values(mth);
|
||||
}
|
||||
|
||||
|
||||
void append_multi_timeout(timeout* t1, timeout* t2)
|
||||
void append_multi_timeout(timeout *t1, timeout *t2)
|
||||
{
|
||||
if (t2->multi_timeout) {
|
||||
// swap t1 and t2 such that t1 is the multi timeout
|
||||
timeout* tmp = t2;
|
||||
timeout *tmp = t2;
|
||||
t2 = t1;
|
||||
t1 = tmp;
|
||||
}
|
||||
|
||||
multi_timeout* mt = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t1);
|
||||
multi_timeout *mt = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t1);
|
||||
|
||||
mth->timeout_list = g_slist_prepend(mth->timeout_list, t2);
|
||||
g_hash_table_insert(multi_timeouts, t2, mth);
|
||||
|
@ -354,8 +335,7 @@ void append_multi_timeout(timeout* t1, timeout* t2)
|
|||
update_multi_timeout_values(mth);
|
||||
}
|
||||
|
||||
|
||||
void update_multi_timeout_values(multi_timeout_handler* mth)
|
||||
void update_multi_timeout_values(multi_timeout_handler *mth)
|
||||
{
|
||||
int interval = calc_multi_timeout_interval(mth);
|
||||
int next_timeout_msec = interval;
|
||||
|
@ -363,14 +343,14 @@ void update_multi_timeout_values(multi_timeout_handler* mth)
|
|||
struct timespec cur_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
|
||||
GSList* it = mth->timeout_list;
|
||||
GSList *it = mth->timeout_list;
|
||||
struct timespec diff_time;
|
||||
while (it) {
|
||||
timeout* t = it->data;
|
||||
timeout *t = it->data;
|
||||
t->multi_timeout->count_to_expiration = t->interval_msec / interval;
|
||||
timespec_subtract(&diff_time, &t->timeout_expires, &cur_time);
|
||||
int msec_to_expiration = diff_time.tv_sec*1000 + diff_time.tv_nsec/1000000;
|
||||
int count_left = msec_to_expiration / interval + (msec_to_expiration%interval != 0);
|
||||
int msec_to_expiration = diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000;
|
||||
int count_left = msec_to_expiration / interval + (msec_to_expiration % interval != 0);
|
||||
t->multi_timeout->current_count = t->multi_timeout->count_to_expiration - count_left;
|
||||
if (msec_to_expiration < next_timeout_msec)
|
||||
next_timeout_msec = msec_to_expiration;
|
||||
|
@ -382,15 +362,14 @@ 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)
|
||||
void callback_multi_timeout(void *arg)
|
||||
{
|
||||
multi_timeout_handler* mth = arg;
|
||||
multi_timeout_handler *mth = arg;
|
||||
struct timespec cur_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
GSList* it = mth->timeout_list;
|
||||
GSList *it = mth->timeout_list;
|
||||
while (it) {
|
||||
timeout* t = it->data;
|
||||
timeout *t = it->data;
|
||||
if (++t->multi_timeout->current_count >= t->multi_timeout->count_to_expiration) {
|
||||
t->_callback(t->arg);
|
||||
if (multi_timeouts && g_hash_table_lookup(multi_timeouts, t)) {
|
||||
|
@ -405,10 +384,9 @@ void callback_multi_timeout(void* arg)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void remove_from_multi_timeout(timeout* t)
|
||||
void remove_from_multi_timeout(timeout *t)
|
||||
{
|
||||
multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t);
|
||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t);
|
||||
g_hash_table_remove(multi_timeouts, t);
|
||||
|
||||
mth->timeout_list = g_slist_remove(mth->timeout_list, t);
|
||||
|
@ -416,7 +394,7 @@ void remove_from_multi_timeout(timeout* t)
|
|||
t->multi_timeout = 0;
|
||||
|
||||
if (g_slist_length(mth->timeout_list) == 1) {
|
||||
timeout* last_timeout = mth->timeout_list->data;
|
||||
timeout *last_timeout = mth->timeout_list->data;
|
||||
mth->timeout_list = g_slist_remove(mth->timeout_list, last_timeout);
|
||||
free(last_timeout->multi_timeout);
|
||||
last_timeout->multi_timeout = 0;
|
||||
|
@ -429,20 +407,22 @@ void remove_from_multi_timeout(timeout* t)
|
|||
struct timespec cur_time, diff_time;
|
||||
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
|
||||
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
|
||||
update_multi_timeout_values(mth);
|
||||
}
|
||||
|
||||
|
||||
void stop_multi_timeout(timeout* t)
|
||||
void stop_multi_timeout(timeout *t)
|
||||
{
|
||||
multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t);
|
||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t);
|
||||
g_hash_table_remove(multi_timeouts, mth->parent_timeout);
|
||||
while (mth->timeout_list) {
|
||||
timeout* t1 = mth->timeout_list->data;
|
||||
timeout *t1 = mth->timeout_list->data;
|
||||
mth->timeout_list = g_slist_remove(mth->timeout_list, t1);
|
||||
g_hash_table_remove(multi_timeouts, t1);
|
||||
free(t1->multi_timeout);
|
||||
|
@ -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.
|
||||
**/
|
||||
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg, timeout **self);
|
||||
// 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'. **/
|
||||
void change_timeout(timeout** t, int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
|
||||
// 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' **/
|
||||
void stop_timeout(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 **/
|
||||
gint compare_timespecs(const struct timespec* t1, const struct timespec* 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,8 +36,9 @@ 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) {
|
||||
if ((end-str) < prefixlen)
|
||||
static const char *has_prefix(const char *str, const char *end, const char *prefix, size_t prefixlen)
|
||||
{
|
||||
if ((end - str) < prefixlen)
|
||||
return NULL;
|
||||
|
||||
if (!memcmp(str, prefix, prefixlen))
|
||||
|
@ -46,38 +47,40 @@ static const char* has_prefix(const char *str, const char *end, const char *pref
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#define HAS_CONST_PREFIX(str,end,prefix) has_prefix((str),end,prefix,sizeof(prefix)-1)
|
||||
#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';
|
||||
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, '@');
|
||||
|
@ -87,10 +90,10 @@ static struct uevent *uevent_new(char *buffer, int size) {
|
|||
free(ev);
|
||||
return NULL;
|
||||
}
|
||||
ev->path = strdup(p+1);
|
||||
ev->path = strdup(p + 1);
|
||||
first = FALSE;
|
||||
} else {
|
||||
const char* val;
|
||||
const char *val;
|
||||
if ((val = HAS_CONST_PREFIX(s, end, "ACTION=")) != NULL) {
|
||||
if (!strcmp(val, "add"))
|
||||
ev->action = UEVENT_ADD;
|
||||
|
@ -109,8 +112,8 @@ static struct uevent *uevent_new(char *buffer, int size) {
|
|||
if (val) {
|
||||
struct uevent_parameter *param = malloc(sizeof(*param));
|
||||
if (param) {
|
||||
param->key = strndup(s, val-s);
|
||||
param->val = strdup(val+1);
|
||||
param->key = strndup(s, val - s);
|
||||
param->val = strdup(val + 1);
|
||||
ev->params = g_list_append(ev->params, param);
|
||||
}
|
||||
}
|
||||
|
@ -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,9 +172,10 @@ void uevent_handler() {
|
|||
}
|
||||
}
|
||||
|
||||
int uevent_init() {
|
||||
int uevent_init()
|
||||
{
|
||||
/* Open hotplug event netlink socket */
|
||||
memset(&nls,0,sizeof(struct sockaddr_nl));
|
||||
memset(&nls, 0, sizeof(struct sockaddr_nl));
|
||||
nls.nl_family = AF_NETLINK;
|
||||
nls.nl_pid = getpid();
|
||||
nls.nl_groups = -1;
|
||||
|
@ -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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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) ) {
|
||||
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) {
|
||||
at = server_get_property(win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, &count);
|
||||
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,81 +144,73 @@ 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;
|
||||
Window src;
|
||||
XTranslateCoordinates(server.dsp, win, server.root_win, 0, 0, x, y, &src);
|
||||
Window src;
|
||||
XTranslateCoordinates(server.dsp, win, server.root_win, 0, 0, x, y, &src);
|
||||
XGetGeometry(server.dsp, win, &src, &dummy_int, &dummy_int, &ww, &wh, &bw, &bh);
|
||||
*w = ww + bw;
|
||||
*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++) {
|
||||
if (*(data_ptr + j) == '\0') {
|
||||
ptr = (gchar*)data_ptr + j + 1;
|
||||
for (int j = 0; j < count - 1; j++) {
|
||||
if (*(data_ptr + j) == '\0') {
|
||||
gchar *ptr = (gchar *)data_ptr + j + 1;
|
||||
list = g_slist_append(list, g_strdup(ptr));
|
||||
}
|
||||
}
|
||||
|
@ -238,44 +219,40 @@ 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 get_icon_count(gulong *data, int num)
|
||||
{
|
||||
int count, pos, w, h;
|
||||
|
||||
count = 0;
|
||||
pos = 0;
|
||||
while (pos+2 < num) {
|
||||
while (pos + 2 < 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)
|
||||
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;
|
||||
gulong *icon_data[icon_count];
|
||||
|
@ -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;
|
||||
|
@ -309,8 +287,8 @@ gulong *get_best_icon (gulong *data, int icon_count, int num, int *iw, int *ih,
|
|||
int highest = 0;
|
||||
for (i = 0; i < icon_count; i++) {
|
||||
if (width[i] > highest) {
|
||||
icon_num = i;
|
||||
highest = width[i];
|
||||
icon_num = i;
|
||||
highest = width[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
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 ();
|
||||
Window get_active_window();
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -160,3 +160,4 @@ src/battery/linux.c
|
|||
src/battery/openbsd.c
|
||||
src/util/uevent.c
|
||||
src/util/uevent.h
|
||||
.clang-format
|
||||
|
|
Loading…
Reference in a new issue