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); }
/*! 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; }
/* 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; }
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); } } }