Support for NETWM viewports (compiz)
This commit is contained in:
parent
4a6937826c
commit
eb044da8bc
11 changed files with 537 additions and 349 deletions
|
@ -258,7 +258,7 @@ void init_panel()
|
|||
}
|
||||
|
||||
task_refresh_tasklist();
|
||||
active_task();
|
||||
reset_active_task();
|
||||
}
|
||||
|
||||
void init_panel_size_and_position(Panel *panel)
|
||||
|
@ -576,7 +576,7 @@ void set_panel_properties(Panel *p)
|
|||
(unsigned char *)&val,
|
||||
1);
|
||||
|
||||
val = ALLDESKTOP;
|
||||
val = ALL_DESKTOPS;
|
||||
XChangeProperty(server.dsp,
|
||||
p->main_win,
|
||||
server.atom._NET_WM_DESKTOP,
|
||||
|
|
127
src/server.c
127
src/server.c
|
@ -29,7 +29,7 @@
|
|||
#include "config.h"
|
||||
#include "window.h"
|
||||
|
||||
Server_global server;
|
||||
Server server;
|
||||
|
||||
void server_catch_error(Display *d, XErrorEvent *ev)
|
||||
{
|
||||
|
@ -44,6 +44,7 @@ void server_init_atoms()
|
|||
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_WORKAREA = XInternAtom(server.dsp, "_NET_WORKAREA", 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);
|
||||
|
@ -388,9 +389,127 @@ void print_monitors()
|
|||
}
|
||||
}
|
||||
|
||||
int server_get_number_of_desktops()
|
||||
void server_get_number_of_desktops()
|
||||
{
|
||||
return get_property32(server.root_win, server.atom._NET_NUMBER_OF_DESKTOPS, XA_CARDINAL);
|
||||
if (server.viewports) {
|
||||
free(server.viewports);
|
||||
server.viewports = NULL;
|
||||
}
|
||||
|
||||
server.num_desktops = get_property32(server.root_win, server.atom._NET_NUMBER_OF_DESKTOPS, XA_CARDINAL);
|
||||
if (server.num_desktops > 1)
|
||||
return;
|
||||
|
||||
int num_results;
|
||||
long *work_area_size = server_get_property(server.root_win, server.atom._NET_WORKAREA, XA_CARDINAL, &num_results);
|
||||
if (!work_area_size)
|
||||
return;
|
||||
int work_area_width = work_area_size[0] + work_area_size[2];
|
||||
int work_area_height = work_area_size[1] + work_area_size[3];
|
||||
XFree(work_area_size);
|
||||
|
||||
long *x_screen_size = server_get_property(server.root_win, server.atom._NET_DESKTOP_GEOMETRY, XA_CARDINAL, &num_results);
|
||||
if (!x_screen_size)
|
||||
return;
|
||||
int x_screen_width = x_screen_size[0];
|
||||
int x_screen_height = x_screen_size[1];
|
||||
XFree(x_screen_size);
|
||||
|
||||
int num_viewports = MAX(x_screen_width / work_area_width, 1) * MAX(x_screen_height / work_area_height, 1);
|
||||
if (num_viewports <= 1)
|
||||
return;
|
||||
|
||||
server.viewports = calloc(num_viewports, sizeof(Viewport));
|
||||
int k = 0;
|
||||
for (int i = 0; i < MAX(x_screen_height / work_area_height, 1); i++) {
|
||||
for (int j = 0; j < MAX(x_screen_width / work_area_width, 1); j++) {
|
||||
server.viewports[k].x = j * work_area_width;
|
||||
server.viewports[k].y = i * work_area_height;
|
||||
server.viewports[k].width = work_area_width;
|
||||
server.viewports[k].height = work_area_height;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
server.num_desktops = num_viewports;
|
||||
}
|
||||
|
||||
GSList *get_desktop_names()
|
||||
{
|
||||
if (server.viewports) {
|
||||
GSList *list = NULL;
|
||||
for (int j = 0; j < server.num_desktops; j++) {
|
||||
list = g_slist_append(list, g_strdup_printf("%d", j + 1));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
int count;
|
||||
GSList *list = NULL;
|
||||
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 (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));
|
||||
}
|
||||
}
|
||||
XFree(data_ptr);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
int get_current_desktop()
|
||||
{
|
||||
if (!server.viewports)
|
||||
return get_property32(server.root_win, server.atom._NET_CURRENT_DESKTOP, XA_CARDINAL);
|
||||
|
||||
int num_results;
|
||||
long *work_area_size = server_get_property(server.root_win, server.atom._NET_WORKAREA, XA_CARDINAL, &num_results);
|
||||
if (!work_area_size)
|
||||
return 0;
|
||||
int work_area_width = work_area_size[0] + work_area_size[2];
|
||||
int work_area_height = work_area_size[1] + work_area_size[3];
|
||||
XFree(work_area_size);
|
||||
|
||||
if (work_area_width <= 0 || work_area_height <= 0)
|
||||
return 0;
|
||||
|
||||
long *viewport = server_get_property(server.root_win, server.atom._NET_DESKTOP_VIEWPORT, XA_CARDINAL, &num_results);
|
||||
if (!viewport)
|
||||
return 0;
|
||||
int viewport_x = viewport[0];
|
||||
int viewport_y = viewport[1];
|
||||
XFree(viewport);
|
||||
|
||||
long *x_screen_size = server_get_property(server.root_win, server.atom._NET_DESKTOP_GEOMETRY, XA_CARDINAL, &num_results);
|
||||
if (!x_screen_size)
|
||||
return 0;
|
||||
int x_screen_width = x_screen_size[0];
|
||||
XFree(x_screen_size);
|
||||
|
||||
int ncols = x_screen_width / work_area_width;
|
||||
|
||||
// fprintf(stderr, "\n");
|
||||
// fprintf(stderr, "Work area size: %d x %d\n", work_area_width, work_area_height);
|
||||
// fprintf(stderr, "Viewport pos: %d x %d\n", viewport_x, viewport_y);
|
||||
// fprintf(stderr, "Viewport i: %d\n", (viewport_y / work_area_height) * ncols + viewport_x / work_area_width);
|
||||
|
||||
return (viewport_y / work_area_height) * ncols + viewport_x / work_area_width;
|
||||
}
|
||||
|
||||
void change_desktop(int desktop)
|
||||
{
|
||||
if (!server.viewports) {
|
||||
send_event32(server.root_win, server.atom._NET_CURRENT_DESKTOP, desktop, 0, 0);
|
||||
} else {
|
||||
send_event32(server.root_win,
|
||||
server.atom._NET_DESKTOP_VIEWPORT,
|
||||
server.viewports[desktop].x,
|
||||
server.viewports[desktop].y,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
void get_desktops()
|
||||
|
@ -398,7 +517,7 @@ void get_desktops()
|
|||
// detect number of desktops
|
||||
// wait 15s to leave some time for window manager startup
|
||||
for (int i = 0; i < 15; i++) {
|
||||
server.num_desktops = server_get_number_of_desktops();
|
||||
server_get_number_of_desktops();
|
||||
if (server.num_desktops > 0)
|
||||
break;
|
||||
sleep(1);
|
||||
|
|
23
src/server.h
23
src/server.h
|
@ -26,6 +26,7 @@ typedef struct Global_atom {
|
|||
Atom _NET_DESKTOP_NAMES;
|
||||
Atom _NET_DESKTOP_GEOMETRY;
|
||||
Atom _NET_DESKTOP_VIEWPORT;
|
||||
Atom _NET_WORKAREA;
|
||||
Atom _NET_ACTIVE_WINDOW;
|
||||
Atom _NET_WM_WINDOW_TYPE;
|
||||
Atom _NET_WM_STATE_SKIP_PAGER;
|
||||
|
@ -98,7 +99,14 @@ typedef struct Monitor {
|
|||
gchar **names;
|
||||
} Monitor;
|
||||
|
||||
typedef struct {
|
||||
typedef struct Viewport {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
} Viewport;
|
||||
|
||||
typedef struct Server {
|
||||
Display *dsp;
|
||||
Window root_win;
|
||||
Window composite_manager;
|
||||
|
@ -111,6 +119,9 @@ typedef struct {
|
|||
int num_desktops;
|
||||
// number of monitor (without monitor included into another one)
|
||||
int num_monitors;
|
||||
// Non-null only if WM uses viewports (compiz) and number of viewports > 1.
|
||||
// In that case there are num_desktops viewports.
|
||||
Viewport *viewports;
|
||||
Monitor *monitor;
|
||||
int got_root_win;
|
||||
Visual *visual;
|
||||
|
@ -125,9 +136,9 @@ typedef struct {
|
|||
SnDisplay *sn_dsp;
|
||||
GTree *pids;
|
||||
#endif // HAVE_SN
|
||||
} Server_global;
|
||||
} Server;
|
||||
|
||||
extern Server_global server;
|
||||
extern Server server;
|
||||
|
||||
// freed memory
|
||||
void cleanup_server();
|
||||
|
@ -147,6 +158,10 @@ void get_root_pixmap();
|
|||
void get_monitors();
|
||||
void print_monitors();
|
||||
void get_desktops();
|
||||
int server_get_number_of_desktops();
|
||||
void server_get_number_of_desktops();
|
||||
GSList *get_desktop_names();
|
||||
int get_current_desktop();
|
||||
void change_desktop(int desktop);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
241
src/tint.c
241
src/tint.c
|
@ -113,7 +113,7 @@ void init(int argc, char *argv[])
|
|||
default_config();
|
||||
default_timeout();
|
||||
default_systray();
|
||||
memset(&server, 0, sizeof(Server_global));
|
||||
memset(&server, 0, sizeof(server));
|
||||
#ifdef ENABLE_BATTERY
|
||||
default_battery();
|
||||
#endif
|
||||
|
@ -390,7 +390,7 @@ void window_action(Task *task, int action)
|
|||
XIconifyWindow(server.dsp, task->win, server.screen);
|
||||
break;
|
||||
case TOGGLE_ICONIFY:
|
||||
if (task_active && task->win == task_active->win)
|
||||
if (active_task && task->win == active_task->win)
|
||||
XIconifyWindow(server.dsp, task->win, server.screen);
|
||||
else
|
||||
activate_window(task->win);
|
||||
|
@ -425,12 +425,12 @@ void window_action(Task *task, int action)
|
|||
break;
|
||||
case NEXT_TASK: {
|
||||
Task *task1;
|
||||
task1 = next_task(find_active_task(task, task_active));
|
||||
task1 = next_task(find_active_task(task));
|
||||
activate_window(task1->win);
|
||||
} break;
|
||||
case PREV_TASK: {
|
||||
Task *task1;
|
||||
task1 = prev_task(find_active_task(task, task_active));
|
||||
task1 = prev_task(find_active_task(task));
|
||||
activate_window(task1->win);
|
||||
}
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ void event_button_motion_notify(XEvent *e)
|
|||
}
|
||||
}
|
||||
} else { // The event is on another taskbar than the task being dragged
|
||||
if (task_drag->desktop == ALLDESKTOP || taskbar_mode != MULTI_DESKTOP)
|
||||
if (task_drag->desktop == ALL_DESKTOPS || taskbar_mode != MULTI_DESKTOP)
|
||||
return;
|
||||
|
||||
Taskbar *drag_taskbar = (Taskbar *)task_drag->area.parent;
|
||||
|
@ -658,18 +658,74 @@ void event_button_release(XEvent *e)
|
|||
|
||||
// switch desktop
|
||||
if (taskbar_mode == MULTI_DESKTOP) {
|
||||
if (taskbar->desktop != server.desktop && action != CLOSE && action != DESKTOP_LEFT && action != DESKTOP_RIGHT)
|
||||
gboolean diff_desktop = FALSE;
|
||||
if (taskbar->desktop != server.desktop && action != CLOSE && action != DESKTOP_LEFT && action != DESKTOP_RIGHT) {
|
||||
diff_desktop = TRUE;
|
||||
change_desktop(taskbar->desktop);
|
||||
}
|
||||
Task *task = click_task(panel, e->xbutton.x, e->xbutton.y);
|
||||
if (task) {
|
||||
if (diff_desktop) {
|
||||
if (action == TOGGLE_ICONIFY) {
|
||||
if (!window_is_active(task->win))
|
||||
activate_window(task->win);
|
||||
} else {
|
||||
window_action(task, action);
|
||||
}
|
||||
} else {
|
||||
window_action(task, action);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
window_action(click_task(panel, e->xbutton.x, e->xbutton.y), action);
|
||||
}
|
||||
|
||||
// action on task
|
||||
window_action(click_task(panel, e->xbutton.x, e->xbutton.y), action);
|
||||
|
||||
// to keep window below
|
||||
if (panel_layer == BOTTOM_LAYER)
|
||||
XLowerWindow(server.dsp, panel->main_win);
|
||||
}
|
||||
|
||||
void update_desktop_names()
|
||||
{
|
||||
if (!taskbarname_enabled)
|
||||
return;
|
||||
GSList *list = get_desktop_names();
|
||||
for (int i = 0; i < num_panels; i++) {
|
||||
int j;
|
||||
GSList *l;
|
||||
for (j = 0, l = list; j < panels[i].num_desktops; j++) {
|
||||
gchar *name;
|
||||
if (l) {
|
||||
name = g_strdup(l->data);
|
||||
l = l->next;
|
||||
} else {
|
||||
name = g_strdup_printf("%d", j + 1);
|
||||
}
|
||||
Taskbar *taskbar = &panels[i].taskbar[j];
|
||||
if (strcmp(name, taskbar->bar_name.name) != 0) {
|
||||
g_free(taskbar->bar_name.name);
|
||||
taskbar->bar_name.name = name;
|
||||
taskbar->bar_name.area.resize_needed = 1;
|
||||
} else {
|
||||
g_free(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (GSList *l = list; l; l = l->next)
|
||||
g_free(l->data);
|
||||
g_slist_free(list);
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
|
||||
void update_task_desktop(Task *task)
|
||||
{
|
||||
Window win = task->win;
|
||||
remove_task(task);
|
||||
task = add_task(win);
|
||||
reset_active_task();
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
|
||||
void event_property_notify(XEvent *e)
|
||||
{
|
||||
int i;
|
||||
|
@ -686,93 +742,93 @@ void event_property_notify(XEvent *e)
|
|||
|
||||
// Change name of desktops
|
||||
else if (at == server.atom._NET_DESKTOP_NAMES) {
|
||||
if (!taskbarname_enabled)
|
||||
return;
|
||||
GSList *l, *list = get_desktop_names();
|
||||
int j;
|
||||
gchar *name;
|
||||
Taskbar *taskbar;
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
for (j = 0, l = list; j < panels[i].num_desktops; j++) {
|
||||
if (l) {
|
||||
name = g_strdup(l->data);
|
||||
l = l->next;
|
||||
} else
|
||||
name = g_strdup_printf("%d", j + 1);
|
||||
taskbar = &panels[i].taskbar[j];
|
||||
if (strcmp(name, taskbar->bar_name.name) != 0) {
|
||||
g_free(taskbar->bar_name.name);
|
||||
taskbar->bar_name.name = name;
|
||||
taskbar->bar_name.area.resize_needed = 1;
|
||||
} else
|
||||
g_free(name);
|
||||
}
|
||||
}
|
||||
for (l = list; l; l = l->next)
|
||||
g_free(l->data);
|
||||
g_slist_free(list);
|
||||
panel_refresh = TRUE;
|
||||
update_desktop_names();
|
||||
}
|
||||
// Change number of desktops
|
||||
else if (at == server.atom._NET_NUMBER_OF_DESKTOPS) {
|
||||
if (!taskbar_enabled)
|
||||
return;
|
||||
server.num_desktops = server_get_number_of_desktops();
|
||||
if (server.num_desktops <= server.desktop) {
|
||||
server.desktop = server.num_desktops - 1;
|
||||
}
|
||||
cleanup_taskbar();
|
||||
init_taskbar();
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
init_taskbar_panel(&panels[i]);
|
||||
set_panel_items_order(&panels[i]);
|
||||
visible_taskbar(&panels[i]);
|
||||
panels[i].area.resize_needed = 1;
|
||||
}
|
||||
task_refresh_tasklist();
|
||||
active_task();
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
// Change desktop
|
||||
else if (at == server.atom._NET_CURRENT_DESKTOP) {
|
||||
// Change desktops
|
||||
else if (at == server.atom._NET_NUMBER_OF_DESKTOPS ||
|
||||
at == server.atom._NET_DESKTOP_GEOMETRY ||
|
||||
at == server.atom._NET_DESKTOP_VIEWPORT ||
|
||||
at == server.atom._NET_WORKAREA ||
|
||||
at == server.atom._NET_CURRENT_DESKTOP) {
|
||||
if (!taskbar_enabled)
|
||||
return;
|
||||
int old_num_desktops = server.num_desktops;
|
||||
int old_desktop = server.desktop;
|
||||
server_get_number_of_desktops();
|
||||
server.desktop = get_current_desktop();
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
Panel *panel = &panels[i];
|
||||
set_taskbar_state(&panel->taskbar[old_desktop], TASKBAR_NORMAL);
|
||||
set_taskbar_state(&panel->taskbar[server.desktop], TASKBAR_ACTIVE);
|
||||
// check ALLDESKTOP task => resize taskbar
|
||||
Taskbar *taskbar;
|
||||
Task *task;
|
||||
if (server.num_desktops > old_desktop) {
|
||||
taskbar = &panel->taskbar[old_desktop];
|
||||
if (old_num_desktops != server.num_desktops) {
|
||||
if (server.num_desktops <= server.desktop) {
|
||||
server.desktop = server.num_desktops - 1;
|
||||
}
|
||||
cleanup_taskbar();
|
||||
init_taskbar();
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
init_taskbar_panel(&panels[i]);
|
||||
set_panel_items_order(&panels[i]);
|
||||
visible_taskbar(&panels[i]);
|
||||
panels[i].area.resize_needed = 1;
|
||||
}
|
||||
task_refresh_tasklist();
|
||||
reset_active_task();
|
||||
panel_refresh = TRUE;
|
||||
} else if (old_desktop != server.desktop) {
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
Panel *panel = &panels[i];
|
||||
set_taskbar_state(&panel->taskbar[old_desktop], TASKBAR_NORMAL);
|
||||
set_taskbar_state(&panel->taskbar[server.desktop], TASKBAR_ACTIVE);
|
||||
// check ALL_DESKTOPS task => resize taskbar
|
||||
Taskbar *taskbar;
|
||||
if (server.num_desktops > old_desktop) {
|
||||
taskbar = &panel->taskbar[old_desktop];
|
||||
GList *l = taskbar->area.children;
|
||||
if (taskbarname_enabled)
|
||||
l = l->next;
|
||||
for (; l; l = l->next) {
|
||||
Task *task = l->data;
|
||||
if (task->desktop == ALL_DESKTOPS) {
|
||||
task->area.on_screen = FALSE;
|
||||
taskbar->area.resize_needed = 1;
|
||||
panel_refresh = TRUE;
|
||||
if (taskbar_mode == MULTI_DESKTOP)
|
||||
panel->area.resize_needed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
taskbar = &panel->taskbar[server.desktop];
|
||||
GList *l = taskbar->area.children;
|
||||
if (taskbarname_enabled)
|
||||
l = l->next;
|
||||
for (; l; l = l->next) {
|
||||
task = l->data;
|
||||
if (task->desktop == ALLDESKTOP) {
|
||||
task->area.on_screen = FALSE;
|
||||
Task *task = l->data;
|
||||
if (task->desktop == ALL_DESKTOPS) {
|
||||
task->area.on_screen = TRUE;
|
||||
taskbar->area.resize_needed = 1;
|
||||
panel_refresh = TRUE;
|
||||
if (taskbar_mode == MULTI_DESKTOP)
|
||||
panel->area.resize_needed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
taskbar = &panel->taskbar[server.desktop];
|
||||
GList *l = taskbar->area.children;
|
||||
if (taskbarname_enabled)
|
||||
l = l->next;
|
||||
for (; l; l = l->next) {
|
||||
task = l->data;
|
||||
if (task->desktop == ALLDESKTOP) {
|
||||
task->area.on_screen = TRUE;
|
||||
taskbar->area.resize_needed = 1;
|
||||
if (taskbar_mode == MULTI_DESKTOP)
|
||||
panel->area.resize_needed = 1;
|
||||
|
||||
if (server.viewports) {
|
||||
GList *need_update = NULL;
|
||||
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_hash_table_iter_init(&iter, win_to_task);
|
||||
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
||||
Window task_win = *(Window *)key;
|
||||
Task *task = task_get_task(task_win);
|
||||
if (task) {
|
||||
int desktop = get_window_desktop(task_win);
|
||||
if (desktop != task->desktop) {
|
||||
need_update = g_list_append(need_update, task);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (l = need_update; l; l = l->next) {
|
||||
Task *task = l->data;
|
||||
update_task_desktop(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -784,7 +840,7 @@ void event_property_notify(XEvent *e)
|
|||
}
|
||||
// Change active
|
||||
else if (at == server.atom._NET_ACTIVE_WINDOW) {
|
||||
active_task();
|
||||
reset_active_task();
|
||||
panel_refresh = TRUE;
|
||||
} else if (at == server.atom._XROOTPMAP_ID || at == server.atom._XROOTMAP_ID) {
|
||||
// change Wallpaper
|
||||
|
@ -838,7 +894,7 @@ void event_property_notify(XEvent *e)
|
|||
}
|
||||
} else if (at == server.atom.WM_STATE) {
|
||||
// Iconic state
|
||||
TaskState state = (task_active && task->win == task_active->win ? TASK_ACTIVE : TASK_NORMAL);
|
||||
TaskState state = (active_task && task->win == active_task->win ? TASK_ACTIVE : TASK_NORMAL);
|
||||
if (window_is_iconified(win))
|
||||
state = TASK_ICONIFIED;
|
||||
set_task_state(task, state);
|
||||
|
@ -855,10 +911,7 @@ void event_property_notify(XEvent *e)
|
|||
// printf(" Window desktop changed %d, %d\n", task->desktop, desktop);
|
||||
// bug in windowmaker : send unecessary 'desktop changed' when focus changed
|
||||
if (desktop != task->desktop) {
|
||||
remove_task(task);
|
||||
task = add_task(win);
|
||||
active_task();
|
||||
panel_refresh = TRUE;
|
||||
update_task_desktop(task);
|
||||
}
|
||||
} else if (at == server.atom.WM_HINTS) {
|
||||
XWMHints *wmhints = XGetWMHints(server.dsp, win);
|
||||
|
@ -917,13 +970,23 @@ void event_configure_notify(XEvent *e)
|
|||
task = add_task(win);
|
||||
if (win == get_active_window()) {
|
||||
set_task_state(task, TASK_ACTIVE);
|
||||
task_active = task;
|
||||
active_task = task;
|
||||
}
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (server.viewports) {
|
||||
Task *task = task_get_task(win);
|
||||
if (task) {
|
||||
int desktop = get_window_desktop(win);
|
||||
if (task->desktop != desktop) {
|
||||
update_task_desktop(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort_taskbar_for_win(win);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef enum MouseAction {
|
|||
PREV_TASK
|
||||
} MouseAction;
|
||||
|
||||
#define ALLDESKTOP 0xFFFFFFFF
|
||||
#define ALL_DESKTOPS 0xFFFFFFFF
|
||||
|
||||
// Copies a file to another path
|
||||
void copy_file(const char *path_src, const char *path_dest);
|
||||
|
|
|
@ -40,11 +40,6 @@ void activate_window(Window win)
|
|||
send_event32(win, server.atom._NET_ACTIVE_WINDOW, 2, CurrentTime, 0);
|
||||
}
|
||||
|
||||
void change_desktop(int desktop)
|
||||
{
|
||||
send_event32(server.root_win, server.atom._NET_CURRENT_DESKTOP, desktop, 0, 0);
|
||||
}
|
||||
|
||||
void change_window_desktop(Window win, int desktop)
|
||||
{
|
||||
send_event32(win, server.atom._NET_WM_DESKTOP, desktop, 2, 0);
|
||||
|
@ -113,7 +108,53 @@ gboolean window_is_hidden(Window win)
|
|||
|
||||
int get_window_desktop(Window win)
|
||||
{
|
||||
return get_property32(win, server.atom._NET_WM_DESKTOP, XA_CARDINAL);
|
||||
if (!server.viewports)
|
||||
return get_property32(win, server.atom._NET_WM_DESKTOP, XA_CARDINAL);
|
||||
|
||||
int x, y, w, h;
|
||||
get_window_coordinates(win, &x, &y, &w, &h);
|
||||
|
||||
int desktop = MIN(get_current_desktop(), server.num_desktops - 1);
|
||||
// Window coordinates are relative to the current viewport, make them absolute
|
||||
x += server.viewports[desktop].x;
|
||||
y += server.viewports[desktop].y;
|
||||
|
||||
if (x < 0 || y < 0) {
|
||||
int num_results;
|
||||
long *x_screen_size = server_get_property(server.root_win, server.atom._NET_DESKTOP_GEOMETRY, XA_CARDINAL, &num_results);
|
||||
if (!x_screen_size)
|
||||
return 0;
|
||||
int x_screen_width = x_screen_size[0];
|
||||
int x_screen_height = x_screen_size[1];
|
||||
XFree(x_screen_size);
|
||||
|
||||
// Wrap
|
||||
if (x < 0)
|
||||
x += x_screen_width;
|
||||
if (y < 0)
|
||||
y += x_screen_height;
|
||||
}
|
||||
|
||||
int best_match = -1;
|
||||
int match_right = 0;
|
||||
int match_bottom = 0;
|
||||
// There is an ambiguity when a window is right on the edge between viewports.
|
||||
// In that case, prefer the viewports which is on the right and bottom of the window's top-left corner.
|
||||
for (int i = 0; i < server.num_desktops; i++) {
|
||||
if (x >= server.viewports[i].x && x <= (server.viewports[i].x + server.viewports[i].width) &&
|
||||
y >= server.viewports[i].y && y <= (server.viewports[i].y + server.viewports[i].height)) {
|
||||
int current_right = x < (server.viewports[i].x + server.viewports[i].width);
|
||||
int current_bottom = y < (server.viewports[i].y + server.viewports[i].height);
|
||||
if (best_match < 0 || (!match_right && current_right) || (!match_bottom && current_bottom)) {
|
||||
best_match = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best_match < 0)
|
||||
best_match = 0;
|
||||
// printf("window %lx : viewport %d, (%d, %d)\n", win, best_match+1, x, y);
|
||||
return best_match;
|
||||
}
|
||||
|
||||
int get_window_monitor(Window win)
|
||||
|
@ -128,14 +169,14 @@ int get_window_monitor(Window win)
|
|||
// 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.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)) {
|
||||
best_match = i;
|
||||
}
|
||||
if (x >= server.monitor[i].x && x <= (server.monitor[i].x + server.monitor[i].width) &&
|
||||
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)) {
|
||||
best_match = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best_match < 0)
|
||||
|
@ -201,29 +242,6 @@ gboolean window_is_skip_taskbar(Window win)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
GSList *get_desktop_names()
|
||||
{
|
||||
int count;
|
||||
GSList *list = NULL;
|
||||
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 (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));
|
||||
}
|
||||
}
|
||||
XFree(data_ptr);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
int get_current_desktop()
|
||||
{
|
||||
return get_property32(server.root_win, server.atom._NET_CURRENT_DESKTOP, XA_CARDINAL);
|
||||
}
|
||||
|
||||
Window get_active_window()
|
||||
{
|
||||
return get_property32(server.root_win, server.atom._NET_ACTIVE_WINDOW, XA_WINDOW);
|
||||
|
|
|
@ -13,10 +13,6 @@
|
|||
#include <pango/pangocairo.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
GSList *get_desktop_names();
|
||||
int get_current_desktop();
|
||||
void change_desktop(int desktop);
|
||||
|
||||
Window get_active_window();
|
||||
|
||||
gboolean window_is_iconified(Window win);
|
||||
|
|
Loading…
Reference in a new issue