Example #1
0
File: place.c Project: KarlGodt/jwm
/** Set _NET_WORKAREA. */
void SetWorkarea(void)
{
   BoundingBox box;
   unsigned long *array;
   unsigned int count;
   int x;

   count = 4 * settings.desktopCount * sizeof(unsigned long);
   array = (unsigned long*)AllocateStack(count);

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

   SubtractTrayBounds(GetTrays(), &box, LAYER_NORMAL);
   SubtractStrutBounds(&box, NULL);

   for(x = 0; x < settings.desktopCount; x++) {
      array[x * 4 + 0] = box.x;
      array[x * 4 + 1] = box.y;
      array[x * 4 + 2] = box.width;
      array[x * 4 + 3] = box.height;
   }
   JXChangeProperty(display, rootWindow, atoms[ATOM_NET_WORKAREA],
                    XA_CARDINAL, 32, PropModeReplace,
                    (unsigned char*)array, settings.desktopCount * 4);

   ReleaseStack(array);

}
Example #2
0
File: place.c Project: KarlGodt/jwm
/** Constrain the position of a client. */
void ConstrainPosition(ClientNode *np)
{

   BoundingBox box;
   int north, south, east, west;

   /* Get the bounds for placement. */
   box.x = 0;
   box.y = 0;
   box.width = rootWidth;
   box.height = rootHeight;
   SubtractTrayBounds(GetTrays(), &box, np->state.layer);
   SubtractStrutBounds(&box, np);

   /* Fix the position. */
   GetBorderSize(&np->state, &north, &south, &east, &west);
   if(np->x + np->width + east + west > box.x + box.width) {
      np->x = box.x + box.width - np->width - east;
   }
   if(np->y + np->height + north + south > box.y + box.height) {
      np->y = box.y + box.height - np->height - south;
   }
   if(np->x < box.x + west) {
      np->x = box.x + west;
   }
   if(np->y < box.y + north) {
      np->y = box.y + north;
   }

}
Example #3
0
File: place.c Project: KarlGodt/jwm
/** Place a client on the screen. */
void PlaceClient(ClientNode *np, char alreadyMapped)
{

   BoundingBox box;
   const ScreenType *sp;

   Assert(np);

   if(alreadyMapped || (!(np->state.status & STAT_PIGNORE)
                        && (np->sizeFlags & (PPosition | USPosition)))) {

      GravitateClient(np, 0);
      if(!alreadyMapped) {
         ConstrainSize(np);
         ConstrainPosition(np);
      }

   } else {

      sp = GetMouseScreen();
      GetScreenBounds(sp, &box);
      SubtractTrayBounds(GetTrays(), &box, np->state.layer);
      SubtractStrutBounds(&box, np);

      /* If tiled is specified, first attempt to use tiled placement. */
      if(np->state.status & STAT_TILED) {
         if(TileClient(&box, np)) {
            return;
         }
      }

      /* Either tiled placement failed or was not specified. */
      if(np->state.status & STAT_CENTERED) {
         CenterClient(&box, np);
      } else {
         CascadeClient(&box, np);
      }

   }

}
Example #4
0
File: key.c Project: kuailexs/jwm
/** Startup key bindings. */
void StartupKeys(void)
{

    XModifierKeymap *modmap;
    KeyNode *np;
    TrayType *tp;
    int x;

    /* Get the keys that we don't care about (num lock, etc). */
    modmap = JXGetModifierMapping(display);
    for(x = 0; x < sizeof(lockMods) / sizeof(lockMods[0]); x++) {
        lockMods[x].mask = GetModifierMask(modmap, lockMods[x].symbol);
        lockMask |= lockMods[x].mask;
    }
    JXFreeModifiermap(modmap);

    /* Look up and grab the keys. */
    for(np = bindings; np; np = np->next) {

        /* Determine the key code. */
        if(!np->code) {
            np->code = JXKeysymToKeycode(display, np->symbol);
        }

        /* Grab the key if needed. */
        if(ShouldGrab(np->key)) {

            /* Grab on the root. */
            GrabKey(np, rootWindow);

            /* Grab on the trays. */
            for(tp = GetTrays(); tp; tp = tp->next) {
                GrabKey(np, tp->window);
            }

        }

    }

}
Example #5
0
File: key.c Project: kuailexs/jwm
/** Shutdown key bindings. */
void ShutdownKeys(void)
{

    ClientNode *np;
    TrayType *tp;
    unsigned int layer;

    /* Ungrab keys on client windows. */
    for(layer = 0; layer < LAYER_COUNT; layer++) {
        for(np = nodes[layer]; np; np = np->next) {
            JXUngrabKey(display, AnyKey, AnyModifier, np->window);
        }
    }

    /* Ungrab keys on trays, only really needed if we are restarting. */
    for(tp = GetTrays(); tp; tp = tp->next) {
        JXUngrabKey(display, AnyKey, AnyModifier, tp->window);
    }

    /* Ungrab keys on the root. */
    JXUngrabKey(display, AnyKey, AnyModifier, rootWindow);

}
Example #6
0
File: move.c Project: Nehamkin/jwm
/** Snap to window borders. */
void DoSnapBorder(ClientNode *np)
{

   const ClientNode *tp;
   const TrayType *tray;
   RectangleType client, other;
   RectangleType left = { 0 };
   RectangleType right = { 0 };
   RectangleType top = { 0 };
   RectangleType bottom = { 0 };
   int layer;
   int north, south, east, west;

   GetClientRectangle(np, &client);

   GetBorderSize(&np->state, &north, &south, &east, &west);

   other.valid = 1;

   /* Work from the bottom of the window stack to the top. */
   for(layer = 0; layer < LAYER_COUNT; layer++) {

      /* Check tray windows. */
      for(tray = GetTrays(); tray; tray = tray->next) {

         if(tray->hidden) {
            continue;
         }

         other.left = tray->x;
         other.right = tray->x + tray->width;
         other.top = tray->y;
         other.bottom = tray->y + tray->height;

         left.valid = CheckLeftValid(&client, &other, &left);
         right.valid = CheckRightValid(&client, &other, &right);
         top.valid = CheckTopValid(&client, &other, &top);
         bottom.valid = CheckBottomValid(&client, &other, &bottom);

         if(CheckOverlapTopBottom(&client, &other)) {
            if(abs(client.left - other.right) <= settings.snapDistance) {
               left = other;
            }
            if(abs(client.right - other.left) <= settings.snapDistance) {
               right = other;
            }
         }
         if(CheckOverlapLeftRight(&client, &other)) {
            if(abs(client.top - other.bottom) <= settings.snapDistance) {
               top = other;
            }
            if(abs(client.bottom - other.top) <= settings.snapDistance) {
               bottom = other;
            }
         }

      }

      /* Check client windows. */
      for(tp = nodeTail[layer]; tp; tp = tp->prev) {

         if(tp == np || !ShouldSnap(tp)) {
            continue;
         }

         GetClientRectangle(tp, &other);

         /* Check if this border invalidates any previous value. */
         left.valid = CheckLeftValid(&client, &other, &left);
         right.valid = CheckRightValid(&client, &other, &right);
         top.valid = CheckTopValid(&client, &other, &top);
         bottom.valid = CheckBottomValid(&client, &other, &bottom);

         /* Compute the new snap values. */
         if(CheckOverlapTopBottom(&client, &other)) {
            if(abs(client.left - other.right) <= settings.snapDistance) {
               left = other;
            }
            if(abs(client.right - other.left) <= settings.snapDistance) {
               right = other;
            }
         }
         if(CheckOverlapLeftRight(&client, &other)) {
            if(abs(client.top - other.bottom) <= settings.snapDistance) {
               top = other;
            }
            if(abs(client.bottom - other.top) <= settings.snapDistance) {
               bottom = other;
            }
         }

      }

   }

   if(right.valid) {
      np->x = right.left - np->width - west;
   }
   if(left.valid) {
      np->x = left.right + east;
   }
   if(bottom.valid) {
      np->y = bottom.top - south;
      if(!(np->state.status & STAT_SHADED)) {
         np->y -= np->height;
      }
   }
   if(top.valid) {
      np->y = top.bottom + north;
   }

}
Example #7
0
/** Restack the clients according the way we want them. */
void RestackClients(void)
{

   TrayType *tp;
   ClientNode *np;
   unsigned int layer, index;
   int trayCount;
   Window *stack;
   Window fw;

   if(JUNLIKELY(shouldExit)) {
      return;
   }

   /* Allocate memory for restacking. */
   trayCount = GetTrayCount();
   stack = AllocateStack((clientCount + trayCount) * sizeof(Window));

   /* Prepare the stacking array. */
   fw = None;
   index = 0;
   if(activeClient && (activeClient->state.status & STAT_FULLSCREEN)) {
      fw = activeClient->window;
      for(np = nodes[activeClient->state.layer]; np; np = np->next) {
         if(np->owner == fw) {
            if(np->parent != None) {
               stack[index] = np->parent;
            } else {
               stack[index] = np->window;
            }
            index += 1;
         }
      }
      if(activeClient->parent != None) {
         stack[index] = activeClient->parent;
      } else {
         stack[index] = activeClient->window;
      }
      index += 1;
   }
   layer = LAST_LAYER;
   for(;;) {

      for(np = nodes[layer]; np; np = np->next) {
         if(    (np->state.status & (STAT_MAPPED | STAT_SHADED))
            && !(np->state.status & STAT_HIDDEN)) {
            if(fw != None && (np->window == fw || np->owner == fw)) {
               continue;
            }
            if(np->parent != None) {
               stack[index] = np->parent;
            } else {
               stack[index] = np->window;
            }
            index += 1;
         }
      }

      for(tp = GetTrays(); tp; tp = tp->next) {
         if(layer == tp->layer) {
            stack[index] = tp->window;
            index += 1;
         }
      }

      if(layer == FIRST_LAYER) {
         break;
      }
      layer -= 1;

   }

   JXRestackWindows(display, stack, index);

   ReleaseStack(stack);
   UpdateNetClientList();
   RequirePagerUpdate();

}
Example #8
0
File: place.c Project: KarlGodt/jwm
/** Place a maximized client on the screen. */
void PlaceMaximizedClient(ClientNode *np, MaxFlags flags)
{

   BoundingBox box;
   const ScreenType *sp;
   int north, south, east, west;

   np->oldx = np->x;
   np->oldy = np->y;
   np->oldWidth = np->width;
   np->oldHeight = np->height;

   GetBorderSize(&np->state, &north, &south, &east, &west);

   sp = GetCurrentScreen(np->x + (east + west + np->width) / 2,
                         np->y + (north + south + np->height) / 2);
   GetScreenBounds(sp, &box);
   if(!(flags & (MAX_HORIZ | MAX_LEFT | MAX_RIGHT))) {
      box.x = np->x - west;
      box.width = np->width + east + west;
   }
   if(!(flags & (MAX_VERT | MAX_TOP | MAX_BOTTOM))) {
      box.y = np->y - north;
      box.height = np->height + north + south;
   }
   SubtractTrayBounds(GetTrays(), &box, np->state.layer);
   SubtractStrutBounds(&box, np);

   if(box.width > np->maxWidth) {
      box.width = np->maxWidth;
   }
   if(box.height > np->maxHeight) {
      box.height = np->maxHeight;
   }

   if(np->sizeFlags & PAspect) {
      if(box.width * np->aspect.miny < box.height * np->aspect.minx) {
         box.height = (box.width * np->aspect.miny) / np->aspect.minx;
      }
      if(box.width * np->aspect.maxy > box.height * np->aspect.maxx) {
         box.width = (box.height * np->aspect.maxx) / np->aspect.maxy;
      }
   }

   /* Remove window outlines. */
   if(flags & (MAX_VERT | MAX_TOP)) {
      north = Max(0, north - 1);
   }
   if(flags & (MAX_VERT | MAX_BOTTOM)) {
      south = Max(0, south - 1);
   }
   if(flags & (MAX_HORIZ | MAX_LEFT)) {
      west = Max(0, west - 1);
   }
   if(flags & (MAX_HORIZ | MAX_RIGHT)) {
      east = Max(0, east - 1);
   }

   /* If maximizing horizontally, update width. */
   if(flags & MAX_HORIZ) {
      np->x = box.x;
      np->width = box.width;
      if(!(np->state.status & STAT_IIGNORE)) {
         np->width -= ((box.width - np->baseWidth) % np->xinc);
      }
   } else if(flags & MAX_LEFT) {
      np->x = box.x;
      np->width = box.width / 2 - west;
      if(!(np->state.status & STAT_IIGNORE)) {
         np->width -= ((box.width - np->baseWidth) % np->xinc);
      }
   } else if(flags & MAX_RIGHT) {
      np->x = box.x + box.width / 2 + west;
      np->width = box.width / 2 - east;
      if(!(np->state.status & STAT_IIGNORE)) {
         np->width -= ((box.width - np->baseWidth) % np->xinc);
      }
   }

   /* If maximizing vertically, update height. */
   if(flags & MAX_VERT) {
      np->y = box.y + north;
      np->height = box.height - north;
      if(!(np->state.status & STAT_IIGNORE)) {
         np->height -= ((box.height - np->baseHeight) % np->yinc);
      }
   } else if(flags & MAX_TOP) {
      np->y = box.y + north;
      np->height = box.height / 2 - north - south;
      if(!(np->state.status & STAT_IIGNORE)) {
         np->height -= ((box.height - np->baseHeight) % np->yinc);
      }
   } else if(flags & MAX_BOTTOM) {
      np->y = box.y + box.height / 2 + north;
      np->height = box.height / 2 - north - south;
      if(!(np->state.status & STAT_IIGNORE)) {
         np->height -= ((box.height - np->baseHeight) % np->yinc);
      }
   }

   np->state.maxFlags = flags;

}
Example #9
0
File: place.c Project: KarlGodt/jwm
/** Constrain the size of the client. */
char ConstrainSize(ClientNode *np)
{

   BoundingBox box;
   const ScreenType *sp;
   int north, south, east, west;
   const int oldWidth = np->width;
   const int oldHeight = np->height;

   /* First we make sure the window isn't larger than the program allows.
    * We do this here to avoid moving the window below.
    */
   np->width = Min(np->width, np->maxWidth);
   np->height = Min(np->height, np->maxHeight);

   /* Constrain the width if necessary. */
   sp = GetCurrentScreen(np->x, np->y);
   GetScreenBounds(sp, &box);
   SubtractTrayBounds(GetTrays(), &box, np->state.layer);
   SubtractStrutBounds(&box, np);
   GetBorderSize(&np->state, &north, &south, &east, &west);
   if(np->width + east + west > sp->width) {
      box.x += west;
      box.width -= east + west;
      if(box.width > np->maxWidth) {
         box.width = np->maxWidth;
      }
      if(box.width > np->width) {
         box.width = np->width;
      }
      np->x = box.x;
      np->width = box.width - (box.width % np->xinc);
   }

   /* Constrain the height if necessary. */
   if(np->height + north + south > sp->height) {
      box.y += north;
      box.height -= north + south;
      if(box.height > np->maxHeight) {
         box.height = np->maxHeight;
      }
      if(box.height > np->height) {
         box.height = np->height;
      }
      np->y = box.y;
      np->height = box.height - (box.height % np->yinc);
   }

   /* If the program has a minimum constraint, we apply that here.
    * Note that this could cause the window to overlap something. */
   np->width = Max(np->width, np->minWidth);
   np->height = Max(np->height, np->minHeight);

   /* Fix the aspect ratio. */
   if(np->sizeFlags & PAspect) {
      if(np->width * np->aspect.miny < np->height * np->aspect.minx) {
         np->height = (np->width * np->aspect.miny) / np->aspect.minx;
      }
      if(np->width * np->aspect.maxy > np->height * np->aspect.maxx) {
         np->width = (np->height * np->aspect.maxx) / np->aspect.maxy;
      }
   }

   if(np->width != oldWidth || np->height != oldHeight) {
      return 1;
   } else {
      return 0;
   }

}