--- src/neg.c 2006-11-26 09:49:23.000000000 -0600 +++ src/reg.c 2006-11-27 16:26:01.000000000 -0600 @@ -40,6 +40,12 @@ /* defaults */ +static char *excludeWinType[] = { + N_("Desktop") +}; + +#define N_EXCLUDE_WIN_TYPE (sizeof (excludeWinType) / sizeof (excludeWinType[0])) + #define NEG_TOGGLE_KEY_DEFAULT "n" #define NEG_TOGGLE_MODIFIERS_DEFAULT CompSuperMask @@ -50,6 +56,13 @@ #define NEG_DISPLAY_OPTION_SCREEN_TOGGLE 1 #define NEG_DISPLAY_OPTION_NUM 2 +#define NEG_SCREEN_OPTION_EXCLUDE_NULL_WM_CLASS 0 +#define NEG_SCREEN_OPTION_EXCLUDE_WINDOW_TYPE 1 +#define NEG_SCREEN_OPTION_EXCLUDE_LIST 2 +#define NEG_SCREEN_OPTION_NUM 3 + +#define NEG_EXCLUDE_NULL_WM_CLASS_DEFAULT TRUE + static int displayPrivateIndex; typedef struct _NEGDisplay @@ -62,10 +75,12 @@ typedef struct _NEGSCreen { int windowPrivateIndex; + CompOption opt[NEG_SCREEN_OPTION_NUM]; /* array of screen options */ DrawWindowTextureProc drawWindowTexture; /* function pointer */ DamageWindowRectProc damageWindowRect; /* function pointer */ PaintWindowProc paintWindow; /* function pointer */ Bool isNeg; /* negative screen flag */ + unsigned int excludeWMask; } NEGScreen; typedef struct _NEGWindow @@ -85,10 +100,30 @@ static void NEGToggle (CompWindow * w) { + CompOption *o; + int i; + + NEG_SCREEN (w->screen); NEG_WINDOW (w); /* toggle window negative flag */ - nw->isNeg = !nw->isNeg; + if (ns->opt[NEG_SCREEN_OPTION_EXCLUDE_NULL_WM_CLASS].value.b && + (w->resClass == NULL)) + nw->isNeg = FALSE; + else + { + if (!(ns->excludeWMask & w->type)) + nw->isNeg = !nw->isNeg; + } + + /* check exclude list */ + o = &ns->opt[NEG_SCREEN_OPTION_EXCLUDE_LIST]; + for (i = 0; i < o->value.list.nValue; i++) + { + if (w->resClass + && (strcmp (o->value.list.value[i].s, w->resClass) == 0)) + nw->isNeg = FALSE; + } /* cause repainting */ addWindowDamage (w); @@ -610,6 +645,99 @@ free (nd); } +static void +NEGScreenInitOptions (NEGScreen * ns) +{ + CompOption *o; + int i; + + o = &ns->opt[NEG_SCREEN_OPTION_EXCLUDE_NULL_WM_CLASS]; + o->name = "exclude_null_wm_class"; + o->shortDesc = N_("Exclude Null WM_CLASS"); + o->longDesc = N_("Exclude to negate if WM_CLASS is Null"); + o->type = CompOptionTypeBool; + o->value.b = NEG_EXCLUDE_NULL_WM_CLASS_DEFAULT; + + o = &ns->opt[NEG_SCREEN_OPTION_EXCLUDE_WINDOW_TYPE]; + o->name = "exclude_window_types"; + o->shortDesc = N_("Exclude Window Types"); + o->longDesc = N_("Window types that should exclude to negate"); + o->type = CompOptionTypeList; + o->value.list.type = CompOptionTypeString; + o->value.list.nValue = N_EXCLUDE_WIN_TYPE; + o->value.list.value = + malloc (sizeof (CompOptionValue) * N_EXCLUDE_WIN_TYPE); + for (i = 0; i < N_EXCLUDE_WIN_TYPE; i++) + o->value.list.value[i].s = strdup (excludeWinType[i]); + o->rest.s.string = (char **)windowTypeString; + o->rest.s.nString = nWindowTypeString; + + ns->excludeWMask = compWindowTypeMaskFromStringList (&o->value); + + o = &ns->opt[NEG_SCREEN_OPTION_EXCLUDE_LIST]; + o->name = "exclude_list"; + o->shortDesc = N_("WM_CLASS to exclude"); + o->longDesc = N_("Windows classes to exclude from negating"); + o->type = CompOptionTypeList; + o->value.list.type = CompOptionTypeString; + o->value.list.nValue = 0; + o->value.list.value = 0; + o->rest.s.string = 0; + o->rest.s.nString = 0; +} + +static CompOption * +NEGGetScreenOptions (CompScreen * screen, int *count) +{ + if (screen) + { + NEG_SCREEN (screen); + *count = NUM_OPTIONS (ns); + return ns->opt; + } + else + { + NEGScreen *ns = malloc (sizeof (NEGScreen)); + NEGScreenInitOptions (ns); + *count = NUM_OPTIONS (ns); + return ns->opt; + } +} + +static Bool +NEGSetScreenOption (CompScreen * screen, char *name, CompOptionValue * value) +{ + CompOption *o; + int index; + + NEG_SCREEN (screen); + + o = compFindOption (ns->opt, NUM_OPTIONS (ns), name, &index); + if (!o) + return FALSE; + + switch (index) + { + case NEG_SCREEN_OPTION_EXCLUDE_WINDOW_TYPE: + if (compSetOptionList (o, value)) + { + ns->excludeWMask = compWindowTypeMaskFromStringList (&o->value); + return TRUE; + } + break; + + case NEG_SCREEN_OPTION_EXCLUDE_LIST: + if (compSetOptionList (o, value)) + return TRUE; + break; + + default: + break; + } + + return FALSE; +} + static Bool NEGInitScreen (CompPlugin * p, CompScreen * s) { @@ -632,6 +760,9 @@ */ ns->isNeg = FALSE; + /* Initialize the screen options */ + NEGScreenInitOptions (ns); + /* add screen actions */ addScreenAction (s, &nd->opt[NEG_DISPLAY_OPTION_WINDOW_TOGGLE].value.action); @@ -721,8 +852,8 @@ NEGFiniWindow, NEGGetDisplayOptions, NEGSetDisplayOption, - 0, /* GetScreenOptions */ - 0, /* SetScreenOption */ + NEGGetScreenOptions, + NEGSetScreenOption, NULL, 0, 0,