Пример #1
0
/** Determine if this is a window to be swallowed, if it is, swallow it. */
int CheckSwallowMap(const XMapEvent *event) {

   SwallowNode *np;
   XClassHint hint;
   XWindowAttributes attr;

   for(np = swallowNodes; np; np = np->next) {

      if(np->cp->window != None) {
         continue;
      }

      Assert(np->cp->tray->window != None);

      if(JXGetClassHint(display, event->window, &hint)) {
         if(!strcmp(hint.res_name, np->name)) {

            /* Swallow the window. */
            JXSelectInput(display, event->window,
                 StructureNotifyMask | ResizeRedirectMask);
            JXAddToSaveSet(display, event->window);
            JXSetWindowBorder(display, event->window, colors[COLOR_TRAY_BG]);
            JXReparentWindow(display, event->window,
               np->cp->tray->window, 0, 0);
            JXMapRaised(display, event->window);
            JXFree(hint.res_name);
            JXFree(hint.res_class);
            np->cp->window = event->window;

            /* Update the size. */
            JXGetWindowAttributes(display, event->window, &attr);
            np->border = attr.border_width;
            if(!np->userWidth) {
               np->cp->requestedWidth = attr.width + 2 * np->border;
            }
            if(!np->userHeight) {
               np->cp->requestedHeight = attr.height + 2 * np->border;
            }

            ResizeTray(np->cp->tray);

            return 1;

         } else {

            JXFree(hint.res_name);
            JXFree(hint.res_class);

         }
      }

   }

   return 0;

}
Пример #2
0
Файл: hint.c Проект: Miteam/jwm
/** Read a window atom. */
char GetWindowAtom(Window window, AtomType atom, Window *value)
{

   unsigned long count;
   int status;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *data;
   char ret;

   Assert(window != None);
   Assert(value);

   status = JXGetWindowProperty(display, window, atoms[atom], 0, 1, False,
                                XA_WINDOW, &realType, &realFormat,
                                &count, &extra, &data);
   ret = 0;
   if(status == Success && realFormat != 0 && data) {
      if(count == 1) {
         *value = *(Window*)data;
         ret = 1;
      }
      JXFree(data);
   }

   return ret;

}
Пример #3
0
Файл: hint.c Проект: Miteam/jwm
/** Read the protocols hint for a window. */
void ReadWMProtocols(Window w, ClientState *state)
{

   unsigned long count, x;
   int status;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *temp;
   Atom *p;

   Assert(w != None);

   state->status &= ~STAT_TAKEFOCUS;
   state->status &= ~STAT_DELETE;
   status = JXGetWindowProperty(display, w, atoms[ATOM_WM_PROTOCOLS],
                                0, 32, False, XA_ATOM, &realType, &realFormat,
                                &count, &extra, &temp);
   p = (Atom*)temp;
   if(status != Success || realFormat == 0 || !p) {
      return;
   }

   for(x = 0; x < count; x++) {
      if(p[x] == atoms[ATOM_WM_DELETE_WINDOW]) {
         state->status |= STAT_DELETE;
      } else if(p[x] == atoms[ATOM_WM_TAKE_FOCUS]) {
         state->status |= STAT_TAKEFOCUS;
      }
   }

   JXFree(p);

}
Пример #4
0
Файл: hint.c Проект: Miteam/jwm
/** Read the WM state for a window. */
void ReadWMState(Window win, ClientState *state)
{

   Status status;
   unsigned long count;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned long *temp;

   status = JXGetWindowProperty(display, win, atoms[ATOM_WM_STATE], 0, 2,
                                False, atoms[ATOM_WM_STATE],
                                &realType, &realFormat,
                                &count, &extra, (unsigned char**)&temp);
   if(JLIKELY(status == Success && realFormat == 32 && count == 2)) {
      switch(temp[0]) {
      case IconicState:
         state->status |= STAT_MINIMIZED;
         break;
      case WithdrawnState:
         state->status &= ~STAT_MAPPED;
         break;
      default:
         break;
      }
      JXFree(temp);
   }

}
Пример #5
0
Файл: hint.c Проект: Miteam/jwm
/** Read the WM hints for a window. */
void ReadWMHints(Window win, ClientState *state, char alreadyMapped)
{

   XWMHints *wmhints;

   Assert(win != None);
   Assert(state);

   state->status |= STAT_CANFOCUS;
   wmhints = JXGetWMHints(display, win);
   if(wmhints) {
      if(!alreadyMapped && (wmhints->flags & StateHint)) {
         switch(wmhints->initial_state) {
         case IconicState:
            state->status |= STAT_MINIMIZED;
            break;
         default:
            break;
         }
      }
      if((wmhints->flags & InputHint) && wmhints->input == False) {
         state->status &= ~STAT_CANFOCUS;
      }
      if(wmhints->flags & XUrgencyHint) {
         state->status |= STAT_URGENT;
      } else {
         state->status &= ~(STAT_URGENT | STAT_FLASH);
      }
      JXFree(wmhints);
   }

}
Пример #6
0
Файл: hint.c Проект: Miteam/jwm
/** Read _MOTIF_WM_HINTS */
void ReadMotifHints(Window win, ClientState *state)
{

   PropMwmHints *mhints;
   Atom type;
   unsigned long itemCount, bytesLeft;
   unsigned char *data;
   int format;

   Assert(win != None);
   Assert(state);

   if(JXGetWindowProperty(display, win, atoms[ATOM_MOTIF_WM_HINTS], 0L, 20L,
                          False, atoms[ATOM_MOTIF_WM_HINTS], &type, &format,
                          &itemCount, &bytesLeft, &data) != Success
         || format == 0) {
      return;
   }

   mhints = (PropMwmHints*)data;
   if(mhints) {

      if((mhints->flags & MWM_HINTS_FUNCTIONS)
         && !(mhints->functions & MWM_FUNC_ALL)) {

         if(!(mhints->functions & MWM_FUNC_RESIZE)) {
            state->border &= ~BORDER_RESIZE;
         }
         if(!(mhints->functions & MWM_FUNC_MOVE)) {
            state->border &= ~BORDER_MOVE;
         }
         if(!(mhints->functions & MWM_FUNC_MINIMIZE)) {
            state->border &= ~BORDER_MIN;
         }
         if(!(mhints->functions & MWM_FUNC_MAXIMIZE)) {
            state->border &= ~BORDER_MAX;
         }
         if(!(mhints->functions & MWM_FUNC_CLOSE)) {
            state->border &= ~BORDER_CLOSE;
         }
      }

      if((mhints->flags & MWM_HINTS_DECORATIONS)
         && !(mhints->decorations & MWM_DECOR_ALL)) {

         if(!(mhints->decorations & MWM_DECOR_BORDER)) {
            state->border &= ~BORDER_OUTLINE;
         }
         if(!(mhints->decorations & MWM_DECOR_TITLE)) {
            state->border &= ~BORDER_TITLE;
         }
      }

      JXFree(mhints);
   }
}
Пример #7
0
/** Read the icon property from a client. */
void ReadNetWMIcon(ClientNode *np)
{
   unsigned long count;
   int status;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *data;
   status = JXGetWindowProperty(display, np->window, atoms[ATOM_NET_WM_ICON],
                                0, 256 * 256 * 4, False, XA_CARDINAL,
                                &realType, &realFormat, &count, &extra, &data);
   if(status == Success && realFormat != 0 && data) {
      np->icon = CreateIconFromBinary((unsigned long*)data, count);
      JXFree(data);
   }
}
Пример #8
0
/** Startup screens. */
void StartupScreens()
{
#ifdef USE_XINERAMA

   XineramaScreenInfo *info;
   int x;

   if(XineramaIsActive(display)) {

      info = XineramaQueryScreens(display, &screenCount);

      screens = Allocate(sizeof(ScreenType) * screenCount);
      for(x = 0; x < screenCount; x++) {
         screens[x].index = x;
         screens[x].x = info[x].x_org;
         screens[x].y = info[x].y_org;
         screens[x].width = info[x].width;
         screens[x].height = info[x].height;
      }

      JXFree(info);

   } else {

      screenCount = 1;
      screens = Allocate(sizeof(ScreenType));
      screens->index = 0;
      screens->x = 0;
      screens->y = 0;
      screens->width = rootWidth;
      screens->height = rootHeight;

   }

#else

   screenCount = 1;
   screens = Allocate(sizeof(ScreenType));
   screens->index = 0;
   screens->x = 0;
   screens->y = 0;
   screens->width = rootWidth;
   screens->height = rootHeight;

#endif /* USE_XINERAMA */
}
Пример #9
0
/** Read the icon WMHint property from a client. */
void ReadWMHintIcon(ClientNode *np)
{
   XWMHints *hints;
   hints = JXGetWMHints(display, np->window);
   if(hints) {
      Drawable d = None;
      Pixmap mask = None;
      if(hints->flags & IconMaskHint) {
         mask = hints->icon_mask;
      }
      if(hints->flags & IconPixmapHint) {
         d = hints->icon_pixmap;
      }
      if(d != None) {
         np->icon = CreateIconFromDrawable(d, mask);
      }
      JXFree(hints);
   }
}
Пример #10
0
Файл: icon.c Проект: Miteam/jwm
/** Read the icon property from a client. */
IconNode *ReadNetWMIcon(Window win)
{
   static const long MAX_LENGTH = 1 << 20;
   IconNode *icon = NULL;
   unsigned long count;
   int status;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *data;
   status = JXGetWindowProperty(display, win, atoms[ATOM_NET_WM_ICON],
                                0, MAX_LENGTH, False, XA_CARDINAL,
                                &realType, &realFormat, &count, &extra, &data);
   if(status == Success && realFormat != 0 && data) {
      icon = CreateIconFromBinary((unsigned long*)data, count);
      JXFree(data);
   }
   return icon;
}
Пример #11
0
Файл: icon.c Проект: Miteam/jwm
/** Read the icon WMHint property from a client. */
IconNode *ReadWMHintIcon(Window win)
{
   IconNode *icon = NULL;
   XWMHints *hints = JXGetWMHints(display, win);
   if(hints) {
      Drawable d = None;
      Pixmap mask = None;
      if(hints->flags & IconMaskHint) {
         mask = hints->icon_mask;
      }
      if(hints->flags & IconPixmapHint) {
         d = hints->icon_pixmap;
      }
      if(d != None) {
         icon = CreateIconFromDrawable(d, mask);
      }
      JXFree(hints);
   }
   return icon;
}
Пример #12
0
Файл: hint.c Проект: Miteam/jwm
/** Read colormap information for a client. */
void ReadWMColormaps(ClientNode *np)
{

   Window *windows;
   ColormapNode *cp;
   int count;

   Assert(np);

   if(JXGetWMColormapWindows(display, np->window, &windows, &count)) {
      if(count > 0) {
         int x;

         /* Free old colormaps. */
         while(np->colormaps) {
            cp = np->colormaps->next;
            Release(np->colormaps);
            np->colormaps = cp;
         }

         /* Put the maps in the list in order so they will come out in
          * reverse order. This way they will be installed with the
          * most important last.
          * Keep track of at most colormapCount colormaps for each
          * window to avoid doing extra work. */
         count = Min(colormapCount, count);
         for(x = 0; x < count; x++) {
            cp = Allocate(sizeof(ColormapNode));
            cp->window = windows[x];
            cp->next = np->colormaps;
            np->colormaps = cp;
         }

         JXFree(windows);

      }
   }

}
Пример #13
0
/** Load windows that are already mapped. */
void StartupClients(void)
{

   XWindowAttributes attr;
   Window rootReturn, parentReturn, *childrenReturn;
   unsigned int childrenCount;
   unsigned int x;

   clientCount = 0;
   activeClient = NULL;
   currentDesktop = 0;

   /* Clear out the client lists. */
   for(x = 0; x < LAYER_COUNT; x++) {
      nodes[x] = NULL;
      nodeTail[x] = NULL;
   }

   /* Query client windows. */
   JXQueryTree(display, rootWindow, &rootReturn, &parentReturn,
               &childrenReturn, &childrenCount);

   /* Add each client. */
   for(x = 0; x < childrenCount; x++) {
      if(JXGetWindowAttributes(display, childrenReturn[x], &attr)) {
         if(attr.override_redirect == False && attr.map_state == IsViewable) {
            AddClientWindow(childrenReturn[x], 1, 1);
         }
      }
   }

   JXFree(childrenReturn);

   LoadFocus();

   RequireTaskUpdate();
   RequirePagerUpdate();

}
Пример #14
0
/** Handle a client message. */
void HandleClientMessage(const XClientMessageEvent *event) {

   ClientNode *np;
   long mask, flags;
#ifdef DEBUG
   char *atomName;
#endif

   np = FindClientByWindow(event->window);
   if(np) {
      if(event->message_type == atoms[ATOM_WIN_STATE]) {

         mask = event->data.l[0];
         flags = event->data.l[1];

         if(mask & WIN_STATE_STICKY) {
            if(flags & WIN_STATE_STICKY) {
               SetClientSticky(np, 1);
            } else {
               SetClientSticky(np, 0);
            }
         }

         if(mask & WIN_STATE_HIDDEN) {
            if(flags & WIN_STATE_HIDDEN) {
               np->state.status |= STAT_NOLIST;
            } else {
               np->state.status &= ~STAT_NOLIST;
            }
            UpdateTaskBar();
            UpdatePager();
         }

      } else if(event->message_type == atoms[ATOM_WIN_LAYER]) {

         SetClientLayer(np, event->data.l[0]);

      } else if(event->message_type == atoms[ATOM_WM_CHANGE_STATE]) {

         if(np->controller) {
            (np->controller)(0);
         }

         switch(event->data.l[0]) {
         case WithdrawnState:
            SetClientWithdrawn(np);
            break;
         case IconicState:
            MinimizeClient(np);
            break;
         case NormalState:
            RestoreClient(np, 1);
            break;
         default:
            break;
         }

      } else if(event->message_type == atoms[ATOM_NET_ACTIVE_WINDOW]) {

         RestoreClient(np, 1);
         FocusClient(np);

      } else if(event->message_type == atoms[ATOM_NET_WM_DESKTOP]) {

         if(event->data.l[0] == ~0L) {
            SetClientSticky(np, 1);
         } else {

            if(np->controller) {
               (np->controller)(0);
            }

            if(event->data.l[0] >= 0 && event->data.l[0] < (long)desktopCount) {
               np->state.status &= ~STAT_STICKY;
               SetClientDesktop(np, event->data.l[0]);
            }
         }

      } else if(event->message_type == atoms[ATOM_NET_CLOSE_WINDOW]) {

         DeleteClient(np);

      } else if(event->message_type == atoms[ATOM_NET_MOVERESIZE_WINDOW]) {

         HandleNetMoveResize(event, np);

      } else if(event->message_type == atoms[ATOM_NET_WM_STATE]) {

         HandleNetWMState(event, np);

      } else {

#ifdef DEBUG
         atomName = JXGetAtomName(display, event->message_type);
         Debug("Unknown ClientMessage to client: %s", atomName);
         JXFree(atomName);
#endif

      }

   } else if(event->window == rootWindow) {

      if(event->message_type == atoms[ATOM_JWM_RESTART]) {
         Restart();
      } else if(event->message_type == atoms[ATOM_JWM_EXIT]) {
         Exit();
      } else if(event->message_type == atoms[ATOM_NET_CURRENT_DESKTOP]) {
         ChangeDesktop(event->data.l[0]);
      } else {
#ifdef DEBUG
         atomName = JXGetAtomName(display, event->message_type);
         Debug("Unknown ClientMessage to root: %s", atomName);
         JXFree(atomName);
#endif
      }

   } else if(event->message_type == atoms[ATOM_NET_SYSTEM_TRAY_OPCODE]) {

      HandleDockEvent(event);

   }

}
Пример #15
0
Файл: hint.c Проект: Miteam/jwm
/** Determine the title to display for a client. */
void ReadWMName(ClientNode *np)
{

   unsigned long count;
   int status;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *name;

   if(np->name) {
      Release(np->name);
   }

   status = JXGetWindowProperty(display, np->window,
                                atoms[ATOM_NET_WM_NAME], 0, 1024, False,
                                atoms[ATOM_UTF8_STRING], &realType,
                                &realFormat, &count, &extra, &name);
   if(status != Success || realFormat == 0) {
      np->name = NULL;
   } else {
      const size_t size = strlen((char*)name) + 1;
      np->name = Allocate(size);
      memcpy(np->name, name, size);
      JXFree(name);
      np->name = ConvertFromUTF8(np->name);
   }

#ifdef USE_XUTF8
   if(!np->name) {
      status = JXGetWindowProperty(display, np->window,
                                   XA_WM_NAME, 0, 1024, False,
                                   atoms[ATOM_COMPOUND_TEXT],
                                   &realType, &realFormat, &count,
                                   &extra, &name);
      if(status == Success && realFormat == 8) {
         char **tlist;
         XTextProperty tprop;
         int tcount;
         tprop.value = name;
         tprop.encoding = atoms[ATOM_COMPOUND_TEXT];
         tprop.format = realFormat;
         tprop.nitems = strlen((char*)name);
         if(XmbTextPropertyToTextList(display, &tprop, &tlist, &tcount)
            == Success && tcount > 0) {
            const size_t len = strlen(tlist[0]) + 1;
            np->name = Allocate(len);
            memcpy(np->name, tlist[0], len);
            XFreeStringList(tlist);
         }
         JXFree(name);
      }
   }
#endif

   if(!np->name) {
      char *temp = NULL;
      if(JXFetchName(display, np->window, &temp)) {
         const size_t len = strlen(temp) + 1;
         np->name = Allocate(len);
         memcpy(np->name, temp, len);
         JXFree(temp);
      }
   }

}
Пример #16
0
Файл: hint.c Проект: Miteam/jwm
/** Read all hints needed to determine the current window state. */
ClientState ReadWindowState(Window win, char alreadyMapped)
{

   ClientState result;
   Status status;
   unsigned long count, x;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *temp;
   Atom *state;
   unsigned long card;
   Window utwin;

   Assert(win != None);

   result.status = STAT_MAPPED;
   result.maxFlags = MAX_NONE;
   result.border = BORDER_DEFAULT;
   result.layer = LAYER_NORMAL;
   result.defaultLayer = LAYER_NORMAL;
   result.desktop = currentDesktop;
   result.opacity = UINT_MAX;

   ReadWMProtocols(win, &result);
   ReadWMHints(win, &result, alreadyMapped);
   ReadWMState(win, &result);
   ReadMotifHints(win, &result);
   ReadWMOpacity(win, &result.opacity);

   /* _NET_WM_DESKTOP */
   if(GetCardinalAtom(win, ATOM_NET_WM_DESKTOP, &card)) {
      if(card == ~0UL) {
         result.status |= STAT_STICKY;
      } else if(card < settings.desktopCount) {
         result.desktop = card;
      } else {
         result.desktop = settings.desktopCount - 1;
      }
   }

   /* _NET_WM_STATE */
   status = JXGetWindowProperty(display, win, atoms[ATOM_NET_WM_STATE], 0, 32,
                                False, XA_ATOM, &realType, &realFormat,
                                &count, &extra, &temp);
   if(status == Success && realFormat != 0) {
      if(count > 0) {
         state = (Atom*)temp;
         for(x = 0; x < count; x++) {
            if(state[x] == atoms[ATOM_NET_WM_STATE_STICKY]) {
               result.status |= STAT_STICKY;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_SHADED]) {
               result.status |= STAT_SHADED;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_MAXIMIZED_VERT]) {
               result.maxFlags |= MAX_VERT;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_MAXIMIZED_HORZ]) {
               result.maxFlags |= MAX_HORIZ;
            } else if(state[x] == atoms[ATOM_JWM_WM_STATE_MAXIMIZED_TOP]) {
               result.maxFlags |= MAX_TOP;
            } else if(state[x] == atoms[ATOM_JWM_WM_STATE_MAXIMIZED_BOTTOM]) {
               result.maxFlags |= MAX_BOTTOM;
            } else if(state[x] == atoms[ATOM_JWM_WM_STATE_MAXIMIZED_LEFT]) {
               result.maxFlags |= MAX_LEFT;
            } else if(state[x] == atoms[ATOM_JWM_WM_STATE_MAXIMIZED_RIGHT]) {
               result.maxFlags |= MAX_RIGHT;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_FULLSCREEN]) {
               result.status |= STAT_FULLSCREEN;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_HIDDEN]) {
               result.status |= STAT_MINIMIZED;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_SKIP_TASKBAR]) {
               result.status |= STAT_NOLIST;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_SKIP_PAGER]) {
               result.status |= STAT_NOPAGER;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_ABOVE]) {
               result.layer = LAYER_ABOVE;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_BELOW]) {
               result.layer = LAYER_BELOW;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_DEMANDS_ATTENTION]) {
               result.status |= STAT_URGENT;
            }
         }
      }
      if(temp) {
         JXFree(temp);
      }
   }

   /* _NET_WM_WINDOW_TYPE */
   status = JXGetWindowProperty(display, win, atoms[ATOM_NET_WM_WINDOW_TYPE],
                                0, 32, False, XA_ATOM, &realType, &realFormat,
                                &count, &extra, &temp);
   if(status == Success && realFormat != 0) {
      /* Loop until we hit a window type we recognize. */
      state = (Atom*)temp;
      for(x = 0; x < count; x++) {
         if(         state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_NORMAL]) {
            break;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_DESKTOP]) {
            result.defaultLayer  = LAYER_DESKTOP;
            result.border        = BORDER_NONE;
            result.status       |= STAT_STICKY;
            result.status       |= STAT_NOLIST;
            result.status       |= STAT_NOFOCUS;
            break;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_DOCK]) {
            result.border        = BORDER_NONE;
            result.defaultLayer  = LAYER_ABOVE;
            result.status       |= STAT_NOFOCUS;
            break;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_SPLASH]) {
            result.border = BORDER_NONE;
            break;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_DIALOG]) {
            result.border &= ~BORDER_MIN;
            result.border &= ~BORDER_MAX;
            break;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_MENU]) {
            result.border       &= ~BORDER_MAX;
            result.status       |= STAT_NOLIST;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION]) {
            result.border        = BORDER_NONE;
            result.status       |= STAT_NOLIST;
            result.status       |= STAT_NOFOCUS;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_TOOLBAR]) {
            result.border       &= ~BORDER_MAX;
            result.defaultLayer  = LAYER_ABOVE;
            result.status       |= STAT_STICKY;
            result.status       |= STAT_NOLIST;
            result.status       |= STAT_NOFOCUS;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_UTILITY]) {
            result.border       &= ~BORDER_MAX;
            result.status       |= STAT_NOFOCUS;
         } else {
            Debug("Unknown _NET_WM_WINDOW_TYPE: %lu", state[x]);
         }
      }
      if(temp) {
         JXFree(temp);
      }
   }

   /* _NET_WM_USER_TIME_WINDOW */
   if(!GetWindowAtom(win, ATOM_NET_WM_USER_TIME_WINDOW, &utwin)) {
      utwin = win;
   }

   /* _NET_WM_USER_TIME */
   if(GetCardinalAtom(utwin, ATOM_NET_WM_USER_TIME, &card)) {
      if(card == 0) {
         result.status |= STAT_NOFOCUS;
      }
   }

   /* Use the default layer if the layer wasn't set explicitly. */
   if(result.layer == LAYER_NORMAL) {
      result.layer = result.defaultLayer;
   }

   /* Check if this window uses the shape extension. */
   if(CheckShape(win)) {
      result.status |= STAT_SHAPED;
   }

   return result;

}
Пример #17
0
/** Add client specified struts to our list. */
void ReadClientStrut(ClientNode *np)
{

   BoundingBox box;
   int status;
   Atom actualType;
   int actualFormat;
   unsigned long count;
   unsigned long bytesLeft;
   unsigned char *value;
   long *lvalue;
   long leftWidth, rightWidth, topHeight, bottomHeight;
   char updated;

   updated = DoRemoveClientStrut(np);

   box.x = 0;
   box.y = 0;
   box.width = 0;
   box.height = 0;

   /* First try to read _NET_WM_STRUT_PARTIAL */
   /* Format is:
    *   left_width, right_width, top_width, bottom_width,
    *   left_start_y, left_end_y, right_start_y, right_end_y,
    *   top_start_x, top_end_x, bottom_start_x, bottom_end_x
    */
   status = JXGetWindowProperty(display, np->window,
                                atoms[ATOM_NET_WM_STRUT_PARTIAL],
                                0, 12, False, XA_CARDINAL, &actualType,
                                &actualFormat, &count, &bytesLeft, &value);
   if(status == Success && actualFormat != 0) {
      if(count == 12) {

         long leftStart, leftStop;
         long rightStart, rightStop;
         long topStart, topStop;
         long bottomStart, bottomStop;

         lvalue = (long*)value;
         leftWidth      = lvalue[0];
         rightWidth     = lvalue[1];
         topHeight      = lvalue[2];
         bottomHeight   = lvalue[3];
         leftStart      = lvalue[4];
         leftStop       = lvalue[5];
         rightStart     = lvalue[6];
         rightStop      = lvalue[7];
         topStart       = lvalue[8];
         topStop        = lvalue[9];
         bottomStart    = lvalue[10];
         bottomStop     = lvalue[11];

         if(leftWidth > 0) {
            box.x = 0;
            box.y = leftStart;
            box.height = leftStop - leftStart;
            box.width = leftWidth;
            InsertStrut(&box, np);
         }

         if(rightWidth > 0) {
            box.x = rootWidth - rightWidth;
            box.y = rightStart;
            box.height = rightStop - rightStart;
            box.width = rightWidth;
            InsertStrut(&box, np);
         }

         if(topHeight > 0) {
            box.x = topStart;
            box.y = 0;
            box.height = topHeight;
            box.width = topStop - topStart;
            InsertStrut(&box, np);
         }

         if(bottomHeight > 0) {
            box.x = bottomStart;
            box.y = rootHeight - bottomHeight;
            box.width = bottomStop - bottomStart;
            box.height = bottomHeight;
            InsertStrut(&box, np);
         }

      }
      JXFree(value);
      SetWorkarea();
      return;
   }

   /* Next try to read _NET_WM_STRUT */
   /* Format is: left_width, right_width, top_width, bottom_width */
   status = JXGetWindowProperty(display, np->window, atoms[ATOM_NET_WM_STRUT],
                                0, 4, False, XA_CARDINAL, &actualType,
                                &actualFormat, &count, &bytesLeft, &value);
   if(status == Success && actualFormat != 0) {
      if(count == 4) {
         lvalue = (long*)value;
         leftWidth = lvalue[0];
         rightWidth = lvalue[1];
         topHeight = lvalue[2];
         bottomHeight = lvalue[3];

         if(leftWidth > 0) {
            box.x = 0;
            box.y = 0;
            box.width = leftWidth;
            box.height = rootHeight;
            InsertStrut(&box, np);
         }

         if(rightWidth > 0) {
            box.x = rootWidth - rightWidth;
            box.y = 0;
            box.width = rightWidth;
            box.height = rootHeight;
            InsertStrut(&box, np);
         }

         if(topHeight > 0) {
            box.x = 0;
            box.y = 0;
            box.width = rootWidth;
            box.height = topHeight;
            InsertStrut(&box, np);
         }

         if(bottomHeight > 0) {
            box.x = 0;
            box.y = rootHeight - bottomHeight;
            box.width = rootWidth;
            box.height = bottomHeight;
            InsertStrut(&box, np);
         }

      }
      JXFree(value);
      SetWorkarea();
      return;
   }

   /* Struts were removed. */
   if(updated) {
      SetWorkarea();
   }

}
Пример #18
0
/** Remove a client window from management. */
void RemoveClient(ClientNode *np)
{

   ColormapNode *cp;

   Assert(np);
   Assert(np->window != None);

   /* Remove this client from the client list */
   if(np->next) {
      np->next->prev = np->prev;
   } else {
      nodeTail[np->state.layer] = np->prev;
   }
   if(np->prev) {
      np->prev->next = np->next;
   } else {
      nodes[np->state.layer] = np->next;
   }
   clientCount -= 1;
   XDeleteContext(display, np->window, clientContext);
   if(np->parent != None) {
      XDeleteContext(display, np->parent, frameContext);
   }

   if(np->state.status & STAT_URGENT) {
      UnregisterCallback(SignalUrgent, np);
   }

   /* Make sure this client isn't active */
   if(activeClient == np && !shouldExit) {
      FocusNextStacked(np);
   }
   if(activeClient == np) {

      /* Must be the last client. */
      SetWindowAtom(rootWindow, ATOM_NET_ACTIVE_WINDOW, None);
      activeClient = NULL;
      JXSetInputFocus(display, rootWindow, RevertToParent, eventTime);

   }

   /* If the window manager is exiting (ie, not the client), then
    * reparent etc. */
   if(shouldExit && !(np->state.status & STAT_WMDIALOG)) {
      if(np->state.maxFlags) {
         np->x = np->oldx;
         np->y = np->oldy;
         np->width = np->oldWidth;
         np->height = np->oldHeight;
         JXMoveResizeWindow(display, np->window,
                            np->x, np->y, np->width, np->height);
      }
      GravitateClient(np, 1);
      if(!(np->state.status & STAT_MAPPED)
         && (np->state.status & (STAT_MINIMIZED | STAT_SHADED))) {
         JXMapWindow(display, np->window);
      }
      JXUngrabButton(display, AnyButton, AnyModifier, np->window);
      JXReparentWindow(display, np->window, rootWindow, np->x, np->y);
      JXRemoveFromSaveSet(display, np->window);
   }

   /* Destroy the parent */
   if(np->parent) {
      JXDestroyWindow(display, np->parent);
   }

   if(np->name) {
      Release(np->name);
   }
   if(np->instanceName) {
      JXFree(np->instanceName);
   }
   if(np->className) {
      JXFree(np->className);
   }

   RemoveClientFromTaskBar(np);
   RemoveClientStrut(np);

   while(np->colormaps) {
      cp = np->colormaps->next;
      Release(np->colormaps);
      np->colormaps = cp;
   }

   DestroyIcon(np->icon);

   Release(np);

   RequireRestack();

}
Пример #19
0
/** Handle a client message. */
void HandleClientMessage(const XClientMessageEvent *event)
{

   ClientNode *np;
#ifdef DEBUG
   char *atomName;
#endif

   np = FindClientByWindow(event->window);
   if(np) {
      if(event->message_type == atoms[ATOM_WM_CHANGE_STATE]) {

         if(np->controller) {
            (np->controller)(0);
         }

         switch(event->data.l[0]) {
         case WithdrawnState:
            SetClientWithdrawn(np);
            break;
         case IconicState:
            MinimizeClient(np, 1);
            break;
         case NormalState:
            RestoreClient(np, 1);
            break;
         default:
            break;
         }

      } else if(event->message_type == atoms[ATOM_NET_ACTIVE_WINDOW]) {

         RestoreClient(np, 1);
         UnshadeClient(np);
         FocusClient(np);

      } else if(event->message_type == atoms[ATOM_NET_WM_DESKTOP]) {

         if(event->data.l[0] == ~0L) {
            SetClientSticky(np, 1);
         } else {

            if(np->controller) {
               (np->controller)(0);
            }

            if(   event->data.l[0] >= 0
               && event->data.l[0] < (long)settings.desktopCount) {
               np->state.status &= ~STAT_STICKY;
               SetClientDesktop(np, event->data.l[0]);
            }
         }

      } else if(event->message_type == atoms[ATOM_NET_CLOSE_WINDOW]) {

         DeleteClient(np);

      } else if(event->message_type == atoms[ATOM_NET_MOVERESIZE_WINDOW]) {

         HandleNetMoveResize(event, np);

      } else if(event->message_type == atoms[ATOM_NET_WM_MOVERESIZE]) {

         HandleNetWMMoveResize(event, np);

      } else if(event->message_type == atoms[ATOM_NET_RESTACK_WINDOW]) {

         HandleNetRestack(event, np);

      } else if(event->message_type == atoms[ATOM_NET_WM_STATE]) {

         HandleNetWMState(event, np);

      } else {

#ifdef DEBUG
         atomName = JXGetAtomName(display, event->message_type);
         Debug("Unknown ClientMessage to client: %s", atomName);
         JXFree(atomName);
#endif

      }

   } else if(event->window == rootWindow) {

      if(event->message_type == atoms[ATOM_JWM_RESTART]) {
         Restart();
      } else if(event->message_type == atoms[ATOM_JWM_EXIT]) {
         Exit();
      } else if(event->message_type == atoms[ATOM_JWM_RELOAD]) {
         ReloadMenu();
      } else if(event->message_type == atoms[ATOM_NET_CURRENT_DESKTOP]) {
         ChangeDesktop(event->data.l[0]);
      } else if(event->message_type == atoms[ATOM_NET_SHOWING_DESKTOP]) {
         ShowDesktop();
      } else {
#ifdef DEBUG
         atomName = JXGetAtomName(display, event->message_type);
         Debug("Unknown ClientMessage to root: %s", atomName);
         JXFree(atomName);
#endif
      }

   } else if(event->message_type == atoms[ATOM_NET_REQUEST_FRAME_EXTENTS]) {

      HandleFrameExtentsRequest(event);

   } else if(event->message_type == atoms[ATOM_NET_SYSTEM_TRAY_OPCODE]) {

      HandleDockEvent(event);

   } else {
#ifdef DEBUG
         atomName = JXGetAtomName(display, event->message_type);
         Debug("ClientMessage to unknown window (0x%x): %s",
               event->window, atomName);
         JXFree(atomName);
#endif
   }

}