Example #1
0
/** Toggle the selected client to max
 * \param cmd uicb_t type unused
*/
void
uicb_togglemax(uicb_t cmd)
{
     (void)cmd;

     if(!sel || ishide(sel, selscreen)
        || (sel->flags & HintFlag)|| (sel->flags & FSSFlag))
          return;

     if(!(sel->flags & MaxFlag))
     {
          sel->ogeo = sel->geo;
          sel->free_geo = sel->geo;
          sel->flags &= ~(TileFlag | FreeFlag);
          client_maximize(sel);
          XRaiseWindow(dpy, sel->frame);
          sel->flags |= MaxFlag;

     }
     else
     {
          sel->geo = sel->ogeo;
          client_moveresize(sel, sel->geo, True);
          sel->flags &= ~MaxFlag;
          tags[selscreen][seltag[selscreen]].layout.func(selscreen);
     }

     return;
}
Example #2
0
/** Toggle the selected client to free
 * \param cmd uicb_t type unused
*/
void
uicb_togglefree(uicb_t cmd)
{
     (void)cmd;

     if(!sel || sel->screen != screen_get_sel() || (sel->flags & FSSFlag))
          return;

     sel->flags ^= FreeFlag;

     if((sel->flags & FreeFlag))
     {
          sel->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
          client_moveresize(sel, sel->free_geo, True);
          client_raise(sel);
     }
     else
     {
          sel->free_geo = sel->geo;
          sel->ogeo = sel->geo;
     }

     client_update_attributes(sel);

     tags[selscreen][seltag[selscreen]].layout.func(selscreen);

     return;
}
Example #3
0
File: ewmh.c Project: n4cht/kwm
/** Manage _NET_WM_STATE_* ewmh
 */
