示例#1
0
文件: FvwmPager.c 项目: att/uwin
void list_restack(unsigned long *body, unsigned long length)
{
  PagerWindow *t;
  Window target_w;
  Window *wins;
  int i, j, d;

  wins = (Window *) safemalloc (length * sizeof (Window));
  /* first restack in the icon view */
  j = 0;
  for (i = 0; i < (length - FvwmPacketHeaderSize); i += 3)
  {
    target_w = body[i];
    t = Start;
    while((t!= NULL)&&(t->w != target_w))
    {
      t = t->next;
    }
    if (t != NULL)
    {
      wins[j++] = t->IconView;
    }
  }
  XRestackWindows(dpy, wins, j);

  /* now restack each desk separately, since they have separate roots */
  for (d = 0; d < ndesks; d++)
  {
    j = 0;
    for (i = 0; i < (length - 4); i+=3)
    {
      target_w = body[i];
      t = Start;
      while((t!= NULL)&&((t->w != target_w)||(t->desk != d+desk1)))
      {
	t = t->next;
      }
      if (t != NULL)
      {
	if (t->PagerView != None)
	{
	  wins[j++] = t->PagerView;
	}
      }
    }
    XRestackWindows(dpy, wins, j);
  }
  free (wins);
}
示例#2
0
bool ThemeEngine::x11Event( XEvent* e )
{
    if( e->type != ConfigureNotify && e->type != MapNotify )
        return false;
    if( e->type == ConfigureNotify && e->xconfigure.event != qt_xrootwin())
        return false;
    if( e->type == MapNotify && e->xmap.event != qt_xrootwin())
        return false;
    if( d->mSplashWindows.count() == 0 )
        return false;
    // this restacking is written in a way so that
    // if the stacking positions actually don't change,
    // all restacking operations will be no-op,
    // and no ConfigureNotify will be generated,
    // thus avoiding possible infinite loops
    XRaiseWindow( qt_xdisplay(), d->mSplashWindows.first()); // raise topmost
    // and stack others below it
    Window* stack = new Window[ d->mSplashWindows.count() ];
    int count = 0;
    for( QValueList< Window >::ConstIterator it = d->mSplashWindows.begin();
         it != d->mSplashWindows.end();
         ++it )
        stack[ count++ ] = *it;
    XRestackWindows( x11Display(), stack, count );
    delete[] stack;
    return false;
}
示例#3
0
/*
 * Class:     XlibWrapper
 * Method:    XRestackWindows
 * Signature: (JJI)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XRestackWindows
(JNIEnv *env, jclass clazz, jlong display, jlong windows, jint length)
{
    
    AWT_CHECK_HAVE_LOCK();   
    XRestackWindows( (Display *)display,(Window*) windows, length);

}
示例#4
0
文件: tag.c 项目: Ismael-VC/goomwwm
// raise all windows in a tag
void tag_raise(unsigned int tag)
{
	int i, found = 0, shaded = 0; Window w; client *c;
	winlist *stack;

	// if this tag was previously hidden, reveal it
	clients_ascend(windows_shaded, i, w, c)
		if (c->manage && c->cache->tags & tag)
			{ client_reveal(c); shaded++; }
	if (shaded)
	{
		XSync(display, False);
		reset_cache_xattr();
		reset_cache_client();
		reset_cache_inplay();
	}

	stack = winlist_new();

	// locate windows with _NET_WM_STATE_ABOVE and _NET_WM_STATE_STICKY
	managed_descend(i, w, c)
		if (winlist_find(stack, w) < 0 && c->visible && c->trans == None
			&& client_has_state(c, netatoms[_NET_WM_STATE_ABOVE])
			&& client_has_state(c, netatoms[_NET_WM_STATE_STICKY]))
				client_stack_family(c, stack);
	// locate windows with _NET_WM_STATE_ABOVE in this tag
	tag_descend(i, w, c, tag)
		if (winlist_find(stack, w) < 0 && c->visible && c->trans == None
			&& client_has_state(c, netatoms[_NET_WM_STATE_ABOVE]))
				{ client_stack_family(c, stack); found++; }
	// locate _NET_WM_WINDOW_TYPE_DOCK windows
	clients_descend(windows_in_play(), i, w, c)
		if (winlist_find(stack, w) < 0 && c->visible && c->trans == None
			&& c->type == netatoms[_NET_WM_WINDOW_TYPE_DOCK])
				client_stack_family(c, stack);
	// locate all other windows in the tag
	tag_descend(i, w, c, tag)
		if (winlist_find(stack, w) < 0 && c->trans == None)
			{ client_stack_family(c, stack); found++; }

	// raise the top window in the stack
	if (stack->len) XRaiseWindow(display, stack->array[0]);
	// stack everything else, in order, underneath top window
	if (stack->len > 1) XRestackWindows(display, stack->array, stack->len);

	winlist_free(stack);
	tag_set_current(tag);
	if (config_only_auto) tag_only(tag);

	// focus the last-focused client in the tag
	clients_descend(windows_activated, i, w, c) if (c->cache->tags & tag)
		{ client_activate(c, RAISE, WARPDEF); break; }

	// in case no windows are in the tag, show some activity
	if (found) notice("Tag %d", tag_to_desktop(tag)+1);
	else notice("Tag %d (empty!)", tag_to_desktop(tag)+1);
}
示例#5
0
void WindowManager::restack_windows()
{
	Window *windows = new Window[1];
	int total=0;

	DBG("Restack: DOCK, SPLASH");
	for(uint n=0; n<stack_order.size(); n++)
	{
		Frame *f = stack_order[n];
		if(f->window_type()==TYPE_DOCK || f->window_type()==TYPE_SPLASH)
		{
			windows = (Window*)realloc(windows, (total+1)*sizeof(Window));
			windows[total++] = fl_xid(f);
		}
	}
	DBG("Restack: TOOLBAR, MENU");
	for(uint n=0; n<stack_order.size(); n++)
	{
		Frame *f = stack_order[n];
		if(f->window_type()==TYPE_TOOLBAR || f->window_type()==TYPE_MENU)
		{
			windows = (Window*)realloc(windows, (total+1)*sizeof(Window));
			windows[total++] = fl_xid(f);
		}
	}
	DBG("Restack: NORMAL, UTIL, DIALOG");
	for(uint n=stack_order.size(); n--;)
	{
		Frame *f = stack_order[n];
		if( (f->window_type()==TYPE_NORMAL ||
			f->window_type()==TYPE_UTIL ||
			f->window_type()==TYPE_DIALOG) &&
			f->state()==NORMAL )
		{
			windows = (Window*)realloc(windows, (total+1)*sizeof(Window));
			windows[total++] = fl_xid(f);
		}
	}
	DBG("Restack: DESKTOP");
	for(uint n=0; n<stack_order.size(); n++)
	{
		Frame *f = stack_order[n];
		if(f->window_type()==TYPE_DESKTOP)
		{
			windows = (Window*)realloc(windows, (total+1)*sizeof(Window));
			windows[total++] = fl_xid(f);
		}
	}

	DBG("Restack: Call XRestackWindows!");
	if(total) XRestackWindows(fl_display, windows, total);
	delete []windows;
}
示例#6
0
int raiseWindow(Display *display, Window window) {
    Window parent, root, *children, *neworder;
    unsigned int nchildren, i, rotate;
    XWindowAttributes attr;

    if (!XQueryTree(display, DefaultRootWindow(display), &root, &parent,
                   &children, &nchildren))
        return 1;
    if (!children)
        return 2;

    for (rotate = 0; rotate < nchildren; ++rotate) {
        if (children[nchildren-1 - rotate] == window)
            break;
    }
    if (rotate == nchildren) {
        XFree(children);
        return 2;
    }

    if (rotate > 0) {
        /* Unmap and remap the old top-level window to kill off any mouse and
         * keyboard hooks */
        XUnmapWindow(display, children[nchildren-1]);

        neworder = (Window*)malloc(nchildren * sizeof(*neworder));
        /* XQueryTree returns children in back-to-front order, while
         * XRestackWindows takes a front-to-back list. Reverse the order and
         * rotate the position of the children -n positions to put the requested
         * window into the first position in the list.
         */
        for (i = 0; i < nchildren; ++i) {
            neworder[nchildren-1 - ((i+rotate) % nchildren)] = children[i];
        }
        XRestackWindows(display, neworder, nchildren);
        free(neworder);

        /* Split the map from the unmap to reduce the number of events */
        XMapWindow(display, children[nchildren-1]);
    }
    XFree(children);

    if (!XGetWindowAttributes(display, DefaultRootWindow(display), &attr)) {
        return 1;
    }
    /* Twiddle the width of the window to force a full refresh */
    XMoveResizeWindow(display, window,
                      attr.x, attr.y, attr.width-1, attr.height);
    XMoveResizeWindow(display, window,
                      attr.x, attr.y, attr.width,   attr.height);

    return 0;
}
示例#7
0
static bool referenceRestack(const T &subset,
                     Window **childrenp=NULL, unsigned *nchildrenp=NULL)
{
    int n = subset.count();
    WindowVec reversed(n);
    for (int i = 0; i < n; i++)
        reversed[n-1-i] = subset[i];

    Q_ASSERT(Dpy != NULL);
    if (!XRestackWindows(Dpy,
                        (Window*)reversed.constData(), reversed.count()))
        qFatal("XRestackWindows() failed");
    return verifyTree(subset, childrenp, nchildrenp);
}
示例#8
0
文件: stacking.c 项目: sylware/lboxwm
void stacking_restore(void)
{
	Window *win;
	GList *it;
	gint i;
	gulong start;
	win = g_new(Window, g_list_length(stacking_list) + 1);
	win[0] = screen_support_win;
	for(i = 1, it = stacking_list; it; ++i, it = g_list_next(it))
		win[i] = window_top(it->data);
	start = event_start_ignore_all_enters();
	XRestackWindows(t_display, win, i);
	event_end_ignore_all_enters(start);
	g_free(win);
	pause_changes = FALSE;
}
示例#9
0
文件: cycling.c 项目: jafd/wmaker
static void raiseWindow(WSwitchPanel * swpanel, WWindow * wwin)
{
	Window swwin = wSwitchPanelGetWindow(swpanel);

	if (wwin->flags.mapped) {
		if (swwin != None) {
			Window win[2];

			win[0] = swwin;
			win[1] = wwin->frame->core->window;

			XRestackWindows(dpy, win, 2);
		} else
			XRaiseWindow(dpy, wwin->frame->core->window);
	}
}
示例#10
0
文件: layers.cpp 项目: lmurray/kwin
/**
 * Raise electric border windows to the real top of the screen. We only need
 * to do this if an effect input window is active.
 */
