/*
* ion/ioncore/screen.c
*
- * Copyright (c) Tuomo Valkonen 1999-2006.
+ * Copyright (c) Tuomo Valkonen 1999-2007.
*
* Ion is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
#include "group-ws.h"
#include "mplex.h"
#include "tags.h"
+#include "gr.h"
+#include "gr-util.h"
+#include "conf.h"
WHook *screen_managed_changed_hook=NULL;
/*{{{ Init/deinit */
-static bool screen_init(WScreen *scr, WRootWin *rootwin,
- int id, const WFitParams *fp, bool useroot)
+bool screen_init(WScreen *scr, WRootWin *parent,
+ const WFitParams *fp, int id, Window rootwin)
{
Window win;
XSetWindowAttributes attr;
ulong attrflags=0;
+ bool is_root=FALSE;
scr->id=id;
scr->atom_workspace=None;
- scr->uses_root=useroot;
scr->managed_off.x=0;
scr->managed_off.y=0;
scr->managed_off.w=0;
watch_init(&(scr->notifywin_watch));
watch_init(&(scr->infowin_watch));
- if(useroot){
- win=WROOTWIN_ROOT(rootwin);
+ if(parent==NULL){
+ win=rootwin;
+ is_root=TRUE;
}else{
attr.background_pixmap=ParentRelative;
attrflags=CWBackPixmap;
- win=XCreateWindow(ioncore_g.dpy, WROOTWIN_ROOT(rootwin),
+ win=XCreateWindow(ioncore_g.dpy, WROOTWIN_ROOT(parent),
fp->g.x, fp->g.y, fp->g.w, fp->g.h, 0,
- DefaultDepth(ioncore_g.dpy, rootwin->xscr),
+ DefaultDepth(ioncore_g.dpy, parent->xscr),
InputOutput,
- DefaultVisual(ioncore_g.dpy, rootwin->xscr),
+ DefaultVisual(ioncore_g.dpy, parent->xscr),
attrflags, &attr);
if(win==None)
return FALSE;
+
}
- if(!mplex_do_init((WMPlex*)scr, (WWindow*)rootwin, win, fp, FALSE))
+ if(!mplex_do_init((WMPlex*)scr, (WWindow*)parent, fp, win)){
+ if(!is_root)
+ XDestroyWindow(ioncore_g.dpy, win);
return FALSE;
+ }
/*scr->mplex.win.region.rootwin=rootwin;
region_set_parent((WRegion*)scr, (WRegion*)rootwin);*/
scr->mplex.flags|=MPLEX_ADD_TO_END;
scr->mplex.win.region.flags|=REGION_BINDINGS_ARE_GRABBED;
- if(useroot)
+
+ if(!is_root){
scr->mplex.win.region.flags|=REGION_MAPPED;
+ window_select_input((WWindow*)scr, IONCORE_EVENTMASK_SCREEN);
+ }
- window_select_input(&(scr->mplex.win),
- FocusChangeMask|EnterWindowMask|
- KeyPressMask|KeyReleaseMask|
- ButtonPressMask|ButtonReleaseMask|
- (useroot ? IONCORE_EVENTMASK_ROOT : 0));
-
if(id==0){
scr->atom_workspace=XInternAtom(ioncore_g.dpy,
"_ION_WORKSPACE", False);
}
}
- /* Add rootwin's bindings to screens (ungrabbed) so that bindings
- * are called with the proper region.
+ /* Add all the needed bindings here; mplex does nothing so that
+ * frames don't have to remove extra bindings.
*/
- region_add_bindmap((WRegion*)scr, ioncore_rootwin_bindmap);
+ region_add_bindmap((WRegion*)scr, ioncore_screen_bindmap);
+ region_add_bindmap((WRegion*)scr, ioncore_mplex_bindmap);
+ region_add_bindmap((WRegion*)scr, ioncore_mplex_toplevel_bindmap);
LINK_ITEM(ioncore_g.screens, scr, next_scr, prev_scr);
}
-WScreen *create_screen(WRootWin *rootwin, int id, const WFitParams *fp,
- bool useroot)
+WScreen *create_screen(WRootWin *parent, const WFitParams *fp, int id)
{
- CREATEOBJ_IMPL(WScreen, screen, (p, rootwin, id, fp, useroot));
+ CREATEOBJ_IMPL(WScreen, screen, (p, parent, fp, id, None));
}
{
UNLINK_ITEM(ioncore_g.screens, scr, next_scr, prev_scr);
- if(scr->uses_root)
- scr->mplex.win.win=None;
-
mplex_deinit((WMPlex*)scr);
}
static void do_notify(WScreen *scr, Watch *watch, bool right,
- const char *str,
- char *style, const char *attr)
+ const char *str, char *style)
{
WInfoWin *iw=(WInfoWin*)(watch->obj);
watch_setup(watch, (Obj*)iw, NULL);
}
- infowin_set_attr2(iw, attr, NULL);
infowin_set_text(iw, str);
}
void screen_notify(WScreen *scr, const char *str)
{
- do_notify(scr, &scr->notifywin_watch, FALSE, str, "actnotify", NULL);
+ do_notify(scr, &scr->notifywin_watch, FALSE, str, "actnotify");
}
-void screen_windowinfo(WScreen *scr, const char *str, const char *attr)
+void screen_windowinfo(WScreen *scr, const char *str)
{
- do_notify(scr, &scr->infowin_watch, TRUE, str, "tab-info", attr);
+ do_notify(scr, &scr->infowin_watch, TRUE, str, "tab-info");
}
Obj *iw=scr->notifywin_watch.obj;
if(iw!=NULL){
watch_reset(&(scr->notifywin_watch));
- mainloop_defer_destroy(iw);
+ region_dispose((WRegion*)iw, FALSE);
}
}
Obj *iw=scr->infowin_watch.obj;
if(iw!=NULL){
watch_reset(&(scr->infowin_watch));
- mainloop_defer_destroy(iw);
+ region_dispose((WRegion*)iw, FALSE);
}
}
}
+GR_DEFATTR(active);
+GR_DEFATTR(inactive);
+GR_DEFATTR(selected);
+GR_DEFATTR(tagged);
+GR_DEFATTR(not_tagged);
+GR_DEFATTR(not_dragged);
+GR_DEFATTR(activity);
+GR_DEFATTR(no_activity);
+
+
+static void init_attr()
+{
+ GR_ALLOCATTR_BEGIN;
+ GR_ALLOCATTR(active);
+ GR_ALLOCATTR(inactive);
+ GR_ALLOCATTR(selected);
+ GR_ALLOCATTR(tagged);
+ GR_ALLOCATTR(not_tagged);
+ GR_ALLOCATTR(not_dragged);
+ GR_ALLOCATTR(no_activity);
+ GR_ALLOCATTR(activity);
+ GR_ALLOCATTR_END;
+}
+
+
static void screen_update_infowin(WScreen *scr)
{
WRegion *reg=mplex_mx_current(&(scr->mplex));
bool tag=(reg!=NULL && region_is_tagged(reg));
- bool act=(reg!=NULL && region_is_activity_r(reg));
+ bool act=(reg!=NULL && region_is_activity_r(reg) && !REGION_IS_ACTIVE(scr));
+ bool sac=REGION_IS_ACTIVE(scr);
if(tag || act){
const char *n=region_displayname(reg);
- char *attr=NULL;
+ WInfoWin *iw;
+
+ screen_windowinfo(scr, n);
- libtu_asprintf(&attr, "%s-selected-%s-not_dragged-%s",
- (REGION_IS_ACTIVE(scr) ? "active" : "inactive"),
- (tag ? "tagged" : "not_tagged"),
- (act ? "activity" : "no_activity"));
+ iw=(WInfoWin*)scr->infowin_watch.obj;
- screen_windowinfo(scr, n, attr); /* NULL attr ok */
+ if(iw!=NULL){
+ GrStyleSpec *spec=infowin_stylespec(iw);
+
+ init_attr();
+
+ gr_stylespec_unalloc(spec);
+
+ gr_stylespec_set(spec, GR_ATTR(selected));
+ gr_stylespec_set(spec, GR_ATTR(not_dragged));
+ gr_stylespec_set(spec, sac ? GR_ATTR(active) : GR_ATTR(inactive));
+ gr_stylespec_set(spec, tag ? GR_ATTR(tagged) : GR_ATTR(not_tagged));
+ gr_stylespec_set(spec, act ? GR_ATTR(activity) : GR_ATTR(no_activity));
+ }
+
}else{
screen_nowindowinfo(scr);
}
}
-static void screen_managed_notify(WScreen *scr, WRegion *reg, const char *how)
+static void screen_managed_notify(WScreen *scr, WRegion *reg, WRegionNotify how)
{
- if(strcmp(how, "sub-activity")==0){
+ if(how==ioncore_g.notifies.sub_activity){
/* TODO: multiple calls */
mainloop_defer_action((Obj*)scr,
(WDeferredAction*)screen_notify_activity);
- }else if(strcmp(how, "tag")==0){
+ }else if(how==ioncore_g.notifies.tag){
mainloop_defer_action((Obj*)scr,
(WDeferredAction*)screen_notify_tag);
}
/*EXTL_DOC
- * Find the screen with numerical id \var{id}. If Xinerama is
- * not present, \var{id} corresponds to X screen numbers. Otherwise
- * the ids are some arbitrary ordering of Xinerama rootwins.
- * If \var{id} is $-1$, the screen with the highest id is returned.
+ * Find the screen with numerical id \var{id}.
*/
EXTL_SAFE
EXTL_EXPORT
static bool create_initial_ws(WScreen *scr)
{
WRegion *reg=NULL;
- WMPlexAttachParams par;
-
- par.flags=0;
+ WMPlexAttachParams par=MPLEXATTACHPARAMS_INIT;
+ ExtlTab lo=ioncore_get_layout("default");
- reg=mplex_do_attach_new(&scr->mplex, &par,
- (WRegionCreateFn*)groupws_load_default,
- NULL);
+ if(lo==extl_table_none()){
+ reg=mplex_do_attach_new(&scr->mplex, &par,
+ (WRegionCreateFn*)create_groupws, NULL);
+ }else{
+ reg=mplex_attach_new_(&scr->mplex, &par, 0, lo);
+ extl_unref_table(lo);
+ }
if(reg==NULL){
warn(TR("Unable to create a workspace on screen %d."), scr->id);