예제 #1
0
void RunSocketMonitor() {
    boost::asio::io_service ios;
    boost::asio::io_service ios_m;

    using socket_ptr = std::unique_ptr<azmq::socket>;
    socket_ptr client(new azmq::socket(ios, ZMQ_DEALER));
    socket_ptr server(new azmq::socket(ios, ZMQ_DEALER));

    monitor_handler client_monitor(ios_m, *client, "client");
    monitor_handler server_monitor(ios_m, *server, "server");

    client_monitor.start();
    server_monitor.start();

    std::thread t([&] {
        ios_m.run();
    });

    server->bind("tcp://127.0.0.1:9998");
    client->connect("tcp://127.0.0.1:9998");

    bounce(*client, *server);

    // On Windows monitored sockets must be closed before their monitors,
    // otherwise ZMQ crashes or deadlocks during the context termination.
    // ZMQ's bug?
    client.reset();
    server.reset();

    std::this_thread::sleep_for(std::chrono::seconds(1));

    ios_m.stop();
    t.join();

//    BOOST_REQUIRE(client_monitor.events_.size() == 3);
//    CHECK(client_monitor.events_[0].e == ZMQ_EVENT_CONNECT_DELAYED);
//    CHECK(client_monitor.events_[1].e == ZMQ_EVENT_CONNECTED);
//    CHECK(client_monitor.events_[2].e == ZMQ_EVENT_MONITOR_STOPPED);
//
//    REQUIRE(server_monitor.events_.size() == 4);
//    CHECK(server_monitor.events_[0].e == ZMQ_EVENT_LISTENING);
//    CHECK(server_monitor.events_[1].e == ZMQ_EVENT_ACCEPTED);
//    CHECK(server_monitor.events_[2].e == ZMQ_EVENT_CLOSED);
//    CHECK(server_monitor.events_[3].e == ZMQ_EVENT_MONITOR_STOPPED);
}
예제 #2
0
/*! Pick a monitor to place a window on. */
static Rect* choose_monitor(ObClient *c, gboolean client_to_be_foregrounded,
                            ObAppSettings *settings)
{
    Rect *area;
    ObPlaceHead *choice;
    guint i;
    ObClient *p;
    GSList *it;

    choice = g_new(ObPlaceHead, screen_num_monitors);
    for (i = 0; i < screen_num_monitors; ++i) {
        choice[i].monitor = i;
        choice[i].flags = 0;
    }

    /* find monitors with group members */
    if (c->group) {
        for (it = c->group->members; it; it = g_slist_next(it)) {
            ObClient *itc = it->data;
            if (itc != c) {
                guint m = client_monitor(itc);

                if (m < screen_num_monitors) {
                    if (screen_compare_desktops(itc->desktop, c->desktop))
                        choice[m].flags |= HEAD_GROUP_DESK;
                    else
                        choice[m].flags |= HEAD_GROUP;
                }
            }
        }
    }

    i = screen_monitor_primary(FALSE);
    if (i < screen_num_monitors) {
        choice[i].flags |= HEAD_PRIMARY;
        if (config_place_monitor == OB_PLACE_MONITOR_PRIMARY)
            choice[i].flags |= HEAD_PLACED;
        if (settings &&
            settings->monitor_type == OB_PLACE_MONITOR_PRIMARY)
            choice[i].flags |= HEAD_PERAPP;
    }

    i = screen_monitor_active();
    if (i < screen_num_monitors) {
        if (config_place_monitor == OB_PLACE_MONITOR_ACTIVE)
            choice[i].flags |= HEAD_PLACED;
        if (settings &&
            settings->monitor_type == OB_PLACE_MONITOR_ACTIVE)
            choice[i].flags |= HEAD_PERAPP;
    }

    i = screen_monitor_pointer();
    if (i < screen_num_monitors) {
        if (config_place_monitor == OB_PLACE_MONITOR_MOUSE)
            choice[i].flags |= HEAD_PLACED;
        if (settings &&
            settings->monitor_type == OB_PLACE_MONITOR_MOUSE)
            choice[i].flags |= HEAD_PERAPP;
    }

    if (settings) {
        i = settings->monitor - 1;
        if (i < screen_num_monitors)
            choice[i].flags |= HEAD_PERAPP;
    }

    /* direct parent takes highest precedence */
    if ((p = client_direct_parent(c))) {
        i = client_monitor(p);
        if (i < screen_num_monitors)
            choice[i].flags |= HEAD_PARENT;
    }

    qsort(choice, screen_num_monitors, sizeof(ObPlaceHead),
          client_to_be_foregrounded ? cmp_foreground : cmp_background);

    /* save the areas of the monitors in order of their being chosen */
    for (i = 0; i < screen_num_monitors; ++i)
    {
        ob_debug("placement choice %d is monitor %d", i, choice[i].monitor);
        if (choice[i].flags & HEAD_PARENT)
            ob_debug("  - parent on monitor");
        if (choice[i].flags & HEAD_PLACED)
            ob_debug("  - placement choice");
        if (choice[i].flags & HEAD_PRIMARY)
            ob_debug("  - primary monitor");
        if (choice[i].flags & HEAD_GROUP_DESK)
            ob_debug("  - group on same desktop");
        if (choice[i].flags & HEAD_GROUP)
            ob_debug("  - group on other desktop");
    }

    area = screen_area(c->desktop, choice[0].monitor, NULL);

    g_free(choice);

    /* return the area for the chosen monitor */
    return area;
}
예제 #3
0
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
    Options *o = options;

    if (data->client) {
        Rect *area, *carea;
        ObClient *c;
        guint mon, cmon;
        gint x, y, lw, lh, w, h;

        c = data->client;
        mon = o->monitor;
        cmon = client_monitor(c);
        switch (mon) {
        case CURRENT_MONITOR:
            mon = cmon; break;
        case ALL_MONITORS:
            mon = SCREEN_AREA_ALL_MONITORS; break;
        case NEXT_MONITOR:
            mon = (cmon + 1 > screen_num_monitors - 1) ? 0 : (cmon + 1); break;
        case PREV_MONITOR:
            mon = (cmon == 0) ? (screen_num_monitors - 1) : (cmon - 1); break;
        default:
            g_assert_not_reached();
        }

        area = screen_area(c->desktop, mon, NULL);
        carea = screen_area(c->desktop, cmon, NULL);

        w = o->w;
        if (w == G_MININT) w = c->area.width;
        else if (o->w_denom) w = (w * area->width) / o->w_denom;

        h = o->h;
        if (h == G_MININT) h = c->area.height;
        else if (o->h_denom) h = (h * area->height) / o->h_denom;

        /* it might not be able to resize how they requested, so find out what
           it will actually be resized to */
        x = c->area.x;
        y = c->area.y;
        client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE);

        /* get the frame's size */
        w += c->frame->size.left + c->frame->size.right;
        h += c->frame->size.top + c->frame->size.bottom;

        x = o->x.pos;
        if (o->x.denom)
            x = (x * area->width) / o->x.denom;
        if (o->x.center) x = (area->width - w) / 2;
        else if (x == G_MININT) x = c->frame->area.x - carea->x;
        else if (o->x.opposite) x = area->width - w - x;
        x += area->x;

        y = o->y.pos;
        if (o->y.denom)
            y = (y * area->height) / o->y.denom;
        if (o->y.center) y = (area->height - h) / 2;
        else if (y == G_MININT) y = c->frame->area.y - carea->y;
        else if (o->y.opposite) y = area->height - h - y;
        y += area->y;

        /* get the client's size back */
        w -= c->frame->size.left + c->frame->size.right;
        h -= c->frame->size.top + c->frame->size.bottom;

        frame_frame_gravity(c->frame, &x, &y); /* get the client coords */
        client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE);
        /* force it on screen if its moving to another monitor */
        client_find_onscreen(c, &x, &y, w, h, mon != cmon);

        actions_client_move(data, TRUE);
        client_configure(c, x, y, w, h, TRUE, TRUE, FALSE);
        actions_client_move(data, FALSE);

        g_slice_free(Rect, area);
        g_slice_free(Rect, carea);
    }

    return FALSE;
}
예제 #4
0
void popup_delay_show(ObPopup *self, gulong msec, gchar *text)
{
    gint l, t, r, b;
    gint x, y, w, h;
    guint m;
    gint emptyx, emptyy; /* empty space between elements */
    gint textx, texty, textw, texth;
    gint iconx, icony, iconw, iconh;
    const Rect *area;
    Rect mon;
    gboolean hasicon = self->hasicon;

    /* when there is no icon and the text is not parent relative, then
       fill the whole dialog with the text appearance, don't use the bg at all
    */
    if (hasicon || self->a_text->surface.grad == RR_SURFACE_PARENTREL)
        RrMargins(self->a_bg, &l, &t, &r, &b);
    else
        l = t = r = b = 0;

    /* set up the textures */
    self->a_text->texture[0].data.text.string = text;

    /* measure the text out */
    if (text[0] != '\0') {
        RrMinSize(self->a_text, &textw, &texth);
    } else {
        textw = 0;
        texth = RrMinHeight(self->a_text);
    }

    /* get the height, which is also used for the icon width */
    emptyy = t + b + ob_rr_theme->paddingy * 2;
    if (self->h)
        texth = self->h - emptyy;
    h = texth * self->iconhm + emptyy;

    if (self->textw)
        textw = self->textw;

    iconx = textx = l + ob_rr_theme->paddingx;

    emptyx = l + r + ob_rr_theme->paddingx * 2;
    if (hasicon) {
        iconw = texth * self->iconwm;
        iconh = texth * self->iconhm;
        textx += iconw + ob_rr_theme->paddingx;
        if (textw)
            emptyx += ob_rr_theme->paddingx; /* between the icon and text */
        icony = (h - iconh - emptyy) / 2 + t + ob_rr_theme->paddingy;
    } else
        iconw = 0;

    texty = (h - texth - emptyy) / 2 + t + ob_rr_theme->paddingy;

    /* when there is no icon, then fill the whole dialog with the text
       appearance
    */
    if (!hasicon)
    {
        textx = texty = 0;
        texth += emptyy;
        textw += emptyx;
        emptyx = emptyy = 0;
    }

    w = textw + emptyx + iconw;
    /* cap it at maxw/minw */
    if (self->maxw) w = MIN(w, self->maxw);
    if (self->minw) w = MAX(w, self->minw);
    textw = w - emptyx - iconw;

    /* sanity checks to avoid crashes! */
    if (w < 1) w = 1;
    if (h < 1) h = 1;
    if (texth < 1) texth = 1;

    /* set up the x coord */
    x = self->x;
    switch (self->gravity) {
    case NorthGravity: case CenterGravity: case SouthGravity:
        x -= w / 2;
        break;
    case NorthEastGravity: case EastGravity: case SouthEastGravity:
        x -= w;
        break;
    }

    /* set up the y coord */
    y = self->y;
    switch (self->gravity) {
    case WestGravity: case CenterGravity: case EastGravity:
        y -= h / 2;
        break;
    case SouthWestGravity: case SouthGravity: case SouthEastGravity:
        y -= h;
        break;
    }

    /* If the popup belongs to a client (eg, the moveresize popup), get
     * the monitor for that client, otherwise do other stuff */
    if (self->client) {
        m = client_monitor(self->client);
    } else {
        /* Find the monitor which contains the biggest part of the popup.
         * If the popup is completely off screen, limit it to the intersection
         * of all monitors and then try again. If it's still off screen, put it
         * on monitor 0. */
        RECT_SET(mon, x, y, w, h);
        m = screen_find_monitor(&mon);
    }
    area = screen_physical_area_monitor(m);

    x = MAX(MIN(x, area->x+area->width-w), area->x);
    y = MAX(MIN(y, area->y+area->height-h), area->y);

    if (m == screen_num_monitors) {
        RECT_SET(mon, x, y, w, h);
        m = screen_find_monitor(&mon);
        if (m == screen_num_monitors)
            m = 0;
        area = screen_physical_area_monitor(m);

        x = MAX(MIN(x, area->x+area->width-w), area->x);
        y = MAX(MIN(y, area->y+area->height-h), area->y);
    }

    /* set the windows/appearances up */
    XMoveResizeWindow(obt_display, self->bg, x, y, w, h);
    /* when there is no icon and the text is not parent relative, then
       fill the whole dialog with the text appearance, don't use the bg at all
    */
    if (hasicon || self->a_text->surface.grad == RR_SURFACE_PARENTREL)
        RrPaint(self->a_bg, self->bg, w, h);

    if (textw) {
        self->a_text->surface.parent = self->a_bg;
        self->a_text->surface.parentx = textx;
        self->a_text->surface.parenty = texty;
        XMoveResizeWindow(obt_display, self->text, textx, texty, textw, texth);
        RrPaint(self->a_text, self->text, textw, texth);
    }

    if (hasicon)
        self->draw_icon(iconx, icony, iconw, iconh, self->draw_icon_data);

    /* do the actual showing */
    if (!self->mapped) {
        if (msec) {
            /* don't kill previous show timers */
            if (!self->delay_mapped) {
                self->delay_timer =
                    g_timeout_add(msec, popup_show_timeout, self);
                self->delay_mapped = TRUE;
            }
        } else {
            popup_show_timeout(self);
        }
    }
}