Пример #1
0
void unpaint_app_icon(WApplication *wapp)
{
	WAppIcon *aicon;
	virtual_screen *vscr;
	WDock *clip;

	if (!wapp || !wapp->app_icon)
		return;

	aicon = wapp->app_icon;

	/* If the icon is docked, don't continue */
	if (aicon->docked)
		return;

	vscr = wapp->main_window_desc->vscr;
	clip = vscr->workspace.array[vscr->workspace.current]->clip;

	if (!clip || !aicon->attracted || !clip->collapsed)
		XUnmapWindow(dpy, aicon->icon->core->window);

	/* We want to avoid having it on the list  because otherwise
	 * there will be a hole when the icons are arranged with
	 * wArrangeIcons() */
	remove_from_appicon_list(aicon);

	if (wPreferences.auto_arrange_icons && !aicon->attracted)
		wArrangeIcons(vscr, True);
}
Пример #2
0
void paint_app_icon(WApplication *wapp)
{
	WIcon *icon;
	virtual_screen *vscr;
	WDock *attracting_dock;
	int x = 0, y = 0;
	Bool update_icon = False;

	if (!wapp || !wapp->app_icon || !wapp->main_window_desc)
		return;

	icon = wapp->app_icon->icon;
	vscr = wapp->main_window_desc->vscr;
	wapp->app_icon->main_window = wapp->main_window;

	/* If the icon is docked, don't continue */
	if (wapp->app_icon->docked)
		return;

	attracting_dock = vscr->drawer.attracting_drawer != NULL ?
		vscr->drawer.attracting_drawer :
		vscr->workspace.array[vscr->workspace.current]->clip;

	if (attracting_dock && attracting_dock->attract_icons &&
		wDockFindFreeSlot(attracting_dock, &x, &y)) {
		wapp->app_icon->attracted = 1;
		if (!icon->shadowed) {
			icon->shadowed = 1;
			update_icon = True;
		}

		wDockAttachIcon(attracting_dock, wapp->app_icon, x, y, update_icon);
	} else {
		/* We must know if the icon is painted in the screen,
		 * because if painted, then PlaceIcon will return the next
		 * space on the screen, and the icon will move */
		if (wapp->app_icon->next == NULL && wapp->app_icon->prev == NULL) {
			PlaceIcon(vscr, &x, &y, wGetHeadForWindow(wapp->main_window_desc));
			wAppIconMove(wapp->app_icon, x, y);
			wLowerFrame(icon->vscr, icon->core);
		}
	}

	/* If we want appicon (no_appicon is not set) and the icon is not
	 * in the appicon_list, we must add it. Else, we want to avoid
	 * having it on the list */
	if (!WFLAGP(wapp->main_window_desc, no_appicon) &&
	    wapp->app_icon->next == NULL && wapp->app_icon->prev == NULL)
		add_to_appicon_list(wapp->app_icon);

	if (!attracting_dock || !wapp->app_icon->attracted || !attracting_dock->collapsed)
		XMapWindow(dpy, icon->core->window);

	if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
		wArrangeIcons(vscr, True);
}
Пример #3
0
static void appicon_move_button_release(WDock *originalDock, WDock *lastDock,
					WAppIcon *aicon, WIcon *icon, int x, int y,
					int oldX, int oldY, int shad_x, int shad_y,
					int ix, int iy, Bool *collapsed, Bool ondock,
					Bool ghost, Bool showed_all_clips)
{
	virtual_screen *vscr = aicon->icon->vscr;
	WScreen *scr = vscr->screen_ptr;
	int i, superfluous = wPreferences.superfluous;
	Bool docked = False;

	XUngrabPointer(dpy, CurrentTime);

	if (ondock)
		appicon_move_to_dock(originalDock, lastDock,
				     aicon, icon, x, y,
				     oldX, oldY, shad_x, shad_y,
				     ix, iy, &docked, collapsed);
	else
		appicon_move_or_detach(originalDock, aicon, x, y);

	if (superfluous) {
		if (ghost != None)
			XFreePixmap(dpy, ghost);

		XSetWindowBackground(dpy, scr->dock_shadow, scr->white_pixel);
	}

	if (showed_all_clips) {
		for (i = 0; i < vscr->workspace.count; i++) {
			if (i == vscr->workspace.current)
				continue;

			wDockHideIcons(vscr->workspace.array[i]->clip);
		}
	}

	/* Need to rearrange unless moving from dock to dock */
	if (wPreferences.auto_arrange_icons && !(originalDock != NULL && docked))
		wArrangeIcons(vscr, True);
}
Пример #4
0
void removeAppIconFor(WApplication *wapp)
{
	if (!wapp->app_icon)
		return;

	if (wPreferences.highlight_active_app)
		wIconSetHighlited(wapp->app_icon->icon, False);

	if (wapp->app_icon->docked && !wapp->app_icon->attracted) {
		wapp->app_icon->running = 0;
		/* since we keep it, we don't care if it was attracted or not */
		wapp->app_icon->attracted = 0;
		wapp->app_icon->icon->shadowed = 0;
		wapp->app_icon->main_window = None;
		wapp->app_icon->pid = 0;
		wapp->app_icon->icon->owner = NULL;
		wapp->app_icon->icon->icon_win = None;

		/* Set the icon image */
		set_icon_image_from_database(wapp->app_icon->icon, wapp->app_icon->wm_instance,
					     wapp->app_icon->wm_class, wapp->app_icon->command);
		map_icon_image(wapp->app_icon->icon);

		/* Paint it */
		wAppIconPaint(wapp->app_icon);
	} else if (wapp->app_icon->docked) {
		wapp->app_icon->running = 0;
		if (wapp->app_icon->dock->type == WM_DRAWER)
			wDrawerFillTheGap(wapp->app_icon->dock, wapp->app_icon, True);

		wDockDetach(wapp->app_icon->dock, wapp->app_icon);
	} else {
		wAppIconDestroy(wapp->app_icon);
	}

	wapp->app_icon = NULL;

	if (wPreferences.auto_arrange_icons)
		wArrangeIcons(wapp->main_window_desc->vscr, True);
}
Пример #5
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

}
Пример #6
0
void wWorkspaceForceChange(WScreen * scr, int workspace)
{
	WWindow *tmp, *foc = NULL, *foc2 = NULL;
	WWindow **toUnmap;
	int toUnmapSize, toUnmapCount;

	if (workspace >= MAX_WORKSPACES || workspace < 0)
		return;

	SendHelperMessage(scr, 'C', workspace + 1, NULL);

	if (workspace > w_global.workspace.count - 1)
		wWorkspaceMake(scr, workspace - w_global.workspace.count + 1);

	wClipUpdateForWorkspaceChange(scr, workspace);

	w_global.workspace.last_used = w_global.workspace.current;
	w_global.workspace.current = workspace;

	wWorkspaceMenuUpdate(w_global.workspace.menu);

	wWorkspaceMenuUpdate(w_global.clip.ws_menu);

	toUnmapSize = 16;
	toUnmapCount = 0;
	toUnmap = wmalloc(toUnmapSize * sizeof(WWindow *));

	if ((tmp = scr->focused_window) != NULL) {
		if ((IS_OMNIPRESENT(tmp) && (tmp->flags.mapped || tmp->flags.shaded) &&
		     !WFLAGP(tmp, no_focusable)) || tmp->flags.changing_workspace) {
			foc = tmp;
		}

		/* foc2 = tmp; will fix annoyance with gnome panel
		 * but will create annoyance for every other application
		 */
		while (tmp) {
			if (tmp->frame->workspace != workspace && !tmp->flags.selected) {
				/* unmap windows not on this workspace */
				if ((tmp->flags.mapped || tmp->flags.shaded) &&
				    !IS_OMNIPRESENT(tmp) && !tmp->flags.changing_workspace) {
					if (toUnmapCount == toUnmapSize)
					{
						toUnmapSize *= 2;
						toUnmap = wrealloc(toUnmap, toUnmapSize * sizeof(WWindow *));
					}
					toUnmap[toUnmapCount++] = tmp;
				}
				/* also unmap miniwindows not on this workspace */
				if (!wPreferences.sticky_icons && tmp->flags.miniaturized &&
				    tmp->icon && !IS_OMNIPRESENT(tmp)) {
					XUnmapWindow(dpy, tmp->icon->core->window);
					tmp->icon->mapped = 0;
				}
				/* update current workspace of omnipresent windows */
				if (IS_OMNIPRESENT(tmp)) {
					WApplication *wapp = wApplicationOf(tmp->main_window);

					tmp->frame->workspace = workspace;

					if (wapp) {
						wapp->last_workspace = workspace;
					}
					if (!foc2 && (tmp->flags.mapped || tmp->flags.shaded)) {
						foc2 = tmp;
					}
				}
			} else {
				/* change selected windows' workspace */
				if (tmp->flags.selected) {
					wWindowChangeWorkspace(tmp, workspace);
					if (!tmp->flags.miniaturized && !foc) {
						foc = tmp;
					}
				} else {
					if (!tmp->flags.hidden) {
						if (!(tmp->flags.mapped || tmp->flags.miniaturized)) {
							/* remap windows that are on this workspace */
							wWindowMap(tmp);
							if (!foc && !WFLAGP(tmp, no_focusable)) {
								foc = tmp;
							}
						}
						/* Also map miniwindow if not omnipresent */
						if (!wPreferences.sticky_icons &&
						    tmp->flags.miniaturized && !IS_OMNIPRESENT(tmp) && tmp->icon) {
							tmp->icon->mapped = 1;
							XMapWindow(dpy, tmp->icon->core->window);
						}
					}
				}
			}
			tmp = tmp->prev;
		}

		while (toUnmapCount > 0)
		{
			wWindowUnmap(toUnmap[--toUnmapCount]);
		}
		wfree(toUnmap);

		/* Gobble up events unleashed by our mapping & unmapping.
		 * These may trigger various grab-initiated focus &
		 * crossing events. However, we don't care about them,
		 * and ignore their focus implications altogether to avoid
		 * flicker.
		 */
		scr->flags.ignore_focus_events = 1;
		ProcessPendingEvents();
		scr->flags.ignore_focus_events = 0;

		if (!foc)
			foc = foc2;

		if (scr->focused_window->flags.mapped && !foc) {
			foc = scr->focused_window;
		}
		if (wPreferences.focus_mode == WKF_CLICK) {
			wSetFocusTo(scr, foc);
		} else {
			unsigned int mask;
			int foo;
			Window bar, win;
			WWindow *tmp;

			tmp = NULL;
			if (XQueryPointer(dpy, scr->root_win, &bar, &win, &foo, &foo, &foo, &foo, &mask)) {
				tmp = wWindowFor(win);
			}

			/* If there's a window under the pointer, focus it.
			 * (we ate all other focus events above, so it's
			 * certainly not focused). Otherwise focus last
			 * focused, or the root (depending on sloppiness)
			 */
			if (!tmp && wPreferences.focus_mode == WKF_SLOPPY) {
				wSetFocusTo(scr, foc);
			} else {
				wSetFocusTo(scr, tmp);
			}
		}
	}

	/* We need to always arrange icons when changing workspace, even if
	 * no autoarrange icons, because else the icons in different workspaces
	 * can be superposed.
	 * This can be avoided if appicons are also workspace specific.
	 */
	if (!wPreferences.sticky_icons)
		wArrangeIcons(scr, False);

	if (scr->dock)
		wAppIconPaint(scr->dock->icon_array[0]);

	if (!wPreferences.flags.noclip && (w_global.workspace.array[workspace]->clip->auto_collapse ||
					   w_global.workspace.array[workspace]->clip->auto_raise_lower)) {
		/* to handle enter notify. This will also */
		XUnmapWindow(dpy, w_global.clip.icon->icon->core->window);
		XMapWindow(dpy, w_global.clip.icon->icon->core->window);
	}
	else if (w_global.clip.icon != NULL) {
		wClipIconPaint();
	}
	wScreenUpdateUsableArea(scr);
	wNETWMUpdateDesktop(scr);
	showWorkspaceName(scr, workspace);

	WMPostNotificationName(WMNWorkspaceChanged, scr, (void *)(uintptr_t) workspace);

	/*   XSync(dpy, False); */
}