void
ewmh_manage_net_wm_state(long data_l[], Client *c)
{
     /* Manage _NET_WM_STATE_FULLSCREEN */
     if(data_l[1] == (long)net_atom[net_wm_state_fullscreen])
     {
          if(data_l[0] == _NET_WM_STATE_ADD && !(c->flags & FSSFlag))
          {
               c->screen = screen_get_with_geo(c->geo.x, c->geo.y);
               c->flags &= ~UnmapFlag;
               XMapWindow(dpy, c->win);
               XReparentWindow(dpy, c->win, ROOT, spgeo[c->screen].x, spgeo[c->screen].y);
               XResizeWindow(dpy, c->win,
                             spgeo[c->screen].width,
                             spgeo[c->screen].height);
               XChangeProperty(dpy, c->win, net_atom[net_wm_state], XA_ATOM, 32,
                               PropModeReplace, (uchar *)&net_atom[net_wm_state_fullscreen], 1);

               c->tmp_geo = c->geo;

               if(c->flags & FreeFlag)
                    c->ogeo = c->geo;

               c->flags |= (FSSFlag | MaxFlag);

               client_raise(c);
               client_focus(c);
               XUnmapWindow(dpy, c->frame);
          }
          else if(data_l[0] == _NET_WM_STATE_REMOVE && (c->flags & FSSFlag))
          {
               XChangeProperty(dpy, c->win, net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace, (uchar *)0, 0);
               c->flags &= ~(FSSFlag | MaxFlag);
               client_map(c);
               XReparentWindow(dpy, c->win, c->frame, BORDH, TBARH);
               client_moveresize(c, c->tmp_geo, False);
          }
     }
     /* Manage _NET_WM_STATE_STICKY */
     else if(data_l[1] == (long)net_atom[net_wm_state_sticky])
     {
          /* == client_ignore_tag */
          c->tag = MAXTAG + 1;
          arrange(c->screen, True);
     }
     /* Manage _NET_WM_STATE_DEMANDS_ATTENTION */
     else if(data_l[1] == (long)net_atom[net_wm_state_demands_attention])
     {
          if(data_l[0] == _NET_WM_STATE_ADD)
               client_urgent(c, True);
          if(data_l[0] == _NET_WM_STATE_REMOVE)
               if(c == sel)
                    client_focus(NULL);
     }

     return;
}
Example #4
0
File: event.c Project: n4cht/kwm
/** ConfigureRequesthandle events
 * \param ev XConfigureRequestEvent pointer
*/
static void
configureevent(XConfigureRequestEvent *ev)
{
     XWindowChanges wc;
     Client *c;

     /* Check part */
     if((c = client_gb_win(ev->window))
        || (c = client_gb_win(ev->window)))
     {
          CHECK(!(c->flags & LMaxFlag));
          CHECK(!(c->flags & MaxFlag));
          CHECK(!(c->flags & FSSFlag));
     }

     if((c = client_gb_win(ev->window)))
     {
          if(ev->value_mask & CWX)
               c->geo.x = ev->x + BORDH;
          if(ev->value_mask & CWY)
               c->geo.y = ev->y + TBARH;
          if(ev->value_mask & CWWidth)
               c->geo.width = ev->width;
          if(ev->value_mask & CWHeight)
               c->geo.height = ev->height;

          if(c->flags & FreeFlag || !(c->flags & (TileFlag | LMaxFlag)))
               client_moveresize(c, c->geo, False);
          else
          {
               client_configure(c);
               arrange(c->screen, True);
          }
     }
     else
     {
          wc.x            = ev->x;
          wc.y            = ev->y;
          wc.width        = ev->width;
          wc.height       = ev->height;
          wc.border_width = ev->border_width;
          wc.sibling      = ev->above;
          wc.stack_mode   = ev->detail;

          XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
     }

     return;
}
Example #5
0
static void
event_configureevent(XEvent *e)
{
     XConfigureRequestEvent *ev = &e->xconfigurerequest;
     XWindowChanges wc;
     struct client *c;

     if((c = client_gb_win(ev->window)))
     {
          if(c->flags & CLIENT_FREE)
          {
               if(ev->value_mask & CWX)
                    c->geo.x = ev->x;
               if(ev->value_mask & CWY)
                    c->geo.y = ev->y - c->tbarw - c->border - c->border;
               if(ev->value_mask & CWWidth)
                    c->geo.w = ev->width + c->border + c->border;
               if(ev->value_mask & CWHeight)
                    c->geo.h = ev->height + c->tbarw + c->border;

               client_moveresize(c, &c->geo);
          }
          else
          {
               if(ev->value_mask & CWWidth)
                    _fac_resize(c, Right, ev->width - c->wgeo.w);
               if(ev->value_mask & CWHeight)
                    _fac_resize(c, Bottom, ev->height - c->wgeo.h);

               client_apply_tgeo(c->tag);
          }
     }
     else
     {
          wc.x            = ev->x;
          wc.y            = ev->y;
          wc.width        = ev->width;
          wc.height       = ev->height;
          wc.border_width = ev->border_width;
          wc.sibling      = ev->above;
          wc.stack_mode   = ev->detail;

          XConfigureWindow(EVDPY(e), ev->window, ev->value_mask, &wc);
     }
}
Example #6
0
/** The free layout function
*/
void
freelayout(int screen)
{
     Client *c;
     (void)screen;

     for(c = clients; c; c = c->next)
          if(!ishide(c, selscreen)
             && c->screen == screen_get_sel()
             && !(c->flags & MaxFlag))
          {
               client_moveresize(c, c->free_geo, True);
               c->flags &= ~(TileFlag | LMaxFlag);
          }

     ewmh_update_current_tag_prop();

     return;
}
Example #7
0
File: ewmh.c Project: Engil/wmfs
void
ewmh_manage_state(long data[], struct client *c)
{
     /* _NET_WM_STATE_FULLSCREEN */
     if(data[1] == (long)W->net_atom[net_wm_state_fullscreen]
        || data[2] == (long)W->net_atom[net_wm_state_fullscreen])
     {
          if(data[0] == _NET_WM_STATE_ADD
             || (data[0] == _NET_WM_STATE_TOGGLE && !(c->flags & CLIENT_FULLSCREEN)))
          {
               c->flags |= CLIENT_FULLSCREEN;

               XChangeProperty(W->dpy, c->win, W->net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace,
                               (unsigned char*)&W->net_atom[net_wm_state_fullscreen], 1);
               XReparentWindow(W->dpy, c->win, W->root, c->screen->geo.x, c->screen->geo.y);
               XResizeWindow(W->dpy, c->win, c->screen->geo.w, c->screen->geo.h);

               if(c->tag)
                    client_focus(c);

               XRaiseWindow(W->dpy, c->win);
          }
          else
          {
               c->flags &= ~CLIENT_FULLSCREEN;

               XChangeProperty(W->dpy, c->win, W->net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace,
                               (unsigned char*)0, 0);
               XReparentWindow(W->dpy, c->win, c->frame, c->wgeo.x, c->wgeo.y);

               if(c->flags & CLIENT_FREE)
                    client_moveresize(c, &c->geo);
               else
                    layout_fix_hole(c);
          }
     }

}
Example #8
0
File: split.c Project: pierreN/wmfs
/** Arrange clients after a client close
  *\param ghost Ghost client
 */
