Esempio n. 1
0
/** Change to the specified desktop. */
void ChangeDesktop(unsigned int desktop) {

   ClientNode *np;
   unsigned int x;

   if(desktop >= desktopCount) {
      return;
   }

   if(currentDesktop == desktop && !initializing) {
      return;
   }

   /* Hide clients from the old desktop.
    * Note that we show clients in a separate loop to prevent an issue
    * with clients losing focus.
    */
   for(x = 0; x < LAYER_COUNT; x++) {
      for(np = nodes[x]; np; np = np->next) {
         if(np->state.status & STAT_STICKY) {
            continue;
         }
         if(np->state.desktop == currentDesktop) {
            HideClient(np);
         }
      }
   }

   /* Show clients on the new desktop. */
   for(x = 0; x < LAYER_COUNT; x++) {
      for(np = nodes[x]; np; np = np->next) {
         if(np->state.status & STAT_STICKY) {
            continue;
         }
         if(np->state.desktop == desktop) {
            ShowClient(np);
         }
      }
   }

   currentDesktop = desktop;

   SetCardinalAtom(rootWindow, ATOM_NET_CURRENT_DESKTOP, currentDesktop);
   SetCardinalAtom(rootWindow, ATOM_WIN_WORKSPACE, currentDesktop);

   RestackClients();

   UpdatePager();
   UpdateTaskBar();

   LoadBackground(desktop);

}
Esempio n. 2
0
/** Set a client's desktop. This will update transients. */
void SetClientDesktop(ClientNode *np, unsigned int desktop)
{

   ClientNode *tp;

   Assert(np);

   if(JUNLIKELY(desktop >= settings.desktopCount)) {
      return;
   }

   if(!(np->state.status & STAT_STICKY)) {
      int x;
      for(x = 0; x < LAYER_COUNT; x++) {
         for(tp = nodes[x]; tp; tp = tp->next) {
            if(tp == np || tp->owner == np->window) {

               tp->state.desktop = desktop;

               if(desktop == currentDesktop) {
                  ShowClient(tp);
               } else {
                  HideClient(tp);
               }

               SetCardinalAtom(tp->window, ATOM_NET_WM_DESKTOP,
                               tp->state.desktop);
            }
         }
      }
      RequirePagerUpdate();
      RequireTaskUpdate();
   }

}
Esempio n. 3
0
/** Toggle the "show desktop" state. */
void ShowDesktop() {

   ClientNode *np;
   int layer;

   for(layer = 0; layer < LAYER_COUNT; layer++) {
      for(np = nodes[layer]; np; np = np->next) {

         /* Skip "nolist" items. */
         if(np->state.status & STAT_NOLIST) {
            continue;
         }

         if(showingDesktop) {
            if(np->state.status & STAT_SDESKTOP) {
               RestoreClient(np, 0);
            }
         } else if(np->state.desktop == currentDesktop
             || (np->state.status & STAT_STICKY)) {
            if(np->state.status & (STAT_MAPPED | STAT_SHADED)) {
               MinimizeClient(np);
               np->state.status |= STAT_SDESKTOP;
            }
         }
      }
   }

   showingDesktop = !showingDesktop;
   SetCardinalAtom(rootWindow, ATOM_NET_SHOWING_DESKTOP, showingDesktop);

   RestackClients();

}
Esempio n. 4
0
File: hint.c Progetto: Miteam/jwm
/** Determine the current desktop. */
void ReadCurrentDesktop(void)
{
   unsigned long temp;
   currentDesktop = 0;
   if(GetCardinalAtom(rootWindow, ATOM_NET_CURRENT_DESKTOP, &temp)) {
      ChangeDesktop(temp);
   } else {
      SetCardinalAtom(rootWindow, ATOM_NET_CURRENT_DESKTOP, currentDesktop);
   }
}
Esempio n. 5
0
/** Set a client's sticky status. This will update transients. */
void SetClientSticky(ClientNode *np, char isSticky)
{

   ClientNode *tp;
   int x;
   char old;

   Assert(np);

   /* Get the old sticky status. */
   if(np->state.status & STAT_STICKY) {
      old = 1;
   } else {
      old = 0;
   }

   if(isSticky && !old) {

      /* Change from non-sticky to sticky. */

      for(x = 0; x < LAYER_COUNT; x++) {
         for(tp = nodes[x]; tp; tp = tp->next) {
            if(tp == np || tp->owner == np->window) {
               tp->state.status |= STAT_STICKY;
               SetCardinalAtom(tp->window, ATOM_NET_WM_DESKTOP, ~0UL);
               WriteState(tp);
            }
         }
      }

   } else if(!isSticky && old) {

      /* Change from sticky to non-sticky. */

      for(x = 0; x < LAYER_COUNT; x++) {
         for(tp = nodes[x]; tp; tp = tp->next) {
            if(tp == np || tp->owner == np->window) {
               tp->state.status &= ~STAT_STICKY;
               WriteState(tp);
            }
         }
      }

      /* Since this client is no longer sticky, we need to assign
       * a desktop. Here we use the current desktop.
       * Note that SetClientDesktop updates transients (which is good).
       */
      SetClientDesktop(np, currentDesktop);

   }

}
Esempio n. 6
0
/** Initialize a dock component. */
void Create(TrayComponentType *cp)
{

   XEvent event;

   Assert(cp);

   /* Map the dock window. */
   if(cp->window != None) {
      JXResizeWindow(display, cp->window, cp->width, cp->height);
      JXMapRaised(display, cp->window);
   }

   /* Set the orientation atom. */
   SetCardinalAtom(dock->cp->window, ATOM_NET_SYSTEM_TRAY_ORIENTATION,
                   orientation);

   /* Get the selection if we don't already own it.
    * If we did already own it, getting it again would cause problems
    * with some clients due to the way restarts are handled.
    */
   if(!owner) {

      owner = 1;
      JXSetSelectionOwner(display, dockAtom, dock->cp->window, CurrentTime);
      if(JUNLIKELY(JXGetSelectionOwner(display, dockAtom)
                   != dock->cp->window)) {

         owner = 0;
         Warning(_("could not acquire system tray selection"));

      } else {

         memset(&event, 0, sizeof(event));
         event.xclient.type = ClientMessage;
         event.xclient.window = rootWindow;
         event.xclient.message_type = atoms[ATOM_MANAGER];
         event.xclient.format = 32;
         event.xclient.data.l[0] = CurrentTime;
         event.xclient.data.l[1] = dockAtom;
         event.xclient.data.l[2] = dock->cp->window;
         event.xclient.data.l[3] = 0;
         event.xclient.data.l[4] = 0;

         JXSendEvent(display, rootWindow, False, StructureNotifyMask, &event);

      }

   }

}
Esempio n. 7
0
File: hint.c Progetto: Miteam/jwm
/** Set the opacity of a client. */
void SetOpacity(ClientNode *np, unsigned int opacity, char force)
{
   Window w;
   if(np->state.opacity == opacity && !force) {
      return;
   }

   w = np->parent != None ? np->parent : np->window;
   np->state.opacity = opacity;
   if(opacity == 0xFFFFFFFF) {
      JXDeleteProperty(display, w, atoms[ATOM_NET_WM_WINDOW_OPACITY]);
   } else {
      SetCardinalAtom(w, ATOM_NET_WM_WINDOW_OPACITY, opacity);
   }
}
Esempio n. 8
0
File: hint.c Progetto: Miteam/jwm
/** Set root hints and intern atoms. */
void StartupHints(void)
{

   unsigned long *array;
   char *data;
   Atom *supported;
   Window win;
   unsigned int x;
   unsigned int count;

   /* Determine how much space we will need on the stack and allocate it. */
   count = 0;
   for(x = 0; x < settings.desktopCount; x++) {
      count += strlen(GetDesktopName(x)) + 1;
   }
   if(count < 2 * sizeof(unsigned long)) {
      count = 2 * sizeof(unsigned long);
   }
   if(count < ATOM_COUNT * sizeof(Atom)) {
      count = ATOM_COUNT * sizeof(Atom);
   }
   data = AllocateStack(count);
   array = (unsigned long*)data;
   supported = (Atom*)data;

   /* Intern the atoms */
   for(x = 0; x < ATOM_COUNT; x++) {
      *atomList[x].atom = JXInternAtom(display, atomList[x].name, False);
   }

   /* _NET_SUPPORTED */
   for(x = FIRST_NET_ATOM; x <= LAST_NET_ATOM; x++) {
      supported[x - FIRST_NET_ATOM] = atoms[x];
   }
   JXChangeProperty(display, rootWindow, atoms[ATOM_NET_SUPPORTED],
                    XA_ATOM, 32, PropModeReplace, (unsigned char*)supported,
                    LAST_NET_ATOM - FIRST_NET_ATOM + 1);

   /* _NET_NUMBER_OF_DESKTOPS */
   SetCardinalAtom(rootWindow, ATOM_NET_NUMBER_OF_DESKTOPS,
                   settings.desktopCount);

   /* _NET_DESKTOP_NAMES */
   count = 0;
   for(x = 0; x < settings.desktopCount; x++) {
      const char *name = GetDesktopName(x);
      const unsigned len = strlen(name);
      memcpy(&data[count], name, len + 1);
      count += len + 1;
   }
   JXChangeProperty(display, rootWindow, atoms[ATOM_NET_DESKTOP_NAMES],
                    atoms[ATOM_UTF8_STRING], 8, PropModeReplace,
                    (unsigned char*)data, count);

   /* _NET_DESKTOP_GEOMETRY */
   array[0] = rootWidth;
   array[1] = rootHeight;
   JXChangeProperty(display, rootWindow, atoms[ATOM_NET_DESKTOP_GEOMETRY],
                    XA_CARDINAL, 32, PropModeReplace,
                    (unsigned char*)array, 2);

   /* _NET_DESKTOP_VIEWPORT */
   array[0] = 0;
   array[1] = 0;
   JXChangeProperty(display, rootWindow, atoms[ATOM_NET_DESKTOP_VIEWPORT],
                    XA_CARDINAL, 32, PropModeReplace,
                    (unsigned char*)array, 2);

   /* _NET_WM_NAME */
   win = supportingWindow;
   JXChangeProperty(display, win, atoms[ATOM_NET_WM_NAME],
                    atoms[ATOM_UTF8_STRING], 8, PropModeReplace,
                    (unsigned char*)"JWM", 3);

   /* _NET_WM_PID */
   array[0] = getpid();
   JXChangeProperty(display, win, atoms[ATOM_NET_WM_PID],
                    XA_CARDINAL, 32, PropModeReplace,
                    (unsigned char*)array, 1);

   /* _NET_SUPPORTING_WM_CHECK */
   SetWindowAtom(rootWindow, ATOM_NET_SUPPORTING_WM_CHECK, win);
   SetWindowAtom(win, ATOM_NET_SUPPORTING_WM_CHECK, win);

   ReleaseStack(data);

}
Esempio n. 9
0
/** Add a window to management. */
ClientNode *AddClientWindow(Window w, char alreadyMapped, char notOwner)
{

   XWindowAttributes attr;
   ClientNode *np;

   Assert(w != None);

   /* Get window attributes. */
   if(JXGetWindowAttributes(display, w, &attr) == 0) {
      return NULL;
   }

   /* Determine if we should care about this window. */
   if(attr.override_redirect == True) {
      return NULL;
   }
   if(attr.class == InputOnly) {
      return NULL;
   }

   /* Prepare a client node for this window. */
   np = Allocate(sizeof(ClientNode));
   memset(np, 0, sizeof(ClientNode));

   np->window = w;
   np->owner = None;
   np->state.desktop = currentDesktop;

   np->x = attr.x;
   np->y = attr.y;
   np->width = attr.width;
   np->height = attr.height;
   np->cmap = attr.colormap;
   np->state.status = STAT_NONE;
   np->state.maxFlags = MAX_NONE;
   np->state.layer = LAYER_NORMAL;
   np->state.defaultLayer = LAYER_NORMAL;

   np->state.border = BORDER_DEFAULT;
   np->borderAction = BA_NONE;

   ReadClientInfo(np, alreadyMapped);

   if(!notOwner) {
      np->state.border = BORDER_OUTLINE | BORDER_TITLE | BORDER_MOVE;
      np->state.status |= STAT_WMDIALOG | STAT_STICKY;
      np->state.layer = LAYER_ABOVE;
      np->state.defaultLayer = LAYER_ABOVE;
   }

   ApplyGroups(np);
   if(np->icon == NULL) {
      LoadIcon(np);
   }

   /* We now know the layer, so insert */
   np->prev = NULL;
   np->next = nodes[np->state.layer];
   if(np->next) {
      np->next->prev = np;
   } else {
      nodeTail[np->state.layer] = np;
   }
   nodes[np->state.layer] = np;

   SetDefaultCursor(np->window);
   ReparentClient(np, notOwner);
   PlaceClient(np, alreadyMapped);

   if(!((np->state.status & STAT_FULLSCREEN) || np->state.maxFlags)) {
      int north, south, east, west;
      GetBorderSize(&np->state, &north, &south, &east, &west);
      if(np->parent != None) {
         JXMoveResizeWindow(display, np->parent, np->x - west, np->y - north,
                            np->width + east + west,
                            np->height + north + south);
         JXMoveResizeWindow(display, np->window, west, north,
                            np->width, np->height);
      } else {
         JXMoveResizeWindow(display, np->window, np->x, np->y,
                            np->width, np->height);
      }
   }

   /* If one of these fails we are SOL, so who cares. */
   XSaveContext(display, np->window, clientContext, (void*)np);
   if(np->parent != None) {
      XSaveContext(display, np->parent, frameContext, (void*)np);
   }

   if(np->state.status & STAT_MAPPED) {
      JXMapWindow(display, np->window);
      if(np->parent != None) {
         JXMapWindow(display, np->parent);
      }
   }

   clientCount += 1;

   if(!alreadyMapped) {
      RaiseClient(np);
   }

   if(np->state.status & STAT_OPACITY) {
      SetOpacity(np, np->state.opacity, 1);
   } else {
      SetOpacity(np, settings.inactiveClientOpacity, 1);
   }
   if(np->state.status & STAT_STICKY) {
      SetCardinalAtom(np->window, ATOM_NET_WM_DESKTOP, ~0UL);
   } else {
      SetCardinalAtom(np->window, ATOM_NET_WM_DESKTOP, np->state.desktop);
   }

   /* Shade the client if requested. */
   if(np->state.status & STAT_SHADED) {
      np->state.status &= ~STAT_SHADED;
      ShadeClient(np);
   }

   /* Minimize the client if requested. */
   if(np->state.status & STAT_MINIMIZED) {
      np->state.status &= ~STAT_MINIMIZED;
      MinimizeClient(np, 0);
   }

   /* Maximize the client if requested. */
   if(np->state.maxFlags) {
      const MaxFlags flags = np->state.maxFlags;
      np->state.maxFlags = MAX_NONE;
      MaximizeClient(np, flags);
   }

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

   /* Update task bars. */
   AddClientToTaskBar(np);

   /* Make sure we're still in sync */
   WriteState(np);
   SendConfigureEvent(np);

   /* Hide the client if we're not on the right desktop. */
   if(np->state.desktop != currentDesktop
      && !(np->state.status & STAT_STICKY)) {
      HideClient(np);
   }

   ReadClientStrut(np);

   /* Focus transients if their parent has focus. */
   if(np->owner != None) {
      if(activeClient && np->owner == activeClient->window) {
         FocusClient(np);
      }
   }

   /* Make the client fullscreen if requested. */
   if(np->state.status & STAT_FULLSCREEN) {
      np->state.status &= ~STAT_FULLSCREEN;
      SetClientFullScreen(np, 1);
   }
   ResetBorder(np);

   return np;

}