Support for NETWM viewports (compiz)

This commit is contained in:
o9000
2015-11-21 04:35:12 +01:00
parent 4a6937826c
commit eb044da8bc
11 changed files with 537 additions and 349 deletions

View File

@@ -18,22 +18,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**************************************************************************/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include "window.h"
#include "panel.h"
#include "server.h"
#include "task.h"
#include "taskbar.h"
#include "server.h"
#include "panel.h"
#include "tooltip.h"
#include "timer.h"
#include "tooltip.h"
#include "window.h"
timeout *urgent_timeout;
GSList *urgent_list;
@@ -47,102 +47,99 @@ char *task_get_tooltip(void *obj)
Task *add_task(Window win)
{
if (!win)
return 0;
return NULL;
if (window_is_hidden(win))
return 0;
return NULL;
XSelectInput(server.dsp, win, PropertyChangeMask | StructureNotifyMask);
XFlush(server.dsp);
int monitor;
int monitor = 0;
if (num_panels > 1) {
monitor = get_window_monitor(win);
if (monitor >= num_panels)
monitor = 0;
} else
monitor = 0;
}
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);
// TODO why do we add the task only to the panel for the current monitor, without checking hide_task_diff_monitor?
Task task_template;
memset(&task_template, 0, sizeof(task_template));
task_template.area.has_mouse_over_effect = TRUE;
task_template.area.has_mouse_press_effect = TRUE;
task_template.win = win;
task_template.desktop = get_window_desktop(win);
task_template.area.panel = &panels[monitor];
task_template.current_state = window_is_iconified(win) ? TASK_ICONIFIED : TASK_NORMAL;
get_window_coordinates(win, &task_template.win_x, &task_template.win_y, &task_template.win_w, &task_template.win_h);
// allocate only one title and one icon
// even with task_on_all_desktop and with task_on_all_panel
new_task.title = 0;
int k;
for (k = 0; k < TASK_STATE_COUNT; ++k) {
new_task.icon[k] = 0;
new_task.state_pix[k] = 0;
task_template.title = NULL;
for (int k = 0; k < TASK_STATE_COUNT; ++k) {
task_template.icon[k] = NULL;
task_template.state_pix[k] = 0;
}
get_title(&new_task);
get_icon(&new_task);
get_title(&task_template);
get_icon(&task_template);
// 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 *taskbar;
Task *new_task2 = 0;
int j;
for (j = 0; j < panels[monitor].num_desktops; j++) {
if (new_task.desktop != ALLDESKTOP && new_task.desktop != j)
for (int j = 0; j < panels[monitor].num_desktops; j++) {
if (task_template.desktop != ALL_DESKTOPS && task_template.desktop != j)
continue;
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_task2->area.on_screen = FALSE;
Taskbar *taskbar = &panels[monitor].taskbar[j];
Task *task_instance = calloc(1, sizeof(Task));
memcpy(&task_instance->area, &panels[monitor].g_task.area, sizeof(Area));
task_instance->area.has_mouse_over_effect = TRUE;
task_instance->area.has_mouse_press_effect = TRUE;
task_instance->win = task_template.win;
task_instance->desktop = task_template.desktop;
task_instance->win_x = task_template.win_x;
task_instance->win_y = task_template.win_y;
task_instance->win_w = task_template.win_w;
task_instance->win_h = task_template.win_h;
task_instance->current_state = -1; // to update the current state later in set_task_state...
if (task_instance->desktop == ALL_DESKTOPS && server.desktop != j) {
// hide ALL_DESKTOPS task on non-current desktop
task_instance->area.on_screen = FALSE;
}
new_task2->title = new_task.title;
task_instance->title = task_template.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;
task_instance->area._get_tooltip_text = task_get_tooltip;
for (int k = 0; k < TASK_STATE_COUNT; ++k) {
task_instance->icon[k] = task_template.icon[k];
task_instance->icon_hover[k] = task_template.icon_hover[k];
task_instance->icon_press[k] = task_template.icon_press[k];
task_instance->state_pix[k] = 0;
}
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);
task_instance->icon_width = task_template.icon_width;
task_instance->icon_height = task_template.icon_height;
add_area(&task_instance->area, &taskbar->area);
g_ptr_array_add(task_group, task_instance);
// printf("add_task panel %d, desktop %d, task %s\n", i, j, task_instance->title);
}
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_task2, new_task.current_state);
*key = task_template.win;
g_hash_table_insert(win_to_task, key, task_group);
set_task_state((Task*)g_ptr_array_index(task_group, 0), task_template.current_state);
sort_taskbar_for_win(win);
if (taskbar_mode == MULTI_DESKTOP) {
Panel *panel = new_task2->area.panel;
panel->area.resize_needed = 1;
Panel *panel = (Panel*)task_template.area.panel;
panel->area.resize_needed = TRUE;
}
if (window_is_urgent(win)) {
add_urgent(new_task2);
add_urgent((Task*)g_ptr_array_index(task_group, 0));
}
return new_task2;
return (Task*)g_ptr_array_index(task_group, 0);
}
void remove_task(Task *task)
@@ -162,8 +159,7 @@ void remove_task(Task *task)
// 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) {
for (int k = 0; k < TASK_STATE_COUNT; ++k) {
if (task->icon[k]) {
imlib_context_set_image(task->icon[k]);
imlib_free_image();
@@ -183,13 +179,11 @@ void remove_task(Task *task)
XFreePixmap(server.dsp, task->state_pix[k]);
}
int i;
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;
GPtrArray *task_group = g_hash_table_lookup(win_to_task, &win);
for (int i = 0; i < task_group->len; ++i) {
Task *task2 = g_ptr_array_index(task_group, i);
if (task2 == active_task)
active_task = 0;
if (task2 == task_drag)
task_drag = 0;
if (g_slist_find(urgent_list, task2))
@@ -197,18 +191,17 @@ void remove_task(Task *task)
remove_area((Area *)task2);
free(task2);
}
g_hash_table_remove(win_to_task_table, &win);
g_hash_table_remove(win_to_task, &win);
}
gboolean get_title(Task *task)
{
Panel *panel = task->area.panel;
char *title, *name;
if (!panel->g_task.text && !panel->g_task.tooltip_enabled && taskbar_sort_method != TASKBAR_SORT_TITLE)
return 0;
return FALSE;
name = server_get_property(task->win, server.atom._NET_WM_VISIBLE_NAME, server.atom.UTF8_STRING, 0);
char *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(task->win, server.atom._NET_WM_NAME, server.atom.UTF8_STRING, 0);
if (!name || !strlen(name)) {
@@ -216,6 +209,7 @@ gboolean get_title(Task *task)
}
}
char *title;
if (name && strlen(name)) {
title = strdup(name);
} else {
@@ -228,22 +222,22 @@ gboolean get_title(Task *task)
// check unecessary title change
if (strcmp(task->title, title) == 0) {
free(title);
return 0;
} else
return FALSE;
} else {
free(task->title);
}
}
task->title = title;
GPtrArray *task_group = task_get_tasks(task->win);
if (task_group) {
int i;
for (i = 0; i < task_group->len; ++i) {
for (int 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;
return TRUE;
}
void get_icon(Task *task)
@@ -251,7 +245,7 @@ void get_icon(Task *task)
Panel *panel = task->area.panel;
if (!panel->g_task.icon)
return;
int i;
Imlib_Image img = NULL;
XWMHints *hints = 0;
gulong *data = 0;
@@ -264,6 +258,7 @@ void get_icon(Task *task)
}
}
int i;
data = server_get_property(task->win, server.atom._NET_WM_ICON, XA_CARDINAL, &i);
if (data) {
// get ARGB icon
@@ -306,9 +301,8 @@ void get_icon(Task *task)
// transform icons
imlib_context_set_image(img);
imlib_image_set_has_alpha(1);
int w, h;
w = imlib_image_get_width();
h = imlib_image_get_height();
int w = imlib_image_get_width();
int 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_free_image();
@@ -380,8 +374,9 @@ void draw_task_icon(Task *task, int text_width)
pos_x = (task->area.width - text_width - panel->g_task.icon_size1) / 2;
else
pos_x = (task->area.width - panel->g_task.icon_size1) / 2;
} else
} else {
pos_x = panel->g_task.area.paddingxlr + task->area.bg->border.width;
}
// Render
@@ -404,53 +399,46 @@ void draw_task_icon(Task *task, int text_width)
void draw_task(void *obj, cairo_t *c)
{
Task *task = obj;
Task *task = (Task *)obj;
Panel *panel = (Panel *)task->area.panel;
if (!panel_config.mouse_effects)
task->state_pix[task->current_state] = task->area.pix;
PangoLayout *layout;
Color *config_text;
int width = 0, height;
Panel *panel = (Panel *)task->area.panel;
// printf("draw_task %d %d\n", task->area.posx, task->area.posy);
int text_width = 0;
if (panel->g_task.text) {
/* Layout */
layout = pango_cairo_create_layout(c);
PangoLayout *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 *)task->area.parent)->text_width * PANGO_SCALE);
pango_layout_set_height(layout, panel->g_task.text_height * PANGO_SCALE);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
/* Center text */
if (panel->g_task.centered)
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
else
pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
pango_layout_get_pixel_size(layout, &width, &height);
config_text = &panel->g_task.font[task->current_state];
double text_posy = (panel->g_task.area.height - height) / 2.0;
int text_height;
pango_layout_get_pixel_size(layout, &text_width, &text_height);
double text_posy = (panel->g_task.area.height - text_height) / 2.0;
Color *config_text = &panel->g_task.font[task->current_state];
draw_text(layout, c, panel->g_task.text_posx, text_posy, config_text, panel->font_shadow);
g_object_unref(layout);
}
if (panel->g_task.icon) {
draw_task_icon(task, width);
draw_task_icon(task, text_width);
}
}
void on_change_task(void *obj)
{
Task *task = obj;
Task *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};
@@ -467,21 +455,18 @@ void on_change_task(void *obj)
set_task_redraw(task);
}
// Given a pointer to the active task (active_task) and a pointer
// to the task that is currently under the mouse (current_task),
// returns a pointer to the active task.
Task *find_active_task(Task *current_task, Task *active_task)
Task *find_active_task(Task *current_task)
{
if (active_task == NULL)
return current_task;
Taskbar *taskbar = current_task->area.parent;
Taskbar *taskbar = (Taskbar *)current_task->area.parent;
GList *l0 = taskbar->area.children;
if (taskbarname_enabled)
l0 = l0->next;
for (; l0; l0 = l0->next) {
Task *task = l0->data;
Task *task = (Task *)l0->data;
if (task->win == active_task->win)
return task;
}
@@ -492,7 +477,7 @@ Task *find_active_task(Task *current_task, Task *active_task)
Task *next_task(Task *task)
{
if (!task)
return 0;
return NULL;
Taskbar *taskbar = task->area.parent;
@@ -508,7 +493,7 @@ Task *next_task(Task *task)
}
}
return 0;
return NULL;
}
Task *prev_task(Task *task)
@@ -535,14 +520,14 @@ Task *prev_task(Task *task)
task2 = task1;
}
return 0;
return NULL;
}
void active_task()
void reset_active_task()
{
if (task_active) {
set_task_state(task_active, window_is_iconified(task_active->win) ? TASK_ICONIFIED : TASK_NORMAL);
task_active = 0;
if (active_task) {
set_task_state(active_task, window_is_iconified(active_task->win) ? TASK_ICONIFIED : TASK_NORMAL);
active_task = NULL;
}
Window w1 = get_active_window();
@@ -554,7 +539,7 @@ void active_task()
while (XGetTransientForHint(server.dsp, w1, &w2))
w1 = w2;
}
set_task_state((task_active = task_get_task(w1)), TASK_ACTIVE);
set_task_state((active_task = task_get_task(w1)), TASK_ACTIVE);
}
}
@@ -566,8 +551,7 @@ void set_task_state(Task *task, TaskState state)
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) {
for (int 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];
@@ -580,29 +564,29 @@ void set_task_state(Task *task, TaskState state)
}
if (state == TASK_ACTIVE && g_slist_find(urgent_list, task1))
del_urgent(task1);
int hide = 0;
gboolean hide = FALSE;
Taskbar *taskbar = (Taskbar *)task1->area.parent;
if (task->desktop == ALLDESKTOP && server.desktop != taskbar->desktop) {
// Hide ALLDESKTOP task on non-current desktop
hide = 1;
if (task->desktop == ALL_DESKTOPS && server.desktop != taskbar->desktop) {
// Hide ALL_DESKTOPS task on non-current desktop
hide = TRUE;
}
if (hide_inactive_tasks) {
// Show only the active task
if (state != TASK_ACTIVE) {
hide = 1;
hide = TRUE;
}
}
if (get_window_monitor(task->win) != ((Panel *)task->area.panel)->monitor &&
(hide_task_diff_monitor || num_panels > 1)) {
hide = 1;
hide = TRUE;
}
if (1 - hide != task1->area.on_screen) {
task1->area.on_screen = TRUE - hide;
if ((!hide) != task1->area.on_screen) {
task1->area.on_screen = !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;
task->area.resize_needed = TRUE;
p->taskbar->area.resize_needed = TRUE;
p->area.resize_needed = TRUE;
}
}
panel_refresh = TRUE;
@@ -612,8 +596,7 @@ void set_task_state(Task *task, TaskState state)
void set_task_redraw(Task *task)
{
int k;
for (k = 0; k < TASK_STATE_COUNT; ++k) {
for (int k = 0; k < TASK_STATE_COUNT; ++k) {
if (task->state_pix[k])
XFreePixmap(server.dsp, task->state_pix[k]);
task->state_pix[k] = 0;
@@ -644,7 +627,7 @@ void add_urgent(Task *task)
return;
// some programs set urgency hint although they are active
if (task_active && task_active->win == task->win)
if (active_task && active_task->win == task->win)
return;
task = task_get_task(task->win); // always add the first task for a task group (omnipresent windows)

View File

@@ -24,8 +24,6 @@ typedef enum TaskState {
extern timeout *urgent_timeout;
extern GSList *urgent_list;
// --------------------------------------------------
// global task parameter
typedef struct GlobalTask {
Area area;
@@ -52,7 +50,10 @@ typedef struct GlobalTask {
gboolean tooltip_enabled;
} GlobalTask;
typedef struct {
// Stores information about a task.
// Warning: any dynamically allocated members are shared between the Task instances created for the same window
// (for example, if the task appears on all desktops, there will be a different instance on each desktop's taskbar).
typedef struct Task {
// always start with area
Area area;
@@ -83,11 +84,15 @@ void on_change_task(void *obj);
void get_icon(Task *task);
gboolean get_title(Task *task);
void active_task();
void reset_active_task();
void set_task_state(Task *task, TaskState state);
void set_task_redraw(Task *task);
Task *find_active_task(Task *current_task, Task *active_task);
// Given a pointer to the task that is currently under the mouse (current_task),
// returns a pointer to the Task for the active window on the same taskbar.
// If not found, returns the current task.
Task *find_active_task(Task *current_task);
Task *next_task(Task *task);
Task *prev_task(Task *task);

View File

@@ -33,13 +33,13 @@
#include "panel.h"
#include "strnatcmp.h"
/* win_to_task_table holds for every Window an array of tasks. Usually the array contains only one
/* win_to_task 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.num_desktops)
*/
GHashTable *win_to_task_table;
GHashTable *win_to_task;
Task *task_active;
Task *active_task;
Task *task_drag;
gboolean taskbar_enabled;
gboolean taskbar_distribute_size;
@@ -50,12 +50,14 @@ Alignment taskbar_alignment;
guint win_hash(gconstpointer key)
{
return (guint) * ((const Window *)key);
return *((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);
@@ -63,7 +65,7 @@ void free_ptr_array(gpointer data)
void default_taskbar()
{
win_to_task_table = NULL;
win_to_task = NULL;
urgent_timeout = NULL;
urgent_list = NULL;
taskbar_enabled = 0;
@@ -77,29 +79,25 @@ void default_taskbar()
void cleanup_taskbar()
{
Panel *panel;
Taskbar *taskbar;
int i, j, k;
cleanup_taskbarname();
if (win_to_task_table) {
while (g_hash_table_size(win_to_task_table)) {
if (win_to_task) {
while (g_hash_table_size(win_to_task)) {
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init(&iter, win_to_task_table);
g_hash_table_iter_init(&iter, win_to_task);
if (g_hash_table_iter_next(&iter, &key, &value)) {
taskbar_remove_task(key, 0, 0);
}
}
g_hash_table_destroy(win_to_task_table);
win_to_task_table = NULL;
g_hash_table_destroy(win_to_task);
win_to_task = NULL;
}
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) {
for (int i = 0; i < num_panels; i++) {
Panel *panel = &panels[i];
for (int j = 0; j < panel->num_desktops; j++) {
Taskbar *taskbar = &panel->taskbar[j];
for (int k = 0; k < TASKBAR_STATE_COUNT; ++k) {
if (taskbar->state_pix[k])
XFreePixmap(server.dsp, taskbar->state_pix[k]);
taskbar->state_pix[k] = 0;
@@ -122,17 +120,16 @@ void cleanup_taskbar()
void init_taskbar()
{
if (!win_to_task_table)
win_to_task_table = g_hash_table_new_full(win_hash, win_compare, free, free_ptr_array);
if (!win_to_task)
win_to_task = g_hash_table_new_full(win_hash, win_compare, free, free_ptr_array);
task_active = 0;
active_task = 0;
task_drag = 0;
}
void init_taskbar_panel(void *p)
{
Panel *panel = (Panel *)p;
int j;
if (!panel->g_taskbar.background[TASKBAR_NORMAL]) {
panel->g_taskbar.background[TASKBAR_NORMAL] = &g_array_index(backgrounds, Background, 0);
@@ -235,7 +232,7 @@ void init_taskbar_panel(void *p)
panel->g_task.area.height = panel->g_task.maximum_height;
}
for (j = 0; j < TASK_STATE_COUNT; ++j) {
for (int 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) {
@@ -275,7 +272,7 @@ void init_taskbar_panel(void *p)
Taskbar *taskbar;
panel->num_desktops = server.num_desktops;
panel->taskbar = calloc(server.num_desktops, sizeof(Taskbar));
for (j = 0; j < panel->num_desktops; j++) {
for (int j = 0; j < panel->num_desktops; j++) {
taskbar = &panel->taskbar[j];
memcpy(&taskbar->area, &panel->g_taskbar.area, sizeof(Area));
taskbar->desktop = j;
@@ -297,32 +294,30 @@ Task *task_get_task(Window win)
GPtrArray *task_group = task_get_tasks(win);
if (task_group)
return g_ptr_array_index(task_group, 0);
else
return 0;
return NULL;
}
GPtrArray *task_get_tasks(Window win)
{
if (win_to_task_table && taskbar_enabled)
return g_hash_table_lookup(win_to_task_table, &win);
else
return 0;
if (win_to_task && taskbar_enabled)
return g_hash_table_lookup(win_to_task, &win);
return NULL;
}
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);
int num_results;
Window *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 *win_list = g_hash_table_get_keys(win_to_task);
GList *it;
for (it = win_list; it; it = it->next) {
int i;
for (i = 0; i < num_results; i++)
if (*((Window *)it->data) == win[i])
break;
@@ -332,7 +327,7 @@ void task_refresh_tasklist()
g_list_free(win_list);
// Add any new
for (i = 0; i < num_results; i++)
for (int i = 0; i < num_results; i++)
if (!task_get_task(win[i]))
add_task(win[i]);
@@ -351,13 +346,12 @@ gboolean resize_taskbar(void *obj)
{
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);
if (panel_horizontal) {
relayout_with_constraint(&taskbar->area, panel->g_task.maximum_width);
text_width = panel->g_task.maximum_width;
int text_width = panel->g_task.maximum_width;
GList *l = taskbar->area.children;
if (taskbarname_enabled)
l = l->next;
@@ -368,23 +362,22 @@ gboolean resize_taskbar(void *obj)
}
}
taskbar->text_width =
text_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingxlr;
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;
}
return 0;
return FALSE;
}
void on_change_taskbar(void *obj)
{
Taskbar *taskbar = (Taskbar *)obj;
int k;
// reset Pixmap when position/size changed
for (k = 0; k < TASKBAR_STATE_COUNT; ++k) {
for (int k = 0; k < TASKBAR_STATE_COUNT; ++k) {
if (taskbar->state_pix[k])
XFreePixmap(server.dsp, taskbar->state_pix[k]);
taskbar->state_pix[k] = 0;
@@ -426,7 +419,7 @@ void set_taskbar_state(Taskbar *taskbar, TaskbarState state)
if (taskbarname_enabled)
l = l->next;
for (; l; l = l->next)
set_task_redraw(l->data);
set_task_redraw((Task *)l->data);
}
}
panel_refresh = TRUE;
@@ -435,10 +428,9 @@ void set_taskbar_state(Taskbar *taskbar, TaskbarState state)
void visible_taskbar(void *p)
{
Panel *panel = (Panel *)p;
int j;
Taskbar *taskbar;
for (j = 0; j < panel->num_desktops; j++) {
for (int j = 0; j < panel->num_desktops; j++) {
taskbar = &panel->taskbar[j];
if (taskbar_mode != MULTI_DESKTOP && taskbar->desktop != server.desktop) {
// SINGLE_DESKTOP and not current desktop
@@ -493,11 +485,10 @@ gint compare_task_centers(Task *a, Task *b, Taskbar *taskbar)
return 1;
// Compare centers
int a_horiz_c, a_vert_c, b_horiz_c, b_vert_c;
a_horiz_c = a->win_x + a->win_w / 2;
b_horiz_c = b->win_x + b->win_w / 2;
a_vert_c = a->win_y + a->win_h / 2;
b_vert_c = b->win_y + b->win_h / 2;
int a_horiz_c = a->win_x + a->win_w / 2;
int b_horiz_c = b->win_x + b->win_w / 2;
int a_vert_c = a->win_y + a->win_h / 2;
int b_vert_c = b->win_y + b->win_h / 2;
if (panel_horizontal) {
if (a_horiz_c != b_horiz_c) {
return a_horiz_c - b_horiz_c;
@@ -534,19 +525,18 @@ gint compare_tasks(Task *a, Task *b, Taskbar *taskbar)
return 0;
}
int taskbar_needs_sort(Taskbar *taskbar)
gboolean taskbar_needs_sort(Taskbar *taskbar)
{
if (taskbar_sort_method == TASKBAR_NOSORT)
return 0;
return FALSE;
GList *i, *j;
for (i = taskbar->area.children, j = i ? i->next : NULL; i && j; i = i->next, j = j->next) {
for (GList *i = taskbar->area.children, *j = i ? i->next : NULL; i && j; i = i->next, j = j->next) {
if (compare_tasks(i->data, j->data, taskbar) > 0) {
return 1;
return TRUE;
}
}
return 0;
return FALSE;
}
void sort_tasks(Taskbar *taskbar)
@@ -557,9 +547,9 @@ void sort_tasks(Taskbar *taskbar)
return;
taskbar->area.children = g_list_sort_with_data(taskbar->area.children, (GCompareDataFunc)compare_tasks, taskbar);
taskbar->area.resize_needed = 1;
taskbar->area.resize_needed = TRUE;
panel_refresh = TRUE;
((Panel *)taskbar->area.panel)->area.resize_needed = 1;
((Panel *)taskbar->area.panel)->area.resize_needed = TRUE;
}
void sort_taskbar_for_win(Window win)
@@ -569,12 +559,11 @@ void sort_taskbar_for_win(Window win)
GPtrArray *task_group = task_get_tasks(win);
if (task_group) {
int i;
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) {
for (int i = 0; i < task_group->len; ++i) {
Task *task = g_ptr_array_index(task_group, i);
task->win_x = task0->win_x;
task->win_y = task0->win_y;

View File

@@ -23,8 +23,8 @@ typedef enum TaskbarSortMethod {
TASKBAR_SORT_TITLE,
} TaskbarSortMethod;
extern GHashTable *win_to_task_table;
extern Task *task_active;
extern GHashTable *win_to_task;
extern Task *active_task;
extern Task *task_drag;
extern gboolean taskbar_enabled;
extern gboolean taskbar_distribute_size;