void
split_arrange_closed(Client *ghost)
{
     Position p;
     bool b = False;
     Geo cgeo;
     Client *c, *cc;
     int screen = ghost->screen;
     int tag = (ghost->tag ? ghost->tag : seltag[screen]);

     /* Use ghost client properties to fix holes in tile
      *     .--.  ~   ~
      *    /xx  \   ~   ~
      *  ~~\O _ (____     ~
      *  __.|    .--'-==~   ~
      * '---\    '.      ~  ,  ~
      *      '.    '-.___.-'/   ~
      *        '-.__     _.'  ~
      *             `````   ~
      */

     /* Search for single parent for easy resize
      * Example case:
      *  ___________               ___________
      * |     |  B  | ->       -> |     |     |
      * |  A  |_____| -> Close -> |  A  |  B  |
      * |     |  C  | ->   C   -> |     |v v v|
      * |_____|_____| ->       -> |_____|_____|
      */
     for(p = Right; p < Center; ++p)
          if((c = client_get_next_with_direction(ghost, p)))
               if(CFACTOR_CHECK2(ghost->frame_geo, c->frame_geo, p))
               {
                    _split_arrange_size(ghost->wrgeo, &c->wrgeo, p);
                    cfactor_clean(c);
                    client_moveresize(c, (c->pgeo = c->wrgeo), (tags[screen][tag].flags & ResizeHintFlag));

                    return;
               }

     /* Check row parents for full resize
      * Example case:
      *  ___________               ___________
      * |     |  B  | ->       -> | <<  B     |
      * |  A  |_____| -> Close -> |___________|
      * |     |  C  | ->   A   -> | <<  C     |
      * |_____|_____| ->       -> |___________|
      */
     for(p = Right; p < Center && !b; ++p)
          if((c = client_get_next_with_direction(ghost, p)) && _split_check_row_dir(c, ghost, p))
          {
               for(cgeo = c->frame_geo, cc = tiled_client(c->screen, SLIST_FIRST(&clients));
                         cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
                    if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, RPOS(p))
                              && SPLIT_CHECK_ROW(cc->frame_geo, ghost->frame_geo, p))
                    {
                         _split_arrange_size(ghost->wrgeo, &cc->wrgeo, p);
                         cfactor_clean(cc);
                         client_moveresize(cc, (cc->pgeo = cc->wrgeo), (tags[screen][tag].flags & ResizeHintFlag));
                         b = True;
                    }
          }

     return;
}
Example #9
0
/** Mirror layout function
 * \param screen Screen to execute this function
 * \param horizont To specify the mirror mode (vertical/horizontal)
 */
