Example #1
0
/** Process a button event. */
void HandleButtonEvent(const XButtonEvent *event)
{

   ClientNode *np;
   int north, south, east, west;

   np = FindClientByParent(event->window);
   if(np) {
      if(event->type == ButtonPress) {
         FocusClient(np);
         RaiseClient(np);
      }
      DispatchBorderButtonEvent(event, np);
   } else if(event->window == rootWindow && event->type == ButtonPress) {
      if(!ShowRootMenu(event->button, event->x, event->y, 0)) {
         if(event->button == Button4) {
            LeftDesktop();
         } else if(event->button == Button5) {
            RightDesktop();
         }
      }
   } else {
      const unsigned int mask = event->state & ~lockMask;
      np = FindClientByWindow(event->window);
      if(np) {
         switch(event->button) {
         case Button1:
         case Button2:
            FocusClient(np);
            RaiseClient(np);
            if(mask == Mod1Mask) {
               GetBorderSize(&np->state, &north, &south, &east, &west);
               MoveClient(np, event->x + west, event->y + north);
            }
            break;
         case Button3:
            if(mask == Mod1Mask) {
               GetBorderSize(&np->state, &north, &south, &east, &west);
               ResizeClient(np, BA_RESIZE | BA_RESIZE_E | BA_RESIZE_S,
                            event->x + west, event->y + north);
            } else {
               FocusClient(np);
               RaiseClient(np);
            }
            break;
         default:
            break;
         }
         JXAllowEvents(display, ReplayPointer, eventTime);
      }

   }

}
Example #2
0
/** Stop walking the window stack or client list. */
void StopWindowWalk(void)
{

   ClientNode *np;

   /* Raise the selected window and free the window array. */
   if(windowStack != NULL) {

      /* Look up the current window. */
      np = FindClientByWindow(windowStack[windowStackCurrent]);
      if(np) {
         if(np->state.status & STAT_MINIMIZED) {
            RestoreClient(np, 1);
         } else {
            RaiseClient(np);
         }
      }

      Release(windowStack);
      windowStack = NULL;

      windowStackSize = 0;
      windowStackCurrent = 0;

   }

   if(walkingWindows) {
      JXUngrabKeyboard(display, CurrentTime);
      LowerTrays();
      walkingWindows = 0;
   }

}
Example #3
0
/** Restore a window with its transients (helper method). */
void RestoreTransients(ClientNode *np, char raise)
{

   ClientNode *tp;
   int x;

   Assert(np);

   /* Make sure this window is on the current desktop. */
   SetClientDesktop(np, currentDesktop);

   /* Restore this window. */
   if(!(np->state.status & STAT_MAPPED)) {
      if(np->state.status & STAT_SHADED) {
         if(np->parent != None) {
            JXMapWindow(display, np->parent);
         }
      } else {
         JXMapWindow(display, np->window);
         if(np->parent != None) {
            JXMapWindow(display, np->parent);
         }
         np->state.status |= STAT_MAPPED;
      }
   }
   np->state.status &= ~STAT_MINIMIZED;
   np->state.status &= ~STAT_SDESKTOP;

   /* Restore transient windows. */
   for(x = 0; x < LAYER_COUNT; x++) {
      for(tp = nodes[x]; tp; tp = tp->next) {
         if(tp->owner == np->window && (tp->state.status & STAT_MINIMIZED)) {
            RestoreTransients(tp, raise);
         }
      }
   }

   if(raise) {
      FocusClient(np);
      RaiseClient(np);
   }
   WriteState(np);

}
Example #4
0
/** Handle a map request. */
void HandleMapRequest(const XMapEvent *event) {

   ClientNode *np;

   Assert(event);

   if(CheckSwallowMap(event)) {
      return;
   }

   np = FindClientByWindow(event->window);
   if(!np) {
      JXSync(display, False);
      JXGrabServer(display);
      np = AddClientWindow(event->window, 0, 1);
      if(np) {
         if(focusModel == FOCUS_CLICK && !(np->state.status & STAT_NOFOCUS)) {
            FocusClient(np);
         }
      } else {
         JXMapWindow(display, event->window);
      }
      JXSync(display, False);
      JXUngrabServer(display);
   } else {
      if(!(np->state.status & STAT_MAPPED)) {
         np->state = ReadWindowState(np->window);
         np->state.status |= STAT_MAPPED;
         if(!(np->state.status & STAT_STICKY)) {
            np->state.desktop = currentDesktop;
         }
         JXMapWindow(display, np->window);
         JXMapWindow(display, np->parent);
         if(!(np->state.status & STAT_NOFOCUS)) {
            RaiseClient(np);
            FocusClient(np);
         }
         UpdateTaskBar();
         UpdatePager();
      }
   }
   RestackClients();
}
Example #5
0
/** Maximize a client window. */
void MaximizeClient(ClientNode *np, MaxFlags flags)
{

    /* Return if we don't have a client. */
    if(np == NULL) {
        return;
    }

   /* Don't allow maximization of full-screen clients. */
   if(np->state.status & STAT_FULLSCREEN) {
      return;
   }
   if(!(np->state.border & BORDER_MAX)) {
      return;
   }

   if(np->state.status & STAT_SHADED) {
      UnshadeClient(np);
   }

   RaiseClient(np);
   FocusClient(np);
   if(np->state.maxFlags) {
      /* Undo existing maximization. */
      np->x = np->oldx;
      np->y = np->oldy;
      np->width = np->oldWidth;
      np->height = np->oldHeight;
      np->state.maxFlags = MAX_NONE;
   }
   if(flags != MAX_NONE) {
      /* Maximize if requested. */
      PlaceMaximizedClient(np, flags);
   }

   WriteState(np);
   ResetBorder(np);
   DrawBorder(np);
   SendConfigureEvent(np);
   RequirePagerUpdate();

}
Example #6
0
/** Handle a map request. */
void HandleMapRequest(const XMapEvent *event)
{
   ClientNode *np;
   Assert(event);
   if(CheckSwallowMap(event->window)) {
      return;
   }
   np = FindClientByWindow(event->window);
   if(!np) {
      GrabServer();
      np = AddClientWindow(event->window, 0, 1);
      if(np) {
         if(!(np->state.status & STAT_NOFOCUS)) {
            FocusClient(np);
         }
      } else {
         JXMapWindow(display, event->window);
      }
      UngrabServer();
   } else {
      if(!(np->state.status & STAT_MAPPED)) {
         UpdateState(np);
         np->state.status |= STAT_MAPPED;
         XMapWindow(display, np->window);
         if(np->parent != None) {
            XMapWindow(display, np->parent);
         }
         if(!(np->state.status & STAT_STICKY)) {
            np->state.desktop = currentDesktop;
         }
         if(!(np->state.status & STAT_NOFOCUS)) {
            FocusClient(np);
            RaiseClient(np);
         }
         WriteState(np);
         RequireTaskUpdate();
         RequirePagerUpdate();
      }
   }
   RequireRestack();
}
Example #7
0
/** Process a key press event. */
void HandleKeyPress(const XKeyEvent *event)
{
   ClientNode *np;
   KeyType key;

   SetMousePosition(event->x_root, event->y_root, event->window);
   key = GetKey(event);
   np = GetActiveClient();
   switch(key & 0xFF) {
   case KEY_EXEC:
      RunKeyCommand(event);
      break;
   case KEY_DESKTOP:
      ChangeDesktop((key >> 8) - 1);
      break;
   case KEY_RDESKTOP:
      RightDesktop();
      break;
   case KEY_LDESKTOP:
      LeftDesktop();
      break;
   case KEY_UDESKTOP:
      AboveDesktop();
      break;
   case KEY_DDESKTOP:
      BelowDesktop();
      break;
   case KEY_SHOWDESK:
      ShowDesktop();
      break;
   case KEY_SHOWTRAY:
      ShowAllTrays();
      break;
   case KEY_NEXT:
      StartWindowWalk();
      FocusNext();
      break;
   case KEY_NEXTSTACK:
      StartWindowStackWalk();
      WalkWindowStack(1);
      break;
   case KEY_PREV:
      StartWindowWalk();
      FocusPrevious();
      break;
   case KEY_PREVSTACK:
      StartWindowStackWalk();
      WalkWindowStack(0);
      break;
   case KEY_CLOSE:
      if(np) {
         DeleteClient(np);
      }
      break;
   case KEY_SHADE:
      if(np) {
         if(np->state.status & STAT_SHADED) {
            UnshadeClient(np);
         } else {
            ShadeClient(np);
         }
      }
      break;
   case KEY_STICK:
      if(np) {
         if(np->state.status & STAT_STICKY) {
            SetClientSticky(np, 0);
         } else {
            SetClientSticky(np, 1);
         }
      }
      break;
   case KEY_MOVE:
      if(np) {
         MoveClientKeyboard(np);
      }
      break;
   case KEY_RESIZE:
      if(np) {
         ResizeClientKeyboard(np);
      }
      break;
   case KEY_MIN:
      if(np) {
         MinimizeClient(np, 1);
      }
      break;
   case KEY_MAX:
      if(np) {
         if(np->state.maxFlags) {
            MaximizeClient(np, MAX_NONE);
         } else {
            MaximizeClient(np, MAX_HORIZ | MAX_VERT);
         }
      }
      break;
   case KEY_MAXTOP:
      ToggleMaximized(np, MAX_TOP | MAX_HORIZ);
      break;
   case KEY_MAXBOTTOM:
      ToggleMaximized(np, MAX_BOTTOM | MAX_HORIZ);
      break;
   case KEY_MAXLEFT:
      ToggleMaximized(np, MAX_LEFT | MAX_VERT);
      break;
   case KEY_MAXRIGHT:
      ToggleMaximized(np, MAX_RIGHT | MAX_VERT);
      break;
   case KEY_MAXV:
      ToggleMaximized(np, MAX_VERT);
      break;
   case KEY_MAXH:
      ToggleMaximized(np, MAX_HORIZ);
      break;
   case KEY_ROOT:
      ShowKeyMenu(event);
      break;
   case KEY_WIN:
      if(np) {
         RaiseClient(np);
         ShowWindowMenu(np, np->x, np->y, 1);
      }
      break;
   case KEY_RESTART:
      Restart();
      break;
   case KEY_EXIT:
      Exit();
      break;
   case KEY_FULLSCREEN:
      if(np) {
         if(np->state.status & STAT_FULLSCREEN) {
            SetClientFullScreen(np, 0);
         } else {
            SetClientFullScreen(np, 1);
         }
      }
      break;
   case KEY_SENDR:
      if(np) {
         SetClientDesktop(np, GetRightDesktop(np->state.desktop));
      }
      break;
   case KEY_SENDL:
      if(np) {
         SetClientDesktop(np, GetLeftDesktop(np->state.desktop));
      }
      break;
   case KEY_SENDU:
      if(np) {
         SetClientDesktop(np, GetAboveDesktop(np->state.desktop));
      }
      break;
   case KEY_SENDD:
      if(np) {
         SetClientDesktop(np, GetBelowDesktop(np->state.desktop));
      }
      break;
   default:
      break;
   }
   DiscardEnterEvents();
}
Example #8
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;

}
Example #9
0
/** Process a button event. */
void HandleButtonEvent(const XButtonEvent *event) {

   int x, y;
   ClientNode *np;
   int north, south, east, west;

   np = FindClientByParent(event->window);
   if(np) {
      RaiseClient(np);
      if(focusModel == FOCUS_CLICK) {
         FocusClient(np);
      }
      switch(event->button) {
      case Button1:
         DispatchBorderButtonEvent(event, np);
         break;
      case Button2:
         MoveClient(np, event->x, event->y);
         break;
      case Button3:
         GetBorderSize(np, &north, &south, &east, &west);
         x = event->x + np->x - west;
         y = event->y + np->y - north;
         ShowWindowMenu(np, x, y);
         break;
      case Button4:
         ShadeClient(np);
         break;
      case Button5:
         UnshadeClient(np);
         break;
      default:
         break;
      }
   } else if(event->window == rootWindow && event->type == ButtonPress) {
      if(!ShowRootMenu(event->button, event->x, event->y)) {
         if(event->button == 4) {
            LeftDesktop();
         } else if(event->button == 5) {
            RightDesktop();
         }
      }
   } else {
      np = FindClientByWindow(event->window);
      if(np) {
         switch(event->button) {
         case Button1:
         case Button2:
            RaiseClient(np);
            if(focusModel == FOCUS_CLICK) {
               FocusClient(np);
            }
            if(event->state & Mod1Mask) {
               GetBorderSize(np, &north, &south, &east, &west);
               MoveClient(np, event->x + west, event->y + north);
            }
            break;
         case Button3:
            if(event->state & Mod1Mask) {
               GetBorderSize(np, &north, &south, &east, &west);
               ResizeClient(np, BA_RESIZE | BA_RESIZE_E | BA_RESIZE_S,
                  event->x + west, event->y + north);
            } else {
               RaiseClient(np);
               if(focusModel == FOCUS_CLICK) {
                  FocusClient(np);
               }
            }
            break;
         default:
            break;
         }
         JXAllowEvents(display, ReplayPointer, CurrentTime);
      }
   }

   UpdatePager();
}