Virtual Desktops! Yay.

Sorry, they don't quite work right yet. I'll fix the bug tomorrow. :)


SVN revision: 12698
This commit is contained in:
xcomputerman 2005-01-03 09:34:24 +00:00 committed by xcomputerman
parent 605b862187
commit 112ca3b2d2
16 changed files with 363 additions and 144 deletions

View File

@ -18,6 +18,7 @@ e_init.h \
e_ipc.h \
e_error.h \
e_container.h \
e_zone.h \
e_desk.h \
e_border.h \
e_pointer.h \
@ -50,6 +51,7 @@ e_init.c \
e_ipc.c \
e_error.c \
e_container.c \
e_zone.c \
e_desk.c \
e_border.c \
e_pointer.c \

View File

@ -50,6 +50,7 @@
#include "e_ipc.h"
#include "e_error.h"
#include "e_container.h"
#include "e_zone.h"
#include "e_desk.h"
#include "e_border.h"
#include "e_pointer.h"
@ -69,6 +70,7 @@
#include "e_resist.h"
#include "e_startup.h"
#include "e_iconify.h"
#include "e_hints.h"
typedef struct _E_Before_Idler E_Before_Idler;

View File

@ -124,7 +124,14 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map)
bd = E_OBJECT_ALLOC(E_Border, _e_border_free);
if (!bd) return NULL;
bd->container = con;
bd->zone = e_zone_current_get(con);
bd->zone->clients = evas_list_append(bd->zone->clients, bd);
bd->desk = e_desk_current_get(bd->zone);
bd->desk->clients = evas_list_append(bd->desk->clients, bd);
bd->w = 1;
bd->h = 1;
bd->win = ecore_x_window_override_new(bd->container->win, 0, 0, bd->w, bd->h);
@ -322,6 +329,7 @@ e_border_move_resize(E_Border *bd, int x, int y, int w, int h)
bd->client.h);
}
/* FIXME: Zone client list is not altered. This affects desktop show function */
void
e_border_raise(E_Border *bd)
{
@ -386,21 +394,21 @@ e_border_focus_set(E_Border *bd, int focus, int set)
{
printf("take focus!\n");
ecore_x_icccm_take_focus_send(bd->client.win, ECORE_X_CURRENT_TIME);
e_hints_active_window_set(bd->client.win);
e_hints_active_window_set(bd->container->manager, bd->client.win);
ecore_x_window_focus(bd->client.win);
}
else
{
printf("set focus\n");
ecore_x_window_focus(bd->client.win);
e_hints_active_window_set(bd->client.win);
e_hints_active_window_set(bd->container->manager, bd->client.win);
}
}
else
{
printf("remove focus\n");
ecore_x_window_focus(bd->container->manager->win);
e_hints_active_window_set(0);
e_hints_active_window_set(bd->container->manager, 0);
}
}
if ((bd->focused) && (focused != bd))
@ -544,7 +552,8 @@ e_border_unshade(E_Border *bd, E_Direction dir)
void
e_border_maximize(E_Border *bd)
{
E_OBJECT_CHECK(bd);
E_Zone *zone;
if ((bd->shaded) || (bd->shading)) return;
if (!bd->maximized)
{
@ -555,7 +564,7 @@ e_border_maximize(E_Border *bd)
bd->saved.h = bd->h;
/* FIXME maximize intelligently */
e_border_move_resize(bd, 0, 0, bd->container->w, bd->container->h);
e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
bd->maximized = 1;
bd->changes.pos = 1;
bd->changes.size = 1;
@ -1869,12 +1878,12 @@ _e_border_eval(E_Border *bd)
int new_x, new_y;
printf("AUTO POS!\n");
if (bd->container->w > bd->w)
new_x = rand() % (bd->container->w - bd->w);
if (bd->zone->w > bd->w)
new_x = rand() % (bd->zone->w - bd->w);
else
new_x = 0;
if (bd->container->h > bd->h)
new_y = rand() % (bd->container->h - bd->h);
if (bd->zone->h > bd->h)
new_y = rand() % (bd->zone->h - bd->h);
else
new_y = 0;

View File

@ -44,6 +44,8 @@ struct _E_Border
int x, y, w, h;
int ref;
E_Container *container;
E_Zone *zone;
E_Desk *desk;
Evas_List *handlers;
struct {
@ -145,7 +147,6 @@ struct _E_Border
unsigned char re_manage : 1;
unsigned char shading : 1;
unsigned char shaded : 1;
unsigned char sticky : 1;
unsigned char maximized : 1;
unsigned char iconic : 1;
@ -166,6 +167,8 @@ struct _E_Border
Ecore_Animator *anim;
} shade;
Evas_List *stick_desks;
struct {
unsigned int visible : 1;
unsigned int pos : 1;

View File

@ -39,8 +39,10 @@ E_Container *
e_container_new(E_Manager *man)
{
E_Container *con;
E_Zone *zone;
con = E_OBJECT_ALLOC(E_Container, _e_container_free);
memset(con, 0, sizeof(E_Container));
if (!con) return NULL;
con->manager = man;
e_object_ref(E_OBJECT(con->manager));
@ -60,49 +62,17 @@ e_container_new(E_Manager *man)
e_path_evas_append(path_fonts, con->bg_evas);
e_pointer_container_set(con);
if (1) /* for now ALWAYS on - but later maybe a config option */
{
Evas_Object *o;
o = evas_object_rectangle_add(con->bg_evas);
con->bg_blank_object = 0;
evas_object_layer_set(o, -100);
evas_object_move(o, 0, 0);
evas_object_resize(o, con->w, con->h);
evas_object_color_set(o, 255, 255, 255, 255);
evas_object_show(o);
o = edje_object_add(con->bg_evas);
con->bg_object = o;
evas_object_layer_set(o, -1);
evas_object_name_set(o, "desktop/background");
evas_object_data_set(o, "e_container", con);
evas_object_move(o, 0, 0);
evas_object_resize(o, con->w, con->h);
edje_object_file_set(o,
e_config->desktop_default_background,
"desktop/background");
evas_object_show(o);
o = evas_object_rectangle_add(con->bg_evas);
con->bg_event_object = 0;
evas_object_move(o, 0, 0);
evas_object_resize(o, con->w, con->h);
evas_object_color_set(o, 255, 255, 255, 0);
evas_object_show(o);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_container_cb_bg_mouse_down, con);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _e_container_cb_bg_mouse_up, con);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _e_container_cb_bg_mouse_move, con);
ecore_evas_callback_resize_set(con->bg_ecore_evas, _e_container_cb_bg_ecore_evas_resize);
}
/* FIXME: Add ecore code to fetch xinerama screens for zones */
zone = e_zone_new(con, 0, 0, con->w, con->h);
return con;
}
void
e_container_show(E_Container *con)
{
printf("Container show!\n");
E_OBJECT_CHECK(con);
if (con->visible) return;
ecore_x_window_show(con->win);
@ -166,22 +136,6 @@ e_container_lower(E_Container *con)
ecore_x_window_lower(con->win);
}
void
e_container_bg_reconfigure(E_Container *con)
{
Evas_Object *o;
E_OBJECT_CHECK(con);
o = con->bg_object;
evas_object_hide(o);
edje_object_file_set(o,
e_config->desktop_default_background,
"desktop/background");
evas_object_layer_set(o, -1);
evas_object_show(o);
}
Evas_List *
e_container_clients_list_get(E_Container *con)
{
@ -327,68 +281,6 @@ _e_container_free(E_Container *con)
free(con);
}
static void
_e_container_cb_bg_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
E_Container *con;
Evas_Event_Mouse_Down *ev;
ev = (Evas_Event_Mouse_Down *)event_info;
con = data;
if (e_menu_grab_window_get()) return;
if (ev->button == 1)
{
E_Menu *m;
m = e_int_menus_main_new();
e_menu_activate_mouse(m, con, ev->output.x, ev->output.y, 1, 1,
E_MENU_POP_DIRECTION_DOWN);
e_util_container_fake_mouse_up_all_later(con);
}
else if (ev->button == 2)
{
E_Menu *m;
m = e_int_menus_clients_new();
/* FIXME: this is a bit of a hack... setting m->con - bad hack */
m->con = con;
e_menu_activate_mouse(m, con, ev->output.x, ev->output.y, 1, 1,
E_MENU_POP_DIRECTION_DOWN);
e_util_container_fake_mouse_up_all_later(con);
}
else if (ev->button == 3)
{
E_Menu *m;
m = e_int_menus_favorite_apps_new(1);
e_menu_activate_mouse(m, con, ev->output.x, ev->output.y, 1, 1,
E_MENU_POP_DIRECTION_DOWN);
e_util_container_fake_mouse_up_all_later(con);
}
}
static void
_e_container_cb_bg_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
E_Container *con;
Evas_Event_Mouse_Up *ev;
ev = (Evas_Event_Mouse_Up *)event_info;
con = data;
}
static void
_e_container_cb_bg_mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
E_Container *con;
Evas_Event_Mouse_Move *ev;
ev = (Evas_Event_Mouse_Move *)event_info;
con = data;
/* printf("move %i %i\n", ev->cur.output.x, ev->cur.output.y); */
}
static void
_e_container_cb_bg_ecore_evas_resize(Ecore_Evas *ee)
{
@ -401,8 +293,11 @@ _e_container_cb_bg_ecore_evas_resize(Ecore_Evas *ee)
evas_output_viewport_get(evas, NULL, NULL, &w, &h);
o = evas_object_name_find(evas, "desktop/background");
con = evas_object_data_get(o, "e_container");
/* FIXME: Handle resizing of zones if container is resized */
#if 0
evas_object_resize(con->bg_object, w, h);
evas_object_resize(con->bg_event_object, w, h);
#endif
_e_container_resize_handle(con);
}