void Workspace::raiseElectricBorderWindows()
    {
    Window* windows = new Window[ 8 ]; // There are up to 8 borders
    int pos = 0;
    for( int i = 0; i < ELECTRIC_COUNT; ++i )
        if( electric_windows[ i ] != None )
            windows[ pos++ ] = electric_windows[ i ];
    if( !pos )
        {
        delete [] windows;
        return; // No borders at all
        }
    XRaiseWindow( display(), windows[ 0 ] );
    XRestackWindows( display(), windows, pos );
    delete [] windows;
    }
示例#11
0
文件: misc.c 项目: morgant/mlvwm
void RaiseMlvwmWindow( MlvwmWindow *win )
{
	MlvwmWindow *tmp, *lastwin=NULL;
	int count=4, set=3;
	Window *wins;

	for( tmp = Scr.MlvwmRoot.next; tmp!=NULL; tmp=tmp->next ){
		if( tmp->flags&TRANSIENT && tmp->transientfor==win->w && tmp!=win 
		   && !(tmp->flags&ONTOP) )
			count++;
		if( tmp->flags&ONTOP && tmp!=win )
			count++;
		if( tmp->next==NULL )
			lastwin = tmp;
	}
	wins = calloc( count, sizeof(Window) );
	wins[0] = Scr.MenuBar;
	wins[1] = Scr.lbCorner;
	wins[2] = Scr.rbCorner;

	for( tmp = Scr.MlvwmRoot.next; tmp!=NULL; tmp=tmp->next ){
		if( win->flags&TRANSIENT && win->transientfor==tmp->w
		   && tmp->flags&ONTOP ){
			wins[set++] = win->frame;
		}
		if( tmp!=win && tmp->flags&ONTOP )
			wins[set++] = tmp->frame;
	}
	for( tmp = lastwin; tmp!=&Scr.MlvwmRoot; tmp=tmp->prev )
		if( tmp->flags&TRANSIENT && tmp->transientfor==win->w && tmp!=win 
		   && !(tmp->flags&ONTOP))
			wins[set++] = tmp->frame;
	if( count!=set )
		wins[set++] = win->frame;

	XRaiseWindow( dpy, wins[0] );
	XRaiseWindow( dpy, wins[1] );
	XRaiseWindow( dpy, wins[2] );
	XRestackWindows( dpy, wins, set );

	free( wins );
}
示例#12
0
文件: stacking.c 项目: sylware/lboxwm
void stacking_temp_raise(struct wm_window *window)
{
	Window win[2];
	GList *it;
	gulong start;
	g_assert(window_layer(window) < WM_STACKING_LAYER_INTERNAL);
	win[0] = screen_support_win;
	for(it = stacking_list; it; it = g_list_next(it)) {
		struct wm_window *w = it->data;
		if(window_layer(w) >= WM_STACKING_LAYER_INTERNAL)
			win[0] = window_top(w);
		else
			break;
	}
	win[1] = window_top(window);
	start = event_start_ignore_all_enters();
	XRestackWindows(t_display, win, 2);
	event_end_ignore_all_enters(start);
	pause_changes = TRUE;
}
示例#13
0
文件: stacking.c 项目: sylware/lboxwm
static void do_restack(GList *wins, GList *before)
{
	GList *it;
	Window *win;
	gint i;
#ifdef DEBUG
	GList *next;
	g_assert(wins);
	for(it = wins; it; it = next) {
		next = g_list_next(it);
		if(!next)
			break;
		g_assert(window_layer(it->data) == window_layer(next->data));
	}
	if(before)
		g_assert(window_layer(it->data) >= window_layer(before->data));
#endif
	win = g_new(Window, g_list_length(wins) + 1);
	if(before == stacking_list)
		win[0] = screen_support_win;
	else if(!before)
		win[0] = window_top(g_list_last(stacking_list)->data);
	else
		win[0] = window_top(g_list_previous(before)->data);
	for(i = 1, it = wins; it; ++i, it = g_list_next(it)) {
		win[i] = window_top(it->data);
		g_assert(win[i] != None);
		stacking_list = g_list_insert_before(stacking_list, before, it->data);
	}
#ifdef DEBUG
	for(it = stacking_list;; it = next) {
		next = g_list_next(it);
		if(!next)
			break;
		g_assert(window_layer(it->data) >= window_layer(next->data));
	}
#endif
	if(!pause_changes)
		XRestackWindows(t_display, win, i);
	g_free(win);
}
示例#14
0
static DWORD
DrvStackingOrder(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct)
{
    HWND hWndInsertAfter = (HWND)dwParm1;
    HWND WinAfter = (HWND)dwParm2;
    Window win = (Window)lpStruct;
    Window win_restack[2];
    PRIVATEDISPLAY *Disp = GETDP();
    int nFunc = (int)hWndInsertAfter;

    switch (nFunc) {
	case (int)HWND_TOP:
#ifdef	LATER
	/* this should be resolved at the upper level */
#else
	case (int)HWND_TOPMOST:
#endif
	    XRaiseWindow(Disp->display, win);
	    break;

	case (int)HWND_BOTTOM:
#ifdef	LATER
	/* this should be resolved at the upper level */
#else
	case (int)HWND_NOTOPMOST:
#endif
	    XLowerWindow(Disp->display, win);
	    break;

	default:
	    /*  this means a real hWndInsertAfter */
	    win_restack[0] = WinAfter;
	    win_restack[1] = win;
	    XRestackWindows(Disp->display, win_restack, 2);
	    break;
    }

    return 1L;
}
示例#15
0
void swapLayer(int num1,int num2){
  int i;
  Window windows[MAX_LAYER];

  for(i=0;i<layer_num;i++){
    if(stack[i]==num1){
      stack[i]=num2;
    }else if(stack[i]==num2){
      stack[i]=num1;
    }
  }


  for(i=0;i<layer_num;i++){
    windows[i]=layer[stack[i]].win;
  }
  XRestackWindows(dis, windows, layer_num); 

  //remapCanvas();
  remapLayerMenu();

}
示例#16
0
void WindowManager::restack_windows(void)
{
	TRACE_FUNCTION("void WindowManager::restack_windows(void)");

	Window* stack = new Window[aot_list.size() + stack_list.size()];
	FrameList::iterator it = aot_list.begin();
	FrameList::iterator last = aot_list.end();
	unsigned int i = 0;

	for(; it != last && i < aot_list.size(); ++it, i++)
		stack[i] = fl_xid(*it);

	it = stack_list.begin();
	last = stack_list.end();


	for(; it != last && i < aot_list.size() + stack_list.size(); ++it, i++)
		stack[i] = fl_xid(*it);

	XRestackWindows(fl_display, stack, stack_list.size());
	delete [] stack;
}
示例#17
0
void
appIconMouseDown(WObjDescriptor *desc, XEvent *event)
{
    WAppIcon *aicon = desc->parent;
    WIcon *icon = aicon->icon;
    XEvent ev;
    int x=aicon->x_pos, y=aicon->y_pos;
    int dx=event->xbutton.x, dy=event->xbutton.y;
    int grabbed=0;
    int done=0;
    int superfluous = wPreferences.superfluous; /* we catch it to avoid problems */
    WScreen *scr = icon->core->screen_ptr;
    WWorkspace *workspace = scr->workspaces[scr->current_workspace];
    int shad_x = 0, shad_y = 0, docking=0, dockable, collapsed = 0;
    int ix, iy;
    int clickButton = event->xbutton.button;
    Pixmap ghost = None;
    Window wins[2];
    Bool movingSingle = False;
    int oldX = x;
    int oldY = y;
    Bool hasMoved = False;

    if (aicon->editing || WCHECK_STATE(WSTATE_MODAL))
        return;

    if (IsDoubleClick(scr, event)) {
        iconDblClick(desc, event);
        return;
    }

    if (event->xbutton.button == Button3) {
        WObjDescriptor *desc;
        WApplication *wapp = wApplicationOf(aicon->icon->owner->main_window);

        if (!wapp)
            return;

        if (event->xbutton.send_event &&
            XGrabPointer(dpy, aicon->icon->core->window, True, ButtonMotionMask
                         |ButtonReleaseMask|ButtonPressMask, GrabModeAsync,
                         GrabModeAsync, None, None, CurrentTime) !=GrabSuccess) {
            wwarning("pointer grab failed for appicon menu");
            return;
        }

        openApplicationMenu(wapp, event->xbutton.x_root,
                            event->xbutton.y_root);

        /* allow drag select of menu */
        desc = &scr->icon_menu->menu->descriptor;
        event->xbutton.send_event = True;
        (*desc->handle_mousedown)(desc, event);
        return;
    }

#ifdef DEBUG
    puts("Moving icon");
#endif
    if (event->xbutton.state & MOD_MASK)
        wLowerFrame(icon->core);
    else
        wRaiseFrame(icon->core);

    if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask
                     |ButtonReleaseMask|ButtonPressMask, GrabModeAsync,
                     GrabModeAsync, None, None, CurrentTime) !=GrabSuccess) {
        wwarning("pointer grab failed for appicon move");
    }

    if (wPreferences.flags.nodock && wPreferences.flags.noclip)
        dockable = 0;
    else
        dockable = canBeDocked(icon->owner);

    wins[0] = icon->core->window;
    wins[1] = scr->dock_shadow;
    XRestackWindows(dpy, wins, 2);
    if (superfluous) {
        if (icon->pixmap!=None)
            ghost = MakeGhostIcon(scr, icon->pixmap);
        else
            ghost = MakeGhostIcon(scr, icon->core->window);
        XSetWindowBackgroundPixmap(dpy, scr->dock_shadow,
                                   ghost);
        XClearWindow(dpy, scr->dock_shadow);
    }

    while (!done) {
        WMMaskEvent(dpy, PointerMotionMask|ButtonReleaseMask|ButtonPressMask
                    |ButtonMotionMask|ExposureMask, &ev);
        switch (ev.type) {
        case Expose:
            WMHandleEvent(&ev);
            break;

        case MotionNotify:
            hasMoved = True;
            if (!grabbed) {
                if (abs(dx-ev.xmotion.x)>=MOVE_THRESHOLD
                    || abs(dy-ev.xmotion.y)>=MOVE_THRESHOLD) {
                    XChangeActivePointerGrab(dpy, ButtonMotionMask
                                             |ButtonReleaseMask|ButtonPressMask,
                                             wCursor[WCUR_MOVE], CurrentTime);
                    grabbed=1;
                } else {
                    break;
                }
            }
            x = ev.xmotion.x_root - dx;
            y = ev.xmotion.y_root - dy;

            if (movingSingle) {
                XMoveWindow(dpy, icon->core->window, x, y);
            } else {
                wAppIconMove(aicon, x, y);
            }

            if (dockable) {
                if (scr->dock && wDockSnapIcon(scr->dock, aicon, x, y,
                                               &ix, &iy, False)) {
                    shad_x = scr->dock->x_pos + ix*wPreferences.icon_size;
                    shad_y = scr->dock->y_pos + iy*wPreferences.icon_size;

                    if (scr->last_dock != scr->dock && collapsed) {
                        scr->last_dock->collapsed = 1;
                        wDockHideIcons(scr->last_dock);
                        collapsed = 0;
                    }
                    if (!collapsed && (collapsed = scr->dock->collapsed)) {
                        scr->dock->collapsed = 0;
                        wDockShowIcons(scr->dock);
                    }

                    if (scr->dock->auto_raise_lower)
                        wDockRaise(scr->dock);

                    scr->last_dock = scr->dock;

                    XMoveWindow(dpy, scr->dock_shadow, shad_x, shad_y);
                    if (!docking) {
                        XMapWindow(dpy, scr->dock_shadow);
                    }
                    docking = 1;
                } else if (workspace->clip &&
                           wDockSnapIcon(workspace->clip, aicon, x, y,
                                         &ix, &iy, False)) {
                    shad_x = workspace->clip->x_pos + ix*wPreferences.icon_size;
                    shad_y = workspace->clip->y_pos + iy*wPreferences.icon_size;

                    if (scr->last_dock != workspace->clip && collapsed) {
                        scr->last_dock->collapsed = 1;
                        wDockHideIcons(scr->last_dock);
                        collapsed = 0;
                    }
                    if (!collapsed && (collapsed = workspace->clip->collapsed)) {
                        workspace->clip->collapsed = 0;
                        wDockShowIcons(workspace->clip);
                    }

                    if (workspace->clip->auto_raise_lower)
                        wDockRaise(workspace->clip);

                    scr->last_dock = workspace->clip;

                    XMoveWindow(dpy, scr->dock_shadow, shad_x, shad_y);
                    if (!docking) {
                        XMapWindow(dpy, scr->dock_shadow);
                    }
                    docking = 1;
                } else if (docking) {
                    XUnmapWindow(dpy, scr->dock_shadow);
                    docking = 0;
                }
            }

            break;

        case ButtonPress:
            break;

        case ButtonRelease:
            if (ev.xbutton.button != clickButton)
                break;
            XUngrabPointer(dpy, CurrentTime);

            if (docking) {
                Bool docked;

                /* icon is trying to be docked */
                SlideWindow(icon->core->window, x, y, shad_x, shad_y);
                XUnmapWindow(dpy, scr->dock_shadow);
                docked = wDockAttachIcon(scr->last_dock, aicon, ix, iy);
                if (scr->last_dock->auto_collapse) {
                    collapsed = 0;
                }
                if (workspace->clip &&
                    workspace->clip != scr->last_dock &&
                    workspace->clip->auto_raise_lower)
                    wDockLower(workspace->clip);

                if (!docked) {
                    /* If icon could not be docked, slide it back to the old
                     * position */
                    SlideWindow(icon->core->window, x, y, oldX, oldY);
                }

                wSoundPlay(WSOUND_DOCK);
            } else {
                if (movingSingle) {
                    /* move back to its place */
                    SlideWindow(icon->core->window, x, y, oldX, oldY);
                    wAppIconMove(aicon, oldX, oldY);
                } else {
                    XMoveWindow(dpy, icon->core->window, x, y);
                    aicon->x_pos = x;
                    aicon->y_pos = y;
                }
                if (workspace->clip && workspace->clip->auto_raise_lower)
                    wDockLower(workspace->clip);
            }
            if (collapsed) {
                scr->last_dock->collapsed = 1;
                wDockHideIcons(scr->last_dock);
                collapsed = 0;
            }
            if (superfluous) {
                if (ghost!=None)
                    XFreePixmap(dpy, ghost);
                XSetWindowBackground(dpy, scr->dock_shadow, scr->white_pixel);
            }

            if (wPreferences.auto_arrange_icons)
                wArrangeIcons(scr, True);

            if (wPreferences.single_click && !hasMoved)
                iconDblClick(desc, event);

            done = 1;
            break;
        }
    }
