]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/screen.c
[svn-upgrade] Integrating new upstream version, ion3 (20070203)
[ion3.git] / ioncore / screen.c
index 3b896bfab6e218012b041d6a11d2e4d12f81b626..cac75a061b063d51d9fdc97e888b2a0e610ca8c0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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
@@ -39,6 +39,9 @@
 #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;
@@ -51,16 +54,16 @@ static void screen_update_infowin(WScreen *scr);
 /*{{{ 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;
@@ -72,38 +75,40 @@ static bool screen_init(WScreen *scr, WRootWin *rootwin,
     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);
@@ -116,10 +121,12 @@ static bool screen_init(WScreen *scr, WRootWin *rootwin,
         }
     }
 
-    /* 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);
     
@@ -127,10 +134,9 @@ static bool screen_init(WScreen *scr, WRootWin *rootwin,
 }
 
 
-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));
 }
 
 
@@ -138,9 +144,6 @@ void screen_deinit(WScreen *scr)
 {
     UNLINK_ITEM(ioncore_g.screens, scr, next_scr, prev_scr);
     
-    if(scr->uses_root)
-        scr->mplex.win.win=None;
-    
     mplex_deinit((WMPlex*)scr);
 }
 
@@ -266,8 +269,7 @@ void screen_activated(WScreen *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);
@@ -304,20 +306,19 @@ static void do_notify(WScreen *scr, Watch *watch, bool right,
         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");
 }
 
 
@@ -326,7 +327,7 @@ void screen_unnotify(WScreen *scr)
     Obj *iw=scr->notifywin_watch.obj;
     if(iw!=NULL){
         watch_reset(&(scr->notifywin_watch));
-        mainloop_defer_destroy(iw);
+        region_dispose((WRegion*)iw, FALSE);
     }
 }
 
@@ -336,7 +337,7 @@ void screen_nowindowinfo(WScreen *scr)
     Obj *iw=scr->infowin_watch.obj;
     if(iw!=NULL){
         watch_reset(&(scr->infowin_watch));
-        mainloop_defer_destroy(iw);
+        region_dispose((WRegion*)iw, FALSE);
     }
 }
 
@@ -397,35 +398,73 @@ static void screen_notify_tag(WScreen *scr)
 }
 
 
+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);
     }
@@ -439,10 +478,7 @@ static void screen_managed_notify(WScreen *scr, WRegion *reg, const char *how)
 
 
 /*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
@@ -644,13 +680,16 @@ static WRegion *do_create_initial(WWindow *parent, const WFitParams *fp,
 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);