View File

@ -29,12 +29,10 @@ struct _E_Container
Ecore_Evas *bg_ecore_evas;
Evas *bg_evas;
Ecore_X_Window bg_win;
Evas_Object *bg_blank_object;
Evas_Object *bg_object;
Evas_Object *bg_event_object;
Evas_List *shapes;
Evas_List *shape_change_cb;
Evas_List *zones;
Evas_List *clients;
};
@ -70,7 +68,6 @@ EAPI void e_container_resize(E_Container *con, int w, int h);
EAPI void e_container_move_resize(E_Container *con, int x, int y, int w, int h);
EAPI void e_container_raise(E_Container *con);
EAPI void e_container_lower(E_Container *con);
EAPI void e_container_bg_reconfigure(E_Container *con);
EAPI Evas_List *e_container_clients_list_get(E_Container *con);

View File

@ -1 +1,168 @@
/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
/* E_Desk is a child object of E_Zone. A desk is essentially a background
* and an associated set of client windows. Each zone can have an arbitrary
* number of desktops.
*/
static void _e_desk_free(E_Desk *desk);
E_Desk *
e_desk_new(E_Zone *zone)
{
E_Desk *desk;
char name[40];
desk = E_OBJECT_ALLOC(E_Desk, _e_desk_free);
memset(desk, 0, sizeof(E_Desk));
if (!desk) return NULL;
desk->zone = zone;
desk->num = evas_list_count(zone->desks) + 1;
snprintf(name, sizeof(name), "Desktop %d", desk->num);
desk->name = strdup(name);
e_object_ref(E_OBJECT(zone));
zone->desks = evas_list_append(zone->desks, desk);
return desk;
}
void
e_desk_name_set(E_Desk *desk, const char *name)
{
E_OBJECT_CHECK(desk);
if (desk->name)
free(desk->name);
desk->name = strdup(name);
}
void
e_desk_show(E_Desk *desk)
{
Evas_List *l;
E_OBJECT_CHECK(desk);
for (l = desk->zone->clients; l; l = l->next)
{
E_Border *bd = l->data;
if (evas_list_find(desk->clients, bd))
e_border_show(bd);
else
e_border_hide(bd);
}
for (l = desk->zone->desks; l; l = l->next)
{
E_Desk *d = l->data;
d->visible = 0;
}
desk->visible = 1;
}
void
e_desk_remove(E_Desk *desk)
{
Evas_List *l;
E_Desk *previous;
E_OBJECT_CHECK(desk);
if (evas_list_count(desk->zone->desks) < 2)
return;
l = evas_list_find(desk->zone->desks, desk);
l = l->prev;
if (!l) l = evas_list_last(desk->zone->desks);
previous = l->data;
for (l = desk->clients; l; l = l->next)
{
E_Border *bd = l->data;
bd->desk = previous;
}
desk->zone->desks = evas_list_remove(desk->zone->desks, desk);
e_desk_show(previous);
evas_list_free(desk->clients);
e_object_del(E_OBJECT(desk));
}
E_Desk *
e_desk_current_get(E_Zone *zone)
{
Evas_List *l;
E_OBJECT_CHECK(man);
for (l = zone->desks; l; l = l->next)
{
E_Desk *desk = l->data;
if (desk->visible)
return desk;
}
return NULL;
}
void
e_desk_next(E_Zone *zone)
{
Evas_List *l;
E_Desk *desk;
E_OBJECT_CHECK(zone);
if (evas_list_count(zone->desks) < 2)
return;
/* Locate the position of the current desktop in the list */
desk = e_desk_current_get(zone);
l = evas_list_find_list(zone->desks, desk);
if (!l) return; /* Couldn't help putting this here */
l = l->next;
if (!l) l = zone->desks; /* Wraparound */
/* Show the desktop */
desk = l->data;
e_desk_show(desk);
}
void
e_desk_prev(E_Zone *zone)
{
Evas_List *l;
E_Desk *desk;
E_OBJECT_CHECK(zone);
if (evas_list_count(zone->desks) < 2)
return;
/* Locate the position of the current desktop in the list */
desk = e_desk_current_get(zone);
l = evas_list_find_list(zone->desks, desk);
if (!l) return; /* Couldn't help putting this here */
l = l->prev;
if (!l) l = evas_list_last(zone->desks); /* Wraparound */
/* Show the desktop */
desk = l->data;
e_desk_show(desk);
}
static void
_e_desk_free(E_Desk *desk)
{
E_Zone *zone = desk->zone;
if (desk->name)
free(desk->name);
zone->desks = evas_list_remove(zone->desks, desk);
e_object_unref(E_OBJECT(desk->zone));
free(desk);
}