#ifdef DEBUG
    puts("End icon move");
#endif

}
示例#18
0
文件: stack.c 项目: collinss/muffin
/*
 * Order the windows on the X server to be the same as in our structure.
 * We do this using XRestackWindows if we don't know the previous order,
 * or XConfigureWindow on a few particular windows if we do and can figure
 * out the minimum set of changes.  After that, we set __NET_CLIENT_LIST
 * and __NET_CLIENT_LIST_STACKING.
 *
 * FIXME: Now that we have a good view of the stacking order on the server
 * with MetaStackTracker it should be possible to do a simpler and better
 * job of computing the minimal set of stacking requests needed.
 */
static void
stack_sync_to_server (MetaStack *stack)
{
  GArray *stacked;
  GArray *root_children_stacked;
  GList *tmp;
  GArray *all_hidden;
  int n_override_redirect = 0;
  int n_unmanaging = 0;
  
  /* Bail out if frozen */
  if (stack->freeze_count > 0)
    return;
  
  meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");  

  stack_ensure_sorted (stack);

  /* Create stacked xwindow arrays.
   * Painfully, "stacked" is in bottom-to-top order for the
   * _NET hints, and "root_children_stacked" is in top-to-bottom
   * order for XRestackWindows()
   */
  stacked = g_array_new (FALSE, FALSE, sizeof (Window));
  root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
  all_hidden = g_array_new (FALSE, FALSE, sizeof (Window));

  /* The screen guard window sits above all hidden windows and acts as
   * a barrier to input reaching these windows. */
  g_array_append_val (all_hidden, stack->screen->guard_window);

  meta_topic (META_DEBUG_STACK, "Top to bottom: ");
  meta_push_no_msg_prefix ();

  for (tmp = stack->sorted; tmp != NULL; tmp = tmp->next)
    {
      MetaWindow *w = tmp->data;
      Window top_level_window;

      if (w->unmanaging)
        {
          n_unmanaging ++;
          continue;
        }
      
      meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
		  w->layer, w->stack_position, w->desc);

      /* remember, stacked is in reverse order (bottom to top) */
      if (w->override_redirect)
	n_override_redirect++;
      else
	g_array_prepend_val (stacked, w->xwindow);
      
      if (w->frame)
	top_level_window = w->frame->xwindow;
      else
	top_level_window = w->xwindow;

      /* We don't restack hidden windows along with the rest, though they are
       * reflected in the _NET hints. Hidden windows all get pushed below
       * the screens fullscreen guard_window. */
      if (w->hidden)
	{
	  g_array_append_val (all_hidden, top_level_window);
	  continue;
	}

      /* build XRestackWindows() array from top to bottom */
      g_array_append_val (root_children_stacked, top_level_window);
    }

  meta_topic (META_DEBUG_STACK, "\n");
  meta_pop_no_msg_prefix ();

  /* All windows should be in some stacking order */
  if (stacked->len != stack->windows->len - n_override_redirect - n_unmanaging)
    meta_bug ("%u windows stacked, %u windows exist in stack\n",
              stacked->len, stack->windows->len);
  
  /* Sync to server */

  meta_topic (META_DEBUG_STACK, "Restacking %u windows\n",
              root_children_stacked->len);
  
  meta_error_trap_push (stack->screen->display);

  if (stack->last_root_children_stacked == NULL)
    {
      /* Just impose our stack, we don't know the previous state.
       * This involves a ton of circulate requests and may flicker.
       */
      meta_topic (META_DEBUG_STACK, "Don't know last stack state, restacking everything\n");

      if (root_children_stacked->len > 0)
        {
          meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker,
                                                     (Window *) root_children_stacked->data,
                                                     root_children_stacked->len,
                                                     XNextRequest (stack->screen->display->xdisplay));
          XRestackWindows (stack->screen->display->xdisplay,
                           (Window *) root_children_stacked->data,
                           root_children_stacked->len);
        }
    }
  else if (root_children_stacked->len > 0)
    {
      /* Try to do minimal window moves to get the stack in order */
      /* A point of note: these arrays include frames not client windows,
       * so if a client window has changed frame since last_root_children_stacked
       * was saved, then we may have inefficiency, but I don't think things
       * break...
       */
      const Window *old_stack = (Window *) stack->last_root_children_stacked->data;
      const Window *new_stack = (Window *) root_children_stacked->data;
      const int old_len = stack->last_root_children_stacked->len;
      const int new_len = root_children_stacked->len;
      const Window *oldp = old_stack;
      const Window *newp = new_stack;
      const Window *old_end = old_stack + old_len;
      const Window *new_end = new_stack + new_len;
      Window last_window = None;
      
      while (oldp != old_end &&
             newp != new_end)
        {
          if (*oldp == *newp)
            {
              /* Stacks are the same here, move on */
              ++oldp;
              last_window = *newp;
              ++newp;
            }
          else if (meta_display_lookup_x_window (stack->screen->display,
                                                 *oldp) == NULL)
            {
              /* *oldp is no longer known to us (probably destroyed),
               * so we can just skip it
               */
              ++oldp;
            }
          else
            {
              /* Move *newp below last_window */
              if (last_window == None)
                {
                  meta_topic (META_DEBUG_STACK, "Using window 0x%lx as topmost (but leaving it in-place)\n", *newp);

                  raise_window_relative_to_managed_windows (stack->screen,
                                                            *newp);
                }
              else
                {
                  /* This means that if last_window is dead, but not
                   * *newp, then we fail to restack *newp; but on
                   * unmanaging last_window, we'll fix it up.
                   */
                  
                  XWindowChanges changes;

                  changes.sibling = last_window;
                  changes.stack_mode = Below;

                  meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n",
                              *newp, last_window);

                  meta_stack_tracker_record_lower_below (stack->screen->stack_tracker,
                                                         *newp, last_window,
                                                         XNextRequest (stack->screen->display->xdisplay));
                  XConfigureWindow (stack->screen->display->xdisplay,
                                    *newp,
                                    CWSibling | CWStackMode,
                                    &changes);
                }

              last_window = *newp;
              ++newp;
            }
        }

      if (newp != new_end)
        {
          /* Restack remaining windows */
          meta_topic (META_DEBUG_STACK, "Restacking remaining %d windows\n",
                        (int) (new_end - newp));
          /* We need to include an already-stacked window
           * in the restack call, so we get in the proper position
           * with respect to it.
           */
          if (newp != new_stack)
            --newp;
          meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker,
                                                     (Window *) newp, new_end - newp,
                                                     XNextRequest (stack->screen->display->xdisplay));
          XRestackWindows (stack->screen->display->xdisplay,
                           (Window *) newp, new_end - newp);
        }
    }

  /* Push hidden windows to the bottom of the stack under the guard window */
  meta_stack_tracker_record_lower (stack->screen->stack_tracker,
                                   stack->screen->guard_window,
                                   XNextRequest (stack->screen->display->xdisplay));
  XLowerWindow (stack->screen->display->xdisplay, stack->screen->guard_window);
  meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker,
                                             (Window *)all_hidden->data,
                                             all_hidden->len,
                                             XNextRequest (stack->screen->display->xdisplay));
  XRestackWindows (stack->screen->display->xdisplay,
		   (Window *)all_hidden->data,
		   all_hidden->len);
  g_array_free (all_hidden, TRUE);

  meta_error_trap_pop (stack->screen->display);
  /* on error, a window was destroyed; it should eventually
   * get removed from the stacking list when we unmanage it
   * and we'll fix stacking at that time.
   */
  
  /* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */

  XChangeProperty (stack->screen->display->xdisplay,
                   stack->screen->xroot,
                   stack->screen->display->atom__NET_CLIENT_LIST,
                   XA_WINDOW,
                   32, PropModeReplace,
                   (unsigned char *)stack->windows->data,
                   stack->windows->len);
  XChangeProperty (stack->screen->display->xdisplay,
                   stack->screen->xroot,
                   stack->screen->display->atom__NET_CLIENT_LIST_STACKING,
                   XA_WINDOW,
                   32, PropModeReplace,
                   (unsigned char *)stacked->data,
                   stacked->len);

  g_array_free (stacked, TRUE);

  if (stack->last_root_children_stacked)
    g_array_free (stack->last_root_children_stacked, TRUE);
  stack->last_root_children_stacked = root_children_stacked;

  /* That was scary... */
}
示例#19
0
文件: x.c 项目: Limsik/e17
void
EXRestackWindows(Window * windows, int nwindows)
{
   XRestackWindows(disp, windows, nwindows);
}
示例#20
0
文件: appicon.c 项目: awmaker/awmaker
Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
{
	WIcon *icon = aicon->icon;
	virtual_screen *vscr = aicon->icon->vscr;
	WScreen *scr = vscr->screen_ptr;
	WDock *originalDock = aicon->dock; /* can be NULL */
	WDock *lastDock = originalDock;
	WDock *allDocks[vscr->drawer.drawer_count + 2]; /* clip, dock and drawers (order determined at runtime) */
	WDrawerChain *dc;
	Bool dockable = True;
	Bool ondock = True;
	Bool grabbed = False;
	Bool collapsed = False; /* Stores the collapsed state of lastDock, before the moving appicon entered it */
	int superfluous = wPreferences.superfluous; /* we cache it to avoid problems */
	int omnipresent = aicon->omnipresent; /* this must be cached */
	Bool showed_all_clips = False;

	int clickButton = event->xbutton.button;
	Pixmap ghost = None;
	Window wins[2]; /* Managing shadow window */
	XEvent ev;

	int x = aicon->x_pos, y = aicon->y_pos;
	int ofs_x = event->xbutton.x, ofs_y = event->xbutton.y;
	int shad_x = x, shad_y = y;
	int ix = aicon->xindex, iy = aicon->yindex;
	int i;
	int oldX = x;
	int oldY = y;
	Bool hasMoved = False;

	if (wPreferences.flags.noupdates && originalDock != NULL)
		return False;

	if (event->xbutton.state & MOD_MASK) {
		/*
		 * If Mod is pressed for an docked appicon,
		 * assume it is to undock it,so don't lower it
		 */
		if (originalDock == NULL)
			wLowerFrame(icon->vscr, icon->core);
	} else {
		wRaiseFrame(icon->vscr, icon->core);
	}

	if (XGrabPointer(dpy, icon->core->window, True,
			 ButtonMotionMask | ButtonReleaseMask | ButtonPressMask,
			 GrabModeAsync, GrabModeAsync, None, None,
			 CurrentTime) != GrabSuccess)
		wwarning("Pointer grab failed in wHandleAppIconMove");

	if (originalDock == NULL) {
		ondock = False;
		if (wPreferences.flags.nodock && wPreferences.flags.noclip && wPreferences.flags.nodrawer)
			dockable = False;
		else
			dockable = canBeDocked(icon->owner);
	}

	/*
	 * We try the various docks in that order:
	 * - First, the dock the appicon comes from, if any
	 * - Then, the drawers
	 * - Then, the "dock" (WM_DOCK)
	 * - Finally, the clip
	 */
	i = 0;
	if (originalDock != NULL)
		allDocks[i++] = originalDock;

	/* Testing vscr->drawers is enough, no need to test wPreferences.flags.nodrawer */
	for (dc = vscr->drawer.drawers; dc != NULL; dc = dc->next)
		if (dc->adrawer != originalDock)
			allDocks[i++] = dc->adrawer;

	if (!wPreferences.flags.nodock && vscr->dock.dock != originalDock)
		allDocks[i++] = vscr->dock.dock;

	if (!wPreferences.flags.noclip &&
	    originalDock != vscr->workspace.array[vscr->workspace.current]->clip)
		allDocks[i++] = vscr->workspace.array[vscr->workspace.current]->clip;

	/* In case the clip, the dock, or both, are disabled */
	for ( ; i < vscr->drawer.drawer_count + 2; i++)
		allDocks[i] = NULL;

	wins[0] = icon->core->window;
	wins[1] = scr->dock_shadow;
	XRestackWindows(dpy, wins, 2);
	XMoveResizeWindow(dpy, scr->dock_shadow, aicon->x_pos, aicon->y_pos, ICON_SIZE, ICON_SIZE);

	if (superfluous) {
		if (icon->pixmap != None)
			ghost = MakeGhostIcon(vscr, icon->pixmap);
		else
			ghost = MakeGhostIcon(vscr, icon->core->window);

		XSetWindowBackgroundPixmap(dpy, scr->dock_shadow, ghost);
		XClearWindow(dpy, scr->dock_shadow);
	}

	if (ondock)
		XMapWindow(dpy, scr->dock_shadow);

	while (1) {
		WMMaskEvent(dpy,
			    PointerMotionMask | ButtonReleaseMask | ButtonPressMask |
			    ButtonMotionMask | ExposureMask | EnterWindowMask, &ev);

		switch (ev.type) {
		case Expose:
			WMHandleEvent(&ev);
			break;

		case EnterNotify:
			/*
			 * It means the cursor moved so fast that it entered
			 * something else (if moving slowly, it would have
			 * stayed in the appIcon that is being moved. Ignore
			 * such "spurious" EnterNotifiy's
			 */
			break;

		case MotionNotify:
			hasMoved = True;
			appicon_move_motion(vscr, scr, ev, &lastDock,
					    &originalDock, aicon,
					    allDocks, &collapsed,
					    &dockable, &ondock,
					    &x, &y, &ix, &iy,
					    &shad_x, &shad_y,
					    &ofs_x, &ofs_y,
					    &grabbed, omnipresent,
					    &showed_all_clips);
			break;

		case ButtonPress:
			break;

		case ButtonRelease:
			if (ev.xbutton.button != clickButton)
				break;

			appicon_move_button_release(originalDock, lastDock,
						    aicon, icon, x, y,
						    oldX, oldY, shad_x, shad_y,
						    ix, iy, &collapsed, ondock,
						    ghost, showed_all_clips);
			return hasMoved;
		}
	}
}