示例#1
0
文件: clientlist.c 项目: mjwhite/jwm
/** Determine if a client is allowed focus. */
char ShouldFocus(const ClientNode *np, char current)
{

   /* Only display clients on the current desktop or clients that are sticky. */
   if(!settings.listAllTasks || current) {
      if(!IsClientOnCurrentDesktop(np)) {
         return 0;
      }
   }

   /* Don't display a client if it doesn't want to be displayed. */
   if(np->state.status & STAT_NOLIST) {
      return 0;
   }

   /* Don't display a client on the tray if it has an owner. */
   if(np->owner != None) {
      return 0;
   }

   if(!(np->state.status & (STAT_MAPPED | STAT_MINIMIZED | STAT_SHADED))) {
      return 0;
   }

   return 1;

}
示例#2
0
文件: taskbar.c 项目: Israel-/jwm
/** Check if all clients in this grou are on the top of their layer. */
char IsGroupOnTop(const TaskEntry *entry)
{
   ClientEntry *cp;
   int layer;

   for(layer = FIRST_LAYER; layer <= LAST_LAYER; layer++) {
      ClientNode *np;
      char foundOther = 0;
      for(np = nodes[layer]; np; np = np->next) {
         char found = 0;
         if(!IsClientOnCurrentDesktop(np)) {
            continue;
         }
         for(cp = entry->clients; cp; cp = cp->next) {
            if(np == cp->client) {
               if(foundOther) {
                  return 0;
               }
               found = 1;
               break;
            }
         }
         foundOther = !found;
      }
   }
   return 1;
}
示例#3
0
文件: taskbar.c 项目: JamesLinus/jwm
/** Draw a specific task bar. */
void Render(const TaskBarType *bp)
{
   TaskEntry *tp;
   char *displayName;
   ButtonNode button;
   int x, y;

   if(JUNLIKELY(shouldExit)) {
      return;
   }

   ClearTrayDrawable(bp->cp);
   if(!taskEntries) {
      UpdateSpecificTray(bp->cp->tray, bp->cp);
      return;
   }

   ResetButton(&button, bp->cp->pixmap);
   button.border = settings.trayDecorations == DECO_MOTIF;
   button.font = FONT_TASKLIST;
   button.height = bp->itemHeight;
   button.width = bp->itemWidth;
   button.text = NULL;

   x = 0;
   y = 0;
   for(tp = taskEntries; tp; tp = tp->next) {

      if(!ShouldShowEntry(tp)) {
         continue;
      }

      /* Check for an active or urgent window and count clients. */
      ClientEntry *cp;
      unsigned clientCount = 0;
      button.type = BUTTON_TASK;
      for(cp = tp->clients; cp; cp = cp->next) {
         if(ShouldFocus(cp->client, 0)) {
            const char flash = (cp->client->state.status & STAT_FLASH) != 0;
            const char active = (cp->client->state.status & STAT_ACTIVE)
               && IsClientOnCurrentDesktop(cp->client);
            if(flash || active) {
               if(button.type == BUTTON_TASK) {
                  button.type = BUTTON_TASK_ACTIVE;
               } else {
                  button.type = BUTTON_TASK;
               }
            }
            clientCount += 1;
         }
      }
      button.x = x;
      button.y = y;
      if(!tp->clients->client->icon) {
         button.icon = GetDefaultIcon();
      } else {
         button.icon = tp->clients->client->icon;
      }
      displayName = NULL;
      if(tp->clients->client->className && settings.groupTasks) {
         if(clientCount != 1) {
            const size_t len = strlen(tp->clients->client->className) + 16;
            displayName = Allocate(len);
            snprintf(displayName, len, "%s (%u)",
                     tp->clients->client->className, clientCount);
            button.text = displayName;
         } else {
            button.text = tp->clients->client->className;
         }
      } else {
         button.text = tp->clients->client->name;
      }
      DrawButton(&button);
      if(displayName) {
         Release(displayName);
      }

      if(bp->layout == LAYOUT_HORIZONTAL) {
         x += bp->itemWidth;
      } else {
         y += bp->itemHeight;
      }
   }

   UpdateSpecificTray(bp->cp->tray, bp->cp);

}
示例#4
0
文件: taskbar.c 项目: JamesLinus/jwm
/** Raise all clients in a group and focus the top-most. */
void FocusGroup(const TaskEntry *tp)
{
   const char *className = tp->clients->client->className;
   ClientNode **toRestore;
   const ClientEntry *cp;
   unsigned restoreCount;
   int i;
   char shouldSwitch;

   /* If there is no class name, then there will only be one client. */
   if(!className || !settings.groupTasks) {
      if(!(tp->clients->client->state.status & STAT_STICKY)) {
         ChangeDesktop(tp->clients->client->state.desktop);
      }
      RestoreClient(tp->clients->client, 1);
      FocusClient(tp->clients->client);
      return;
   }

   /* If there is a client in the group on this desktop,
    * then we remain on the same desktop. */
   shouldSwitch = 1;
   for(cp = tp->clients; cp; cp = cp->next) {
      if(IsClientOnCurrentDesktop(cp->client)) {
         shouldSwitch = 0;
         break;
      }
   }

   /* Switch to the desktop of the top-most client in the group. */
   if(shouldSwitch) {
      for(i = 0; i < LAYER_COUNT; i++) {
         ClientNode *np;
         for(np = nodes[i]; np; np = np->next) {
            if(np->className && !strcmp(np->className, className)) {
               if(ShouldFocus(np, 0)) {
                  if(!(np->state.status & STAT_STICKY)) {
                     ChangeDesktop(np->state.desktop);
                  }
                  break;
               }
            }
         }
      }
   }

   /* Build up the list of clients to restore in correct order. */
   toRestore = AllocateStack(sizeof(ClientNode*) * clientCount);
   restoreCount = 0;
   for(i = 0; i < LAYER_COUNT; i++) {
      ClientNode *np;
      for(np = nodes[i]; np; np = np->next) {
         if(!ShouldFocus(np, 1)) {
            continue;
         }
         if(np->className && !strcmp(np->className, className)) {
            toRestore[restoreCount] = np;
            restoreCount += 1;
         }
      }
   }
   Assert(restoreCount <= clientCount);
   for(i = restoreCount - 1; i >= 0; i--) {
      RestoreClient(toRestore[i], 1);
   }
   for(i = 0; i < restoreCount; i++) {
      if(toRestore[i]->state.status & (STAT_CANFOCUS | STAT_TAKEFOCUS)) {
         FocusClient(toRestore[i]);
         break;
      }
   }
   ReleaseStack(toRestore);
}
示例#5
0
文件: taskbar.c 项目: JamesLinus/jwm
/** Process a task list button event. */
void ProcessTaskButtonEvent(TrayComponentType *cp, int x, int y, int mask)
{

   TaskBarType *bar = (TaskBarType*)cp->object;
   TaskEntry *entry = GetEntry(bar, x, y);

   if(entry) {
      ClientEntry *cp;
      ClientNode *focused = NULL;
      char onTop = 0;
      char hasActive = 0;

      switch(mask) {
      case Button1:  /* Raise or minimize items in this group. */
         for(cp = entry->clients; cp; cp = cp->next) {
            int layer;
            char foundTop = 0;
            if(cp->client->state.status & STAT_MINIMIZED) {
               continue;
            } else if(!ShouldFocus(cp->client, 0)) {
               continue;
            }
            for(layer = LAST_LAYER; layer >= FIRST_LAYER; layer--) {
               ClientNode *np;
               for(np = nodes[layer]; np; np = np->next) {
                  if(np->state.status & STAT_MINIMIZED) {
                     continue;
                  } else if(!ShouldFocus(np, 0)) {
                     continue;
                  }
                  if(np == cp->client) {
                     const char isActive = (np->state.status & STAT_ACTIVE)
                                         && IsClientOnCurrentDesktop(np);
                     onTop = onTop || !foundTop;
                     if(isActive) {
                        focused = np;
                     }
                     if(!(cp->client->state.status
                           & (STAT_CANFOCUS | STAT_TAKEFOCUS))
                        || isActive) {
                        hasActive = 1;
                     }
                  }
                  if(hasActive && onTop) {
                     goto FoundActiveAndTop;
                  }
                  foundTop = 1;
               }
            }
         }
FoundActiveAndTop:
         if(hasActive && onTop) {
            ClientNode *nextClient = NULL;
            int i;

            /* Try to find a client on a different desktop. */
            for(i = 0; i < settings.desktopCount - 1; i++) {
               const int target = (currentDesktop + i + 1)
                                % settings.desktopCount;
               for(cp = entry->clients; cp; cp = cp->next) {
                  ClientNode *np = cp->client;
                  if(!ShouldFocus(np, 0)) {
                     continue;
                  } else if(np->state.status & STAT_STICKY) {
                     continue;
                  } else if(np->state.desktop == target) {
                     if(!nextClient || np->state.status & STAT_ACTIVE) {
                        nextClient = np;
                     }
                  }
               }
               if(nextClient) {
                  break;
               }
            }
            /* Focus the next client or minimize the current group. */
            if(nextClient) {
               ChangeDesktop(nextClient->state.desktop);
               RestoreClient(nextClient, 1);
            } else {
               MinimizeGroup(entry);
            }
         } else {
            FocusGroup(entry);
            if(focused) {
               FocusClient(focused);
            }
         }
         break;
      case Button3:
         ShowClientList(bar, entry);
         break;
      case Button4:
         FocusPrevious();
         break;
      case Button5:
         FocusNext();
         break;
      default:
         break;
      }
   }

}