View File

@ -1,4 +1,28 @@
#ifndef E_DESK_H
#define E_DESK_H
typedef struct _E_Desk E_Desk;
struct _E_Desk
{
E_Object e_obj_inherit;
E_Zone *zone;
char *name;
int num;
char visible : 1;
Evas_Object *bg_object;
Evas_List *clients;
};
EAPI E_Desk *e_desk_new(E_Zone *zone);
EAPI void e_desk_name_set(E_Desk *desk, const char *name);
EAPI void e_desk_show(E_Desk *desk);
EAPI E_Desk *e_desk_current_get(E_Zone *zone);
EAPI void e_desk_next(E_Zone *zone);
EAPI void e_desk_prev(E_Zone *zone);
#endif

View File

@ -145,17 +145,10 @@ e_hints_client_stacking_set(void)
}
void
e_hints_active_window_set(Ecore_X_Window win)
e_hints_active_window_set(E_Manager *man, Ecore_X_Window win)
{
Evas_List *ml;
for (ml = e_manager_list(); ml; ml = ml->next)
{
E_Manager *m;
m = ml->data;
ecore_x_netwm_client_active_set(m->root, win);
}
E_OBJECT_CHECK(man);
ecore_x_netwm_client_active_set(man->root, win);
}
void
@ -232,7 +225,7 @@ e_hints_window_state_set(Ecore_X_Window win)
ecore_x_netwm_window_state_set(win, ECORE_X_WINDOW_STATE_MODAL,
bd->client.netwm.state.modal);
ecore_x_netwm_window_state_set(win, ECORE_X_WINDOW_STATE_STICKY,
bd->sticky);
(evas_list_count(bd->stick_desks) > 1));
ecore_x_netwm_window_state_set(win, ECORE_X_WINDOW_STATE_MAXIMIZED_VERT,
bd->client.netwm.state.maximized_v);
ecore_x_netwm_window_state_set(win, ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ,

View File

@ -4,7 +4,7 @@
EAPI void e_hints_init(void);
EAPI void e_hints_client_list_set(void);
EAPI void e_hints_client_stacking_set(void);
EAPI void e_hints_active_window_set(Ecore_X_Window win);
EAPI void e_hints_active_window_set(E_Manager *man, Ecore_X_Window win);
EAPI void e_hints_window_name_set(Ecore_X_Window win, const char *name);
EAPI void e_hints_desktop_config_set(void);
EAPI void e_hints_window_state_set(Ecore_X_Window win);

View File

@ -24,6 +24,10 @@ static void _e_int_menus_apps_free_hook (void *obj);
static void _e_int_menus_apps_run (void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_int_menus_clients_pre_cb (void *data, E_Menu *m);
static void _e_int_menus_clients_item_cb (void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_int_menus_desktops_pre_cb (void *data, E_Menu *m);
static void _e_int_menus_desktops_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_int_menus_desktops_add_cb (void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_int_menus_desktops_del_cb (void *data, E_Menu *m, E_Menu_Item *mi);
/* externally accessible functions */
E_Menu *
@ -57,6 +61,13 @@ e_int_menus_main_new(void)
e_menu_item_icon_edje_set(mi, e_path_find(path_icons, "default.eet"),
"module");
e_menu_item_submenu_set(mi, subm);
subm = e_int_menus_desktops_new();
mi = e_menu_item_new(m);
e_menu_item_label_set(mi, "Desktops");
e_menu_item_icon_edje_set(mi, e_path_find(path_icons, "default.eet"),
"windows");
e_menu_item_submenu_set(mi, subm);
subm = e_int_menus_clients_new();
mi = e_menu_item_new(m);
@ -109,6 +120,19 @@ e_int_menus_apps_new(char *dir, int top)
return m;
}
E_Menu *
e_int_menus_desktops_new(void)
{
E_Menu *m;
E_Menu_Item *mi;
m = e_menu_new();
e_menu_pre_activate_callback_set(m, _e_int_menus_desktops_pre_cb, NULL);
return m;
}
E_Menu *
e_int_menus_favorite_apps_new(int top)
{
@ -259,6 +283,105 @@ _e_int_menus_apps_run(void *data, E_Menu *m, E_Menu_Item *mi)
e_app_exec(a);
}
static void
_e_int_menus_desktops_pre_cb(void *data, E_Menu *m)
{
E_Menu_Item *mi;
Evas_List *l, *desks = NULL;
E_Menu *root;
if (m->realized) return;
/* clear list */
if (m->items)
{
Evas_List *l;
for (l = m->items; l; l = l->next)
{
E_Menu_Item *mi = l->data;
e_object_free(E_OBJECT(mi));
}
}
mi = e_menu_item_new(m);
e_menu_item_label_set(mi, "Add New Desktop");
e_menu_item_callback_set(mi, _e_int_menus_desktops_add_cb, NULL);
mi = e_menu_item_new(m);
e_menu_item_label_set(mi, "Remove This Desktop");
e_menu_item_callback_set(mi, _e_int_menus_desktops_del_cb, NULL);
mi = e_menu_item_new(m);
e_menu_item_separator_set(mi, 1);
root = e_menu_root_get(m);
/* Get the desktop list for this zone */
/* FIXME: Menu code needs to determine what zone menu was clicked in */
if (root && root->con)
{
E_Zone *zone = e_zone_current_get(root->con);
for (l = zone->desks; l; l = l->next)
{
E_Desk *desk = l->data;
desks = evas_list_append(desks, desk);
}
for (l = desks; l; l = l->next)
{
E_Desk *desk = l->data;
mi = e_menu_item_new(m);
e_menu_item_check_set(mi, 1);
e_menu_item_label_set(mi, desk->name);
e_menu_item_callback_set(mi, _e_int_menus_desktops_item_cb, desk);
if (desk == e_desk_current_get(zone))
e_menu_item_toggle_set(mi, 1);
e_menu_item_icon_edje_set(mi, e_path_find(path_icons, "default.eet"),
"desktop");
}
}
evas_list_free(desks);
}
/* FIXME: Use the zone the menu was clicked in */
static void
_e_int_menus_desktops_add_cb(void *data, E_Menu *m, E_Menu_Item *mi)
{
E_Menu *root = e_menu_root_get(m);
if (root && root->con)
{
E_Desk *desk;
E_Zone *zone = e_zone_current_get(root->con);
desk = e_desk_new(zone);
}
}
static void
_e_int_menus_desktops_del_cb(void *data, E_Menu *m, E_Menu_Item *mi)
{
E_Menu *root = e_menu_root_get(m);
if (root && root->con)
{
E_Zone *zone;
E_Desk *desk;
zone = e_zone_current_get(root->con);
desk = e_desk_current_get(zone);
e_desk_remove(desk);
}
}
static void
_e_int_menus_desktops_item_cb(void *data, E_Menu *m, E_Menu_Item *mi)
{
E_Desk *desk = data;
e_desk_show(desk);
}
static void
_e_int_menus_clients_pre_cb(void *data, E_Menu *m)
{

View File

@ -2,6 +2,7 @@
#define E_INT_MENUS_H
EAPI E_Menu *e_int_menus_main_new(void);
EAPI E_Menu *e_int_menus_desktops_new(void);
EAPI E_Menu *e_int_menus_clients_new(void);
EAPI E_Menu *e_int_menus_apps_new(char *dir, int top);
EAPI E_Menu *e_int_menus_favorite_apps_new(int top);

View File

@ -190,9 +190,11 @@ _e_ipc_cb_client_data(void *data, int type, void *event)
for (ll = man->containers; ll; ll = ll->next)
{
E_Container *con;
E_Zone *zone;
con = ll->data;
e_container_bg_reconfigure(con);
zone = e_zone_current_get(con);
e_zone_bg_reconfigure(zone);
}
}
e_config_save_queue();

View File

@ -513,11 +513,12 @@ _e_main_screens_init(void)
}
}
}
e_container_show(con);
}
else
{
e_error_message_show("Cannot create container object for manager on screen %i\n",
e_error_message_show("Cannot create desktop object for manager on screen %i\n",
i);
return 0;
}

View File

@ -189,7 +189,7 @@ _e_manager_cb_window_show_request(void *data, int ev_type, void *ev)
E_Container *con;
E_Border *bd;
con = man->containers->data;
con = man->containers->data;
if (!e_border_find_by_client_window(e->win))
{
bd = e_border_new(con, e->win, 0);

View File

@ -23,7 +23,7 @@ struct _E_Menu
Evas_List *items;
/* the container it belongs to */
/* the zone it belongs to */
E_Container *con;
/* if a menu item spawned this menu, what item is it? */