Example #1
0
/** Window menu action callback. */
void RunWindowCommand(const MenuAction *action)
{

   switch(action->type) {
   case MA_STICK:
      if(client->state.status & STAT_STICKY) {
         SetClientSticky(client, 0);
      } else {
         SetClientSticky(client, 1);
      }
      break;
   case MA_MAXIMIZE:
      if(client->state.maxFlags) {
         MaximizeClient(client, MAX_NONE);
      } else {
         MaximizeClient(client, MAX_VERT | MAX_HORIZ);
      }
      break;
   case MA_MAXIMIZE_H:
      MaximizeClient(client, MAX_HORIZ);
      break;
   case MA_MAXIMIZE_V:
      MaximizeClient(client, MAX_VERT);
      break;
   case MA_MINIMIZE:
      MinimizeClient(client, 1);
      break;
   case MA_RESTORE:
      RestoreClient(client, 1);
      break;
   case MA_CLOSE:
      DeleteClient(client);
      break;
   case MA_SENDTO:
   case MA_DESKTOP:
      SetClientDesktop(client, action->data.i);
      break;
   case MA_SHADE:
      if(client->state.status & STAT_SHADED) {
         UnshadeClient(client);
      } else {
         ShadeClient(client);
      }
      break;
   case MA_MOVE:
      MoveClientKeyboard(client);
      break;
   case MA_RESIZE:
      ResizeClientKeyboard(client);
      break;
   case MA_KILL:
      KillClient(client);
      break;
   case MA_LAYER:
      SetClientLayer(client, action->data.i);
      break;
   default:
      Debug("unknown window command: %d", action->type);
      break;
   }

}
Example #2
0
/** Window menu action callback. */
void RunWindowCommand(MenuAction *action, unsigned button)
{
   ClientNode *client = action->context;
   switch(action->type) {
   case MA_STICK:
      if(client->state.status & STAT_STICKY) {
         SetClientSticky(client, 0);
      } else {
         SetClientSticky(client, 1);
      }
      break;
   case MA_MAXIMIZE:
      if((client->state.maxFlags & MAX_HORIZ)
         && (client->state.maxFlags & MAX_VERT)
         && !(client->state.status & STAT_MINIMIZED)) {
         MaximizeClient(client, MAX_NONE);
      } else {
         MaximizeClient(client, MAX_VERT | MAX_HORIZ);
      }
      break;
   case MA_MAXIMIZE_H:
      if((client->state.maxFlags & MAX_HORIZ)
         && !(client->state.maxFlags & MAX_VERT)
         && !(client->state.status & STAT_MINIMIZED)) {
         MaximizeClient(client, MAX_NONE);
      } else {
         MaximizeClient(client, MAX_HORIZ);
      }
      break;
   case MA_MAXIMIZE_V:
      if((client->state.maxFlags & MAX_VERT)
         && !(client->state.maxFlags & MAX_HORIZ)
         && !(client->state.status & STAT_MINIMIZED)) {
         MaximizeClient(client, MAX_NONE);
      } else {
         MaximizeClient(client, MAX_VERT);
      }
      break;
   case MA_MINIMIZE:
      MinimizeClient(client, 1);
      break;
   case MA_RESTORE:
      RestoreClient(client, 1);
      break;
   case MA_CLOSE:
      DeleteClient(client);
      break;
   case MA_SENDTO:
   case MA_DESKTOP:
      SetClientDesktop(client, action->value);
      break;
   case MA_SHADE:
      if(client->state.status & STAT_SHADED) {
         UnshadeClient(client);
      } else {
         ShadeClient(client);
      }
      break;
   case MA_MOVE:
      MoveClientKeyboard(client);
      break;
   case MA_RESIZE:
      ResizeClientKeyboard(client);
      break;
   case MA_KILL:
      KillClient(client);
      break;
   case MA_LAYER:
      SetClientLayer(client, action->value);
      break;
   default:
      break;
   }

}
Example #3
0
/** Handle a _NET_WM_STATE request. */
void HandleNetWMState(const XClientMessageEvent *event, ClientNode *np)
{

   unsigned int x;
   MaxFlags maxFlags;
   char actionStick;
   char actionShade;
   char actionFullScreen;
   char actionMinimize;
   char actionNolist;
   char actionNopager;
   char actionBelow;
   char actionAbove;

   /* Up to two actions to be applied together. */
   maxFlags = MAX_NONE;
   actionStick = 0;
   actionShade = 0;
   actionFullScreen = 0;
   actionMinimize = 0;
   actionNolist = 0;
   actionNopager = 0;
   actionBelow = 0;
   actionAbove = 0;

   for(x = 1; x <= 2; x++) {
      if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_STICKY]) {
         actionStick = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_MAXIMIZED_VERT]) {
         maxFlags |= MAX_VERT;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_MAXIMIZED_HORZ]) {
         maxFlags |= MAX_HORIZ;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_SHADED]) {
         actionShade = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_FULLSCREEN]) {
         actionFullScreen = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_HIDDEN]) {
         actionMinimize = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_SKIP_TASKBAR]) {
         actionNolist = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_SKIP_PAGER]) {
         actionNopager = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_BELOW]) {
         actionBelow = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_ABOVE]) {
         actionAbove = 1;
      }
   }

   switch(event->data.l[0]) {
   case 0: /* Remove */
      if(actionStick) {
         SetClientSticky(np, 0);
      }
      if(maxFlags != MAX_NONE && np->state.maxFlags) {
         MaximizeClient(np, np->state.maxFlags & ~maxFlags);
      }
      if(actionShade) {
         UnshadeClient(np);
      }
      if(actionFullScreen) {
         SetClientFullScreen(np, 0);
      }
      if(actionMinimize) {
         RestoreClient(np, 0);
      }
      if(actionNolist) {
         np->state.status &= ~STAT_NOLIST;
         RequireTaskUpdate();
      }
      if(actionNopager) {
         np->state.status &= ~STAT_NOPAGER;
         RequirePagerUpdate();
      }
      if(actionBelow && np->state.layer == LAYER_BELOW) {
         SetClientLayer(np, np->state.defaultLayer);
      }
      if(actionAbove && np->state.layer == LAYER_ABOVE) {
         SetClientLayer(np, np->state.defaultLayer);
      }
      break;
   case 1: /* Add */
      if(actionStick) {
         SetClientSticky(np, 1);
      }
      if(maxFlags != MAX_NONE) {
         MaximizeClient(np, np->state.maxFlags | maxFlags);
      }
      if(actionShade) {
         ShadeClient(np);
      }
      if(actionFullScreen) {
         SetClientFullScreen(np, 1);
      }
      if(actionMinimize) {
         MinimizeClient(np, 1);
      }
      if(actionNolist) {
         np->state.status |= STAT_NOLIST;
         RequireTaskUpdate();
      }
      if(actionNopager) {
         np->state.status |= STAT_NOPAGER;
         RequirePagerUpdate();
      }
      if(actionBelow) {
         SetClientLayer(np, LAYER_BELOW);
      }
      if(actionAbove) {
         SetClientLayer(np, LAYER_ABOVE);
      }
      break;
   case 2: /* Toggle */
      if(actionStick) {
         if(np->state.status & STAT_STICKY) {
            SetClientSticky(np, 0);
         } else {
            SetClientSticky(np, 1);
         }
      }
      if(maxFlags) {
         MaximizeClient(np, np->state.maxFlags ^ maxFlags);
      }
      if(actionShade) {
         if(np->state.status & STAT_SHADED) {
            UnshadeClient(np);
         } else {
            ShadeClient(np);
         }
      }
      if(actionFullScreen) {
         if(np->state.status & STAT_FULLSCREEN) {
            SetClientFullScreen(np, 0);
         } else {
            SetClientFullScreen(np, 1);
         }
      }
      if(actionBelow) {
         if(np->state.layer == LAYER_BELOW) {
            SetClientLayer(np, np->state.defaultLayer);
         } else {
            SetClientLayer(np, LAYER_BELOW);
         }
      }
      if(actionAbove) {
         if(np->state.layer == LAYER_ABOVE) {
            SetClientLayer(np, np->state.defaultLayer);
         } else {
            SetClientLayer(np, LAYER_ABOVE);
         }
      }
      /* Note that we don't handle toggling of hidden per EWMH
       * recommendations. */
      if(actionNolist) {
         np->state.status ^= STAT_NOLIST;
         RequireTaskUpdate();
      }
      if(actionNopager) {
         np->state.status ^= STAT_NOPAGER;
         RequirePagerUpdate();
      }
      break;
   default:
      Debug("bad _NET_WM_STATE action: %ld", event->data.l[0]);
      break;
   }

   /* Update _NET_WM_STATE if needed.
    * The state update is handled elsewhere for the other actions.
    */
   if(actionNolist | actionNopager | actionAbove | actionBelow) {
      WriteState(np);
   }

}
Example #4
0
/** Apply a group to a client. */
void ApplyGroup(const GroupType *gp, ClientNode *np) {

    OptionListType *lp;
    unsigned int temp;
    float tempf;

    Assert(gp);
    Assert(np);

    for(lp = gp->options; lp; lp = lp->next) {
        switch(lp->option) {
        case OPTION_STICKY:
            np->state.status |= STAT_STICKY;
            break;
        case OPTION_NOLIST:
            np->state.status |= STAT_NOLIST;
            break;
        case OPTION_BORDER:
            np->state.border |= BORDER_OUTLINE;
            break;
        case OPTION_NOBORDER:
            np->state.border &= ~BORDER_OUTLINE;
            break;
        case OPTION_TITLE:
            np->state.border |= BORDER_TITLE;
            break;
        case OPTION_NOTITLE:
            np->state.border &= ~BORDER_TITLE;
            break;
        case OPTION_LAYER:
            temp = atoi(lp->value);
            if(temp <= LAYER_COUNT) {
                SetClientLayer(np, temp);
            } else {
                Warning("invalid group layer: %s", lp->value);
            }
            break;
        case OPTION_DESKTOP:
            temp = atoi(lp->value);
            if(temp >= 1 && temp <= desktopCount) {
                np->state.desktop = temp - 1;
            } else {
                Warning("invalid group desktop: %s", lp->value);
            }
            break;
        case OPTION_ICON:
            DestroyIcon(np->icon);
            np->icon = LoadNamedIcon(lp->value);
            break;
        case OPTION_PIGNORE:
            np->state.status |= STAT_PIGNORE;
            break;
        case OPTION_MAXIMIZED:
            np->state.status |= STAT_HMAX | STAT_VMAX;
            break;
        case OPTION_MINIMIZED:
            np->state.status |= STAT_MINIMIZED;
            break;
        case OPTION_SHADED:
            np->state.status |= STAT_SHADED;
            break;
        case OPTION_OPACITY:
            tempf = atof(lp->value);
            if(tempf > 0.0 && tempf <= 1.0) {
                np->state.opacity = (unsigned int)(tempf * UINT_MAX);
                np->state.status |= STAT_OPACITY;
            } else {
                Warning("invalid group opacity: %s", lp->value);
            }
            break;
        case OPTION_MAX_V:
            np->state.border &= ~BORDER_MAX_H;
            break;
        case OPTION_MAX_H:
            np->state.border &= ~BORDER_MAX_V;
            break;
        case OPTION_NOFOCUS:
            np->state.status |= STAT_NOFOCUS;
            break;
        default:
            Debug("invalid option: %d", lp->option);
            break;
        }
    }

}
Example #5
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);

   }

}