/**
 * Removes a child from the given client.
 */
void ClientModel::remove_child(Window child, bool focus_parent)
{
    if (!is_child(child))
        return;

    Window parent = m_parents[child];
    m_children[parent]->erase(child);
    m_parents.erase(child);

    if (m_focused == child)
    {
        if (focus_parent)
            focus(parent);
        else
            unfocus();
    }

    Desktop *desktop = find_desktop(parent);
    if (desktop->is_user_desktop())
    {
        UserDesktop *user_desktop = dynamic_cast<UserDesktop*>(desktop);
        user_desktop->focus_cycle.remove(child, false);
    }
    else if (desktop->is_all_desktop())
        dynamic_cast<AllDesktops*>(ALL_DESKTOPS)->focus_cycle.remove(child, false);

    m_changes.push(new ChildRemoveChange(parent, child));
}
/**
 * Removes a client.
 *
 * Note that this method will put out a ChangeFocus event, but that event will
 * have a nonexistent 'prev_focus' field (pointing to the client that is
 * destroyed). Other than that event, however, no other notification will be
 * delivered that this window was removed.
 */
void ClientModel::remove_client(Window client)
{
    if (!is_client(client))
        return;

    // Unregister the client from any categories it may be a member of, but
    // keep a copy of each of the categories so we can pass it on to notify
    // that the window was destroyed (don't copy the size/location though,
    // since they will most likely be invalid, and of no use anyway)
    Desktop *desktop = find_desktop(client);
    Layer layer = find_layer(client);

    if (desktop->is_user_desktop())
    {
        UserDesktop *user_desktop = dynamic_cast<UserDesktop*>(desktop);
        user_desktop->focus_cycle.remove(client, true);
        sync_focus_to_cycle();
    }
    else if (desktop->is_all_desktop())
    {
        dynamic_cast<AllDesktops*>(ALL_DESKTOPS)->focus_cycle.remove(client, true);
        sync_focus_to_cycle();
    }

    // Make sure to remove the child before removing any other parent state - the
    // child removal procedure depends upon knowing the parent's desktop
    std::set<Window> children(*m_children[client]);
    for (std::set<Window>::iterator child = children.begin();
         child != children.end();
         child++)
    {
        remove_child(*child, false);
    }

    m_desktops.remove_member(client);
    m_layers.remove_member(client);
    m_location.erase(client);
    m_size.erase(client);
    m_cps_mode.erase(client);
    m_screen.erase(client);
    m_autofocus.erase(client);
    m_pack_corners.erase(client);
    m_pack_priority.erase(client);

    delete m_children[client];
    m_children.erase(client);

    m_changes.push(new DestroyChange(client, desktop, layer));
}
Exemple #3
0
void
add_task (Window win, int focus)
{
	task *tk, *list;

	if (win == tb.win)
		return;

	/* is this window on a different desktop? */
	if (tb.my_desktop != find_desktop (win) || is_hidden (win))
		return;

	tk = calloc (1, sizeof (task));
	tk->win = win;
	tk->focused = focus;
	tk->name = get_prop_data (win, XA_WM_NAME, XA_STRING, 0);
	tk->iconified = is_iconified (win);

	get_task_kdeicon (tk);
	if (tk->icon == None)
		get_task_hinticon (tk);

	XSelectInput (dd, win, PropertyChangeMask | FocusChangeMask |
					  StructureNotifyMask);

	/* now append it to our linked list */
	tb.num_tasks++;

	list = tb.task_list;
	if (!list)
	{
		tb.task_list = tk;
		return;
	}
	while (1)
	{
		if (!list->next)
		{
			list->next = tk;
			return;
		}
		list = list->next;
	}
}
/**
 * Handles an existing client that was unmapped, and is now being re-mapped.
 */
void ClientModel::remap_client(Window client)
{
    if (!is_client(client))
        return;

    std::vector<Window> children;
    get_children_of(client, children);

    Desktop *desktop = find_desktop(client);
    if (desktop->is_user_desktop())
    {
        UserDesktop *user_desktop = dynamic_cast<UserDesktop*>(desktop);
        user_desktop->focus_cycle.add(client);
        for (std::vector<Window>::iterator child = children.begin();
             child != children.end();
             child++)
        {
            user_desktop->focus_cycle.add(*child);
        }

        focus(client);
    }
    else if (desktop->is_all_desktop())
    {
        AllDesktops *all_desktop = dynamic_cast<AllDesktops*>(ALL_DESKTOPS);
        all_desktop->focus_cycle.add(client);
        for (std::vector<Window>::iterator child = children.begin();
             child != children.end();
             child++)
        {
            all_desktop->focus_cycle.add(*child);
        }

        focus(client);
    }

    // The event processor also needs to know that it should update the current 
    // layering, since the window could have been raised since it was remapped
    Layer current_layer = m_layers.get_category_of(client);
    m_changes.push(new ChangeLayer(client, current_layer));
}
/**
 * This is just a way of directly sending an event to the ClientModel - we
 * don't do anything with it.
 */
void ClientModel::unmap_client(Window client)
{
    if (!is_client(client))
        return;

    std::vector<Window> children;
    get_children_of(client, children);

    Desktop *desktop = find_desktop(client);
    if (desktop->is_user_desktop())
    {
        UserDesktop *user_desktop = dynamic_cast<UserDesktop*>(desktop);
        for (std::vector<Window>::iterator child = children.begin();
             child != children.end();
             child++)
        {
            user_desktop->focus_cycle.remove(*child, false);
        }

        user_desktop->focus_cycle.remove(client, false);
        sync_focus_to_cycle();
    }
    else if (desktop->is_all_desktop())
    {
        AllDesktops *all_desktop = dynamic_cast<AllDesktops*>(ALL_DESKTOPS);
        for (std::vector<Window>::iterator child = children.begin();
             child != children.end();
             child++)
        {
            all_desktop->focus_cycle.remove(*child, false);
        }

        all_desktop->focus_cycle.remove(client, false);
        sync_focus_to_cycle();
    }

    m_changes.push(new UnmapChange(client));
}