static void
mirror(int screen, Bool horizontal)
{
     Client *c;
     XRectangle sg = sgeo[screen];
     XRectangle mastergeo = {sg.x, sg.y, sg.width, sg.height};
     XRectangle cgeo = {sg.x, sg.y , sg.width, sg.height};
     XRectangle nextg[2];
     uint i, n, tilesize = 0, mwfact;
     uint nmaster = tags[screen][seltag[screen]].nmaster;
     int pa, imp;
     Bool isp = 0;

     memset(nextg, 0, sizeof(nextg));

     for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
     CHECK(n);

     /* Fix nmaster */
     nmaster = (n < nmaster) ? n : nmaster;

     imp = ((n - (nmaster - 1)) / 2);
     pa = ((n - (nmaster - 1)) / 2) - (((n - (nmaster - 1)) % 2) ? 0 : 1);

     /* Set mwfact */
     if(tags[screen][seltag[screen]].mwfact < 0.55)
          tags[screen][seltag[screen]].mwfact = 0.55;

     mwfact = tags[screen][seltag[screen]].mwfact * ((horizontal) ? sg.height : sg.width);

     /* Master size */
     if(horizontal)
     {
          mastergeo.width = (sg.width / nmaster) - (BORDH * 2);
          mastergeo.height -= BORDH;
     }
     else
     {
          mastergeo.width -= BORDH * 2;
          mastergeo.height = (sg.height / nmaster) - (TBARH + (BORDH * 2));
     }

     if(n == nmaster + 1)
     {
          if(horizontal)
          {
               mastergeo.height = mwfact - ((BORDH * 2) + TBARH);
               tilesize = (sg.height - mastergeo.height) - ((BORDH * 2) + TBARH);
          }
          else
          {
               mastergeo.width = mwfact - (BORDH * 3);
               tilesize = (sg.width - mastergeo.width) - (BORDH * 4);
          }
     }
     if(n > nmaster + 1)
     {
          if(horizontal)
          {
               mastergeo.y = (sg.y + (sg.height - mwfact)) + TBARH + BORDH;
               mastergeo.height = (2 * mwfact - sg.height) - ((BORDH * 3) + (TBARH * 2));
               tilesize = (mwfact - mastergeo.height) - ((BORDH * 3) + (TBARH * 2));
          }
          else
          {
               mastergeo.x = (sg.x + (sg.width - mwfact)) + BORDH;
               mastergeo.width = ((2 * mwfact - sg.width) - (BORDH * 4));
               tilesize = (mwfact - mastergeo.width) - (BORDH * 5);
          }
     }

     for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
     {
          /* Set client property */
          c->flags &= ~(MaxFlag | LMaxFlag);
          c->flags |= TileFlag;

          if(i < nmaster)
          {
               cgeo = mastergeo;

               /* Master remainder */
               if(i + 1 == nmaster)
               {
                    if(horizontal)
                         cgeo.width = (sg.x + sg.width) - (cgeo.x + (BORDH * 2));
                    else
                         cgeo.height = (sg.y + sg.height) - (cgeo.y + BORDH);
               }
          }
          else
          {
               if(horizontal)
                    cgeo.height = tilesize;
               else
                    cgeo.width = tilesize;

               if((i + nmaster) % 2)
               {
                    isp = 1;

                    if(horizontal)
                    {
                         cgeo.y = sg.y;
                         cgeo.width = (sg.width / pa) - (BORDH * 2);
                    }
                    else
                    {
                         cgeo.x = sg.x;
                         cgeo.height = (sg.height / pa) - (TBARH + (BORDH * 2));
                    }
               }
               else
               {
                    isp = 0;

                    if(horizontal)
                    {
                         cgeo.y = (sg.y + mwfact) - BORDH;
                         cgeo.width = (sg.width / imp) - (BORDH * 2);
                    }
                    else
                    {
                         cgeo.x = (sg.x + mwfact) - BORDH;
                         cgeo.height = (sg.height / imp) - (TBARH + (BORDH * 2));
                    }
               }

               /* Remainder */
               if(i + 1 == n || i + 1 == n - 1)
               {
                    if(horizontal)
                         cgeo.width = (sg.x + sg.width) - (cgeo.x + (BORDH * 2));
                    else
                         cgeo.height = (sg.y + sg.height) - (cgeo.y + BORDH);
               }
          }

          client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);

          if(i >= nmaster)
               nextg[!isp] = c->geo;

          /* Next y/x position */
          if(i >= nmaster - 1)
          {
               if(horizontal)
               {
                    if(i == nmaster || i == nmaster - 1)
                         cgeo.x = sg.x;
                    else
                         cgeo.x = nextg[isp].x + nextg[isp].width + BORDH * 2;
               }
               else
               {
                    if(i == nmaster || i == nmaster - 1)
                         cgeo.y = sg.y;
                    else
                         cgeo.y = nextg[isp].y + nextg[isp].height + BORDH + TBARH;
               }
          }
          else if (i <= nmaster - 1)
          {
               if(horizontal)
                    mastergeo.x = c->geo.x + c->geo.width + BORDH * 2;
               else
                    mastergeo.y = c->geo.y + c->geo.height + BORDH + TBARH;
          }

     }

     ewmh_update_current_tag_prop();

     return;
}
Example #10
0
/** Multi tile function
 * \param type Postion type { Top, Bottom, Left, Right }
*/
static void
multi_tile(int screen, Position type)
{
     Client *c;
     XRectangle sg = sgeo[screen];
     XRectangle mastergeo = {sg.x, sg.y, 0, 0};
     XRectangle cgeo = {sg.x, sg.y, 0, 0};
     uint i, n, tilesize = 0, mwfact, nmaster = tags[screen][seltag[screen]].nmaster;

     for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
     CHECK(n);

     /* FIX NMASTER */
     nmaster = (n < nmaster) ? n : nmaster;

     /* SET MWFACT */
     mwfact = (type == Top || type == Bottom)
          ? tags[screen][seltag[screen]].mwfact * sg.height
          : tags[screen][seltag[screen]].mwfact * sg.width;

     /* MASTER SIZE */
     if(type == Top || type == Bottom)
     {
          if(type == Top)
               mastergeo.y = (n <= nmaster) ? (uint)sg.y : sg.y + (sg.height - mwfact) - BORDH;
          mastergeo.width = (sg.width / nmaster) - (BORDH * 4);
          mastergeo.height = (n <= nmaster) ? (uint)(sg.height - BORDH) : mwfact;
     }
     else
     {
          if(type == Left)
               mastergeo.x = (n <= nmaster) ? (uint)sg.x : (sg.x + sg.width) - mwfact - (BORDH * 2);
          mastergeo.width = (n <= nmaster) ? (uint)(sg.width - (BORDH * 2)) : mwfact;
          mastergeo.height = (sg.height / nmaster) - BORDH;
     }

     /* TILED SIZE */
     if(n > nmaster)
     {
          if(type == Top || type == Bottom)
               tilesize = sg.width / (n - nmaster) - (BORDH * 4);
          else
               tilesize = sg.height / (n - nmaster) - ((BORDH * 2) + TBARH);
     }


     for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
     {
          /* Set client property */
          c->flags &= ~(MaxFlag | LMaxFlag);
          c->flags |= TileFlag;

          /* MASTER */
          if(i < nmaster)
          {
               cgeo.width = mastergeo.width;
               cgeo.height = mastergeo.height;

               if(type == Top || type == Bottom)
                    cgeo.y = mastergeo.y;
               else
               {
                    cgeo.x = mastergeo.x;
                    cgeo.height -= (TBARH + BORDH);
               }
          }

          /* TILED */
          else
          {
               if(i == nmaster)
               {
                    switch(type)
                    {
                    case Top:
                    case Left:
                         cgeo.y = sg.y;
                         cgeo.x = sg.x;
                         break;
                    case Bottom:
                         cgeo.y += mastergeo.height + TBARH + BORDH;
                         cgeo.x = sg.x;
                         break;
                    default:
                    case Right:
                         cgeo.x += mastergeo.width + (BORDH * 2);
                         cgeo.y = sg.y;
                         break;
                    }
               }
               if(type == Top || type == Bottom)
               {
                    cgeo.width = tilesize;
                    cgeo.height = sg.height - mastergeo.height - TBARH - (BORDH * 2);
               }
               else
               {
                    cgeo.width = sg.width - mastergeo.width - (BORDH * 4);
                    cgeo.height = tilesize;
               }
          }

          /* REMAINDER */
          if(i + 1 == n  || i + 1 == (n < nmaster ? n : nmaster))
          {
               if(type == Top || type == Bottom)
                    cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH * 2)));
               else
                    cgeo.height = (sg.y + sg.height) - cgeo.y - BORDH;
          }

          /* Magic instant */
          client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);

          /* Set the position of the next client */
          if(type == Top || type == Bottom)
               cgeo.x = c->geo.x + c->geo.width + (BORDH * 2);
          else
               cgeo.y = c->geo.y + c->geo.height + BORDH + TBARH;
     }

     ewmh_update_current_tag_prop();

     return;
}
Example #11
0
/** Grid layout function
*/
static void
grid(int screen, Bool horizontal)
{
     Client *c;
     XRectangle sg = sgeo[screen];
     XRectangle cgeo = {sg.x, sg.y, 0, 0};
     unsigned int i, n, temp, cols, rows, cpcols = 0;

     for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
     CHECK(n);

     for(rows = 0; rows <= n / 2; ++rows)
          if(rows * rows >= n)
               break;

     cols = (rows && ((rows - 1) * rows) >= n)
          ? rows - 1
          : rows;

     if(!horizontal)
     {
         temp = cols;
         cols = rows;
         rows = temp;
     }

     for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
     {
          /* Set client property */
          c->flags &= ~(MaxFlag | LMaxFlag);
          c->flags |= TileFlag;
          ++cpcols;
          cgeo.width = (sg.width / cols) - (BORDH * 2);
          cgeo.height = (sg.height / rows) - BORDH;

          /* Last row's and last client remainder */
          if(cpcols == rows || i + 1 == n)
               cgeo.height = sg.y + sg.height - cgeo.y - BORDH;

          /* Last column's client remainder */
          if(i >= rows * (cols - 1))
               cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH * 2)));

          /* Resize */
          client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);

          /* Set all the other size with current client info */
          cgeo.y = c->geo.y + c->geo.height + BORDH + TBARH;

          if(cpcols + 1 > rows)
          {
               cpcols = 0;
               cgeo.x = c->geo.x + c->geo.width + (BORDH * 2);
               cgeo.y = sg.y;
          }
     }

     ewmh_update_current_tag_prop();

     return;
}
Example #12
0
void
mouse_resize(Client *c)
{
     XRectangle geo = c->geo, ogeo = c->geo;
     Position pos = Right;
     XEvent ev;
     Window w;
     int d, u, omx, omy;
     XGCValues xgc;
     GC gci;
     float mwf = tags[selscreen][seltag[selscreen]].mwfact;

     if((c->flags & MaxFlag)
        || (c->flags & LMaxFlag)
        || (c->flags & FSSFlag))
          return;

     XQueryPointer(dpy, ROOT, &w, &w, &omx, &omy, &d, &d, (uint *)&u);

     if((omx - c->geo.x) < (c->geo.width / 2))
          pos = Left;

     if(XGrabPointer(dpy, ROOT, False, MouseMask, GrabModeAsync, GrabModeAsync, None,
                     cursor[((c->flags & TileFlag) ? CurResize : ((pos == Right) ? CurRightResize : CurLeftResize))],
                     CurrentTime) != GrabSuccess)
          return;

     if(!(c->flags & TileFlag))
          XGrabServer(dpy);

     /* Set the GC for the rectangle */
     xgc.function = GXinvert;
     xgc.subwindow_mode = IncludeInferiors;
     xgc.line_width = BORDH;
     gci = XCreateGC(dpy, ROOT, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);

     if(!(c->flags & TileFlag))
     {
          if(pos == Right)
               XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->geo.width + conf.client.borderheight, c->geo.height);
          else
               XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, 0, c->geo.height);
          mouse_dragborder(c->geo, gci);
     }

     do
     {
          XMaskEvent(dpy, MouseMask | SubstructureRedirectMask, &ev);

          if(ev.type == MotionNotify)
          {
               /* To resize MWFACT in tile mode */
               if((c->flags & TileFlag)
                  && tags[selscreen][seltag[selscreen]].layout.func != grid_vertical
                  && tags[selscreen][seltag[selscreen]].layout.func != grid_horizontal)
               {
                    if(tags[selscreen][seltag[selscreen]].layout.func == tile)
                         mwf += (ROUND(ev.xmotion.x_root) - omx) / (sgeo[c->screen].width);
                    else if(tags[selscreen][seltag[selscreen]].layout.func == tile_left)
                         mwf -= (ROUND(ev.xmotion.x_root) - omx) / (sgeo[c->screen].width);
                    else if(tags[selscreen][seltag[selscreen]].layout.func == tile_top)
                         mwf -= (ROUND(ev.xmotion.y_root) - omy) / (sgeo[c->screen].height);
                    else
                         mwf += (ROUND(ev.xmotion.y_root) - omy) / (sgeo[c->screen].height);

                    omx = ROUND(ev.xmotion.x_root);
                    omy = ROUND(ev.xmotion.y_root);

                    tags[selscreen][seltag[selscreen]].mwfact = (mwf < 0.05) ? 0.05 : ((mwf > 0.95) ? 0.95 : mwf);
               }
               /* Free mode */
               else if(!(c->flags & TileFlag))
               {
                    mouse_dragborder(geo, gci);

                    if(pos == Right)
                    {
                         geo.width = ((ev.xmotion.x - c->geo.x < c->minw) ? c->minw : ev.xmotion.x - c->geo.x);
                         geo.height = ((ev.xmotion.y - c->geo.y < c->minh) ? c->minh : ev.xmotion.y - c->geo.y);
                    }
                    else
                    {
                         geo.x = (geo.width != c->maxw) ? c->geo.x - (c->geo.x - ev.xmotion.x) : geo.x;
                         geo.width  = ((c->geo.width + (c->geo.x - geo.x) < c->minw)
                                       ? c->minw && (geo.x = (c->geo.x + c->geo.width) - c->minw)
                                       : c->geo.width + (c->geo.x - geo.x));
                         geo.height = ((ev.xmotion.y - c->geo.y <= c->minh) ? c->minh : ev.xmotion.y - c->geo.y);
                    }

                    client_geo_hints(&geo, c);

                    mouse_dragborder((ogeo = geo), gci);

                    XSync(dpy, False);
               }
          }
     }
     while(ev.type != ButtonRelease);

     if(!(c->flags & TileFlag))
     {
          mouse_dragborder(ogeo, gci);
          client_moveresize(c, geo, True);
          frame_update(c);
          XUngrabServer(dpy);
     }
     else
          tags[selscreen][seltag[selscreen]].layout.func(c->screen);

     client_update_attributes(c);
     XUngrabPointer(dpy, CurrentTime);
     XFreeGC(dpy, gci);

     return;
}
Example #13
0
/** Move the client with the mouse
 * \param c Client pointer
*/
static void
mouse_move(Client *c)
{
     int ocx, ocy, mx, my;
     int dint;
     uint duint;
     Window dw;
     XRectangle geo = c->geo;
     XGCValues xgc;
     GC gci;
     XEvent ev;

     if((c->flags & MaxFlag) || (c->flags & FSSFlag))
          return;

     ocx =  c->geo.x;
     ocy =  c->geo.y;

     if(XGrabPointer(dpy, ROOT, False, MouseMask, GrabModeAsync, GrabModeAsync,
                     None, cursor[CurMove], CurrentTime) != GrabSuccess)
          return;

     if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
          XGrabServer(dpy);

     /* Set the GC for the rectangle */
     xgc.function = GXinvert;
     xgc.subwindow_mode = IncludeInferiors;
     xgc.line_width = BORDH;
     gci = XCreateGC(dpy, ROOT, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);

     if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
          mouse_dragborder(c->geo, gci);

     XQueryPointer(dpy, ROOT, &dw, &dw, &mx, &my, &dint, &dint, &duint);

     do
     {
          XMaskEvent(dpy, MouseMask | SubstructureRedirectMask, &ev);
          screen_get_sel();

          if(ev.type == MotionNotify)
          {
              mouse_move_tile_client(&c);
              mouse_move_tag_client(c);

               /* To move a client normally, in freelayout */
               if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
               {
                    mouse_dragborder(geo, gci);

                    geo.x = (ocx + (ev.xmotion.x - mx));
                    geo.y = (ocy + (ev.xmotion.y - my));

                    /*
                     * Need to draw 2 times the same rectangle because
                     * it is draw with the revert color; revert + revert = normal
                     */
                    mouse_dragborder(geo, gci);
               }
          }
          else if(ev.type == MapRequest
                  || ev.type == ConfigureRequest)
               getevent(ev);
     }
     while(ev.type != ButtonRelease);

     /* One time again to delete all the trace on the window */
     if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
     {
          mouse_dragborder(geo, gci);
          client_moveresize(c, geo, False);
          frame_update(c);
          XUngrabServer(dpy);
     }
     client_update_attributes(c);
     XUngrabPointer(dpy, CurrentTime);
     XFreeGC(dpy, gci);

     return;
}
Example #14
0
File: ewmh.c Project: n4cht/kwm
/** Manage the client hints
 *\param c Client pointer
*/
void
ewmh_manage_window_type(Client *c)
{
     Atom *atom, rf;
     int f;
     ulong n, il, i;
     uchar *data = NULL;
     long ldata[5] = { 0 };

     if(XGetWindowProperty(dpy, c->win, net_atom[net_wm_window_type], 0L, 0x7FFFFFFFL,
                           False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
     {
          atom = (Atom*)data;

          for(i = 0; i < n; ++i)
          {
               /* Manage _NET_WM_WINDOW_TYPE_DOCK & _NET_WM_WINDOW_TYPE_SPLASH */
               if(atom[i] == net_atom[net_wm_window_type_dock]
                  || atom[i] == net_atom[net_wm_window_type_splash])
               {
                    /* Unmap frame, decoration.. */
                    client_unmap(c);

                    /* Map only window */
                    XMapWindow(dpy, c->win);

                    /* Reparent it to ROOT win */
                    XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
                    XRaiseWindow(dpy, c->win);

                    c->flags |= DockFlag;
               }
               /* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
               else if(atom[i] == net_atom[net_wm_window_type_dialog])
               {
                    c->flags |= FreeFlag;
                    c->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
                    client_moveresize(c, c->ogeo, True);
                    client_focus(c);
                    tags[selscreen][seltag[selscreen]].layout.func(selscreen);
               }
          }
          XFree(data);
     }

     /* Get NET_WM_STATE set without sending client message event */
     if(XGetWindowProperty(dpy, c->win, net_atom[net_wm_state], 0L, 0x7FFFFFFFL,
                           False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
     {
          atom = (Atom*)data;

          for(i = 0; i < n; ++i)
          {
               ldata[0] = _NET_WM_STATE_ADD;
               ldata[1] = atom[i];
               ewmh_manage_net_wm_state(ldata, c);
          }
          XFree(data);
     }

     return;
}