Exemplo n.º 1
0
Client::~Client()
{
    if (mWorkspace)
        mWorkspace->onClientDestroyed(this);
    WindowManager::instance()->js().onClientDestroyed(this);
    assert(mJSValue.isInvalid() || mJSValue.isCustom());
    if (!mJSValue.isInvalid()) {
        JavaScript &engine = WindowManager::instance()->js();
        ScriptEngine::Object::SharedPtr obj = engine.toObject(mJSValue);
        if (obj)
            obj->setExtraData(0);
    }
    unmap();
    delete mGraphics;
    xcb_connection_t* conn = WindowManager::instance()->connection();
    if (mWindow) {
        if (!mOwned) {
            xcb_reparent_window(conn, mWindow, root(), 0, 0);
        } else {
            xcb_destroy_window(conn, mWindow);
        }
        sClients.erase(mWindow);
    }
    xcb_destroy_window(conn, mFrame);
    if (mGroup)
        mGroup->onClientDestroyed(this);
}
Exemplo n.º 2
0
    //_____________________________________________
    void SizeGrip::embed( void )
    {

        #if OXYGEN_HAVE_X11

        if( !QX11Info::isPlatformX11() ) return;
        auto c = m_decoration.data()->client().data();

        xcb_window_t windowId = c->windowId();
        if( windowId )
        {

            /*
            find client's parent
            we want the size grip to be at the same level as the client in the stack
            */
            xcb_window_t current = windowId;
            auto connection = QX11Info::connection();
            xcb_query_tree_cookie_t cookie = xcb_query_tree_unchecked( connection, current );
            ScopedPointer<xcb_query_tree_reply_t> tree(xcb_query_tree_reply( connection, cookie, nullptr ) );
            if( !tree.isNull() && tree->parent ) current = tree->parent;

            // reparent
            xcb_reparent_window( connection, winId(), current, 0, 0 );
            setWindowTitle( "Oxygen::SizeGrip" );

        } else {

            hide();

        }

        #endif
    }
Exemplo n.º 3
0
/** Update the systray
 * \param L The Lua VM state.
 * \return The number of elements pushed on stack.
 * \luastack
 * \lparam The drawin to display the systray in.
 * \lparam x X position for the systray.
 * \lparam y Y position for the systray.
 * \lparam base_size The size (width and height) each systray item gets.
 * \lparam horiz If true, the systray is horizontal, else vertical.
 * \lparam bg Color of the systray background.
 * \lparam revers If true, the systray icon order will be reversed, else default.
 * \lparam spacing The size of the spacing between icons.
 */
int
luaA_systray(lua_State *L)
{
    systray_register();

    if(lua_gettop(L) != 0)
    {
        size_t bg_len;
        drawin_t *w = luaA_checkudata(L, 1, &drawin_class);
        int x = luaL_checkinteger(L, 2);
        int y = luaL_checkinteger(L, 3);
        int base_size = luaL_checkinteger(L, 4);
        bool horiz = lua_toboolean(L, 5);
        const char *bg = luaL_checklstring(L, 6, &bg_len);
        bool revers = lua_toboolean(L, 7);
        int spacing = luaL_checkinteger(L, 8);
        color_t bg_color;

        if(color_init_reply(color_init_unchecked(&bg_color, bg, bg_len)))
        {
            uint32_t config_back[] = { bg_color.pixel };
            xcb_change_window_attributes(globalconf.connection,
                                         globalconf.systray.window,
                                         XCB_CW_BACK_PIXEL, config_back);
        }

        if(globalconf.systray.parent != w)
            xcb_reparent_window(globalconf.connection,
                                globalconf.systray.window,
                                w->window,
                                x, y);
        else
        {
            uint32_t config_vals[2] = { x, y };
            xcb_configure_window(globalconf.connection,
                                 globalconf.systray.window,
                                 XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
                                 config_vals);
        }

        globalconf.systray.parent = w;

        if(globalconf.embedded.len != 0)
        {
            systray_update(base_size, horiz, revers, spacing);
            xcb_map_window(globalconf.connection,
                           globalconf.systray.window);
        }
        else
            xcb_unmap_window(globalconf.connection,
                             globalconf.systray.window);
    }

    lua_pushinteger(L, globalconf.embedded.len);
    luaA_object_push(L, globalconf.systray.parent);
    return 2;
}
Exemplo n.º 4
0
// === EmbedWindow() ===
uint LXCB::EmbedWindow(WId win, WId container){
  if(DEBUG){ qDebug() << "XCB: EmbedWindow()"; }
  //This returns the damage control ID number (or 0 for a failure)
  if(win==0 || container==0){ return 0; }
  //qDebug() << "Embed Window:" << win << container;

  //Initialize any atoms that will be needed
  xcb_intern_atom_cookie_t ecookie = xcb_intern_atom_unchecked(QX11Info::connection(), 0, 7, "_XEMBED");
  
  xcb_intern_atom_reply_t *ereply = xcb_intern_atom_reply(QX11Info::connection(), ecookie, NULL);
  if(ereply==0){ return 0; } //unable to initialize the atom
  xcb_atom_t emb = ereply->atom;
  free(ereply); //done with this structure
  
  //Reparent the window into the container
  xcb_reparent_window(QX11Info::connection(), win, container, 0, 0);
  xcb_map_window(QX11Info::connection(), win);
  
  //Now send the embed event to the app
  //qDebug() << " - send _XEMBED event";
  xcb_client_message_event_t event;
    event.response_type = XCB_CLIENT_MESSAGE;
    event.format = 32;
    event.window = win;
    event.type = emb; //_XEMBED
    event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime; 
    event.data.data32[1] = 0; //XEMBED_EMBEDDED_NOTIFY
    event.data.data32[2] = 0;
    event.data.data32[3] = container; //WID of the container
    event.data.data32[4] = 0;

    xcb_send_event(QX11Info::connection(), 0, win,  XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event);
  
  //Now setup any redirects and return
  //qDebug() << " - select Input";
  //XSelectInput(disp, win, StructureNotifyMask); //Notify of structure changes
  //uint32_t val[] = {XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY};
  //xcb_change_window_attributes(QX11Info::connection(), win, XCB_CW_EVENT_MASK, val);
  this->SelectInput(win);
  //qDebug() << " - Composite Redirect";
  xcb_composite_redirect_window(QX11Info::connection(), win, XCB_COMPOSITE_REDIRECT_MANUAL);

  //Now map the window (will be a transparent child of the container)
  xcb_map_window(QX11Info::connection(), win);
  
  //Now create/register the damage handler
  xcb_damage_damage_t dmgID = xcb_generate_id(QX11Info::connection()); //This is a typedef for a 32-bit unsigned integer
  xcb_damage_create(QX11Info::connection(), dmgID, win, XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES);
  
  //qDebug() << " - Done";
  return ( (uint) dmgID );	
}
Exemplo n.º 5
0
/** Handle a systray request.
 * \param embed_win The window to embed.
 * \param phys_screen The physical monitor to display on.
 * \param info The embedding info
 * \return 0 on no error.
 */
int
systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *info)
{
    xembed_window_t em;
    xcb_get_property_cookie_t em_cookie;
    const uint32_t select_input_val[] =
    {
        XCB_EVENT_MASK_STRUCTURE_NOTIFY
            | XCB_EVENT_MASK_PROPERTY_CHANGE
            | XCB_EVENT_MASK_ENTER_WINDOW
    };

    /* check if not already trayed */
    if(xembed_getbywin(&globalconf.embedded, embed_win))
        return -1;

    p_clear(&em_cookie, 1);

    if(!info)
        em_cookie = xembed_info_get_unchecked(globalconf.connection, embed_win);

    xcb_change_window_attributes(globalconf.connection, embed_win, XCB_CW_EVENT_MASK,
                                 select_input_val);
    window_state_set(embed_win, XCB_ICCCM_WM_STATE_WITHDRAWN);

    /* we grab the window, but also make sure it's automatically reparented back
     * to the root window if we should die.
     */
    xcb_change_save_set(globalconf.connection, XCB_SET_MODE_INSERT, embed_win);
    xcb_reparent_window(globalconf.connection, embed_win,
                        globalconf.screens.tab[phys_screen].systray.window,
                        0, 0);

    em.win = embed_win;
    em.phys_screen = phys_screen;

    if(info)
        em.info = *info;
    else
        xembed_info_get_reply(globalconf.connection, em_cookie, &em.info);

    xembed_embedded_notify(globalconf.connection, em.win,
                           globalconf.screens.tab[phys_screen].systray.window,
                           MIN(XEMBED_VERSION, em.info.version));

    xembed_window_array_append(&globalconf.embedded, em);

    widget_invalidate_bytype(widget_systray);

    return 0;
}
Exemplo n.º 6
0
// === Unembed Window() ===
bool LXCB::UnembedWindow(WId win){
  if(DEBUG){ qDebug() << "XCB: UnembedWindow()"; }
  if(win==0){ return false; }
  //Display *disp = QX11Info::display();
  //Remove redirects
  //XSelectInput(disp, win, NoEventMask);
  uint32_t val[] = {XCB_EVENT_MASK_NO_EVENT};	
  xcb_change_window_attributes(QX11Info::connection(), win, XCB_CW_EVENT_MASK, val);
  //Make sure it is invisible
  xcb_unmap_window(QX11Info::connection(), win);
  //Reparent the window back to the root window
  xcb_reparent_window(QX11Info::connection(), win, QX11Info::appRootWindow(), 0, 0);
  return true;	
}
Exemplo n.º 7
0
/** Handle a systray request.
 * \param embed_win The window to embed.
 */
int
systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *info)
{
    xembed_window_t em;
    xcb_get_property_cookie_t em_cookie;
    int i;
    const uint32_t select_input_val[] =
    {
        XCB_EVENT_MASK_STRUCTURE_NOTIFY
            | XCB_EVENT_MASK_PROPERTY_CHANGE
            | XCB_EVENT_MASK_ENTER_WINDOW
    };

    /* check if not already trayed */
    if(xembed_getbywin(&globalconf.embedded, embed_win))
        return -1;

    p_clear(&em_cookie, 1);

    if(!info)
        em_cookie = xembed_info_get_unchecked(globalconf.connection, embed_win);

    xcb_change_window_attributes(globalconf.connection, embed_win, XCB_CW_EVENT_MASK,
                                 select_input_val);
    window_state_set(embed_win, XCB_WM_STATE_WITHDRAWN);

    xcb_reparent_window(globalconf.connection, embed_win,
                        globalconf.screens[phys_screen].systray.window,
                        0, 0);

    em.win = embed_win;
    em.phys_screen = phys_screen;

    if(info)
        em.info = *info;
    else
        xembed_info_get_reply(globalconf.connection, em_cookie, &em.info);

    xembed_embedded_notify(globalconf.connection, em.win,
                           globalconf.screens[phys_screen].systray.window,
                           MIN(XEMBED_VERSION, em.info.version));

    xembed_window_array_append(&globalconf.embedded, em);

    for(i = 0; i < globalconf.nscreen; i++)
        widget_invalidate_bytype(i, widget_systray);

    return 0;
}
Exemplo n.º 8
0
/** Kick out systray windows.
 */
static void
drawin_systray_kickout(drawin_t *w)
{
    if(globalconf.systray.parent == w)
    {
        /* Who! Check that we're not deleting a drawin with a systray, because it
         * may be its parent. If so, we reparent to root before, otherwise it will
         * hurt very much. */
        systray_cleanup();
        xcb_reparent_window(globalconf.connection,
                            globalconf.systray.window,
                            globalconf.screen->root,
                            -512, -512);

        globalconf.systray.parent = NULL;
    }
}
Exemplo n.º 9
0
/*
 * Restores the geometry of each window by reparenting it to the root window
 * at the position of its frame.
 *
 * This is to be called *only* before exiting/restarting i3 because of evil
 * side-effects which are to be expected when continuing to run i3.
 *
 */
void restore_geometry(void) {
    DLOG("Restoring geometry\n");

    Con *con;
    TAILQ_FOREACH(con, &all_cons, all_cons)
    if (con->window) {
        DLOG("Re-adding X11 border of %d px\n", con->border_width);
        con->window_rect.width += (2 * con->border_width);
        con->window_rect.height += (2 * con->border_width);
        xcb_set_window_rect(conn, con->window->id, con->window_rect);
        DLOG("placing window %08x at %d %d\n", con->window->id, con->rect.x, con->rect.y);
        xcb_reparent_window(conn, con->window->id, root,
                            con->rect.x, con->rect.y);
    }

    /* Strictly speaking, this line doesn’t really belong here, but since we
     * are syncing, let’s un-register as a window manager first */
    xcb_change_window_attributes(conn, root, XCB_CW_EVENT_MASK, (uint32_t[]){XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT});

    /* Make sure our changes reach the X server, we restart/exit now */
    xcb_aux_sync(conn);
}
Exemplo n.º 10
0
static void
_e_alert_display(void)
{
   xcb_char2b_t *str = NULL;
   xcb_query_text_extents_cookie_t cookie;
   xcb_query_text_extents_reply_t *reply;
   int x = 0, w = 0;

   tainted = _e_alert_root_tainted_get();

   str = _e_alert_build_string(title);

   cookie =
     xcb_query_text_extents_unchecked(conn, font, strlen(title), str);
   reply = xcb_query_text_extents_reply(conn, cookie, NULL);
   if (reply)
     {
        fa = reply->font_ascent;
        fh = (fa + reply->font_descent);
        fw = reply->overall_width;
        free(reply);
     }
   free(str);

   /* move buttons */
   x = 20;
   w = (WINDOW_WIDTH / 2) - 40;
   _e_alert_button_move_resize(btn1, x, WINDOW_HEIGHT - 20 - (fh + 20),
                               w, (fh + 20));

   x = ((WINDOW_WIDTH / 2) + 20);
   _e_alert_button_move_resize(btn2, x, WINDOW_HEIGHT - 20 - (fh + 20),
                               w, (fh + 20));

   comp_win = _e_alert_comp_win_get();
   if (comp_win)
     {
        xcb_rectangle_t rect;
        int wx = 0, wy = 0;

        wx = ((sw - WINDOW_WIDTH) / 2);
        wy = ((sh - WINDOW_HEIGHT) / 2);

        rect.x = wx;
        rect.y = wy;
        rect.width = WINDOW_WIDTH;
        rect.height = WINDOW_HEIGHT;

        xcb_shape_rectangles(conn, XCB_SHAPE_SO_SET,
                             XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED,
                             comp_win, 0, 0, 1, &rect);

        xcb_reparent_window(conn, win, comp_win, wx, wy);
     }

   /* map and raise main window */
   xcb_map_window(conn, win);
   _e_alert_window_raise(win);

   /* grab pointer & keyboard */
   xcb_grab_pointer_unchecked(conn, 0, win,
                              (XCB_EVENT_MASK_BUTTON_PRESS |
                               XCB_EVENT_MASK_BUTTON_RELEASE),
                              XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
                              XCB_NONE, XCB_NONE, XCB_CURRENT_TIME);
   xcb_grab_keyboard_unchecked(conn, 0, win, XCB_CURRENT_TIME,
                               XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
   xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT,
                       win, XCB_CURRENT_TIME);

   /* flush screen */
   xcb_flush(conn);

   /* sync */
   _e_alert_sync();
}
Exemplo n.º 11
0
	void
	Window::put_inside(WindowPtr parent, int32_t x, int32_t y)
	{
		xcb_reparent_window(conn->xcb(), window, parent->window, x, y);
	}
Exemplo n.º 12
0
void draw_byxid(xcb_window_t xid)
{
  xcb_connection_t    *c=G.conn;
  xcb_window_t         w=xid;
  xcb_get_geometry_reply_t *geo;
  uint32_t mask;
  uint32_t values[4];

  geo = xcb_get_geometry_reply(G.conn, 
      xcb_get_geometry(G.conn, w), NULL);
  assert(geo != NULL);

  printf("get (%hdx%hd)@(%dx%d)\n",  
      geo->x, geo->y, geo->width, geo->height);
  // try require event handler, and draw something.

  //start create sub window and draw gc in it.
//  getchar();

  /* create sub window */
  xcb_window_t         child;
  child = xcb_generate_id(c);
	mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
	values[0] = G.s->black_pixel;
	values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
  xcb_void_cookie_t cookie;

   // create colormap if needed , window pixfmt is diff from root window.

/*	xcb_map_window(c, w); xcb_flush(c);   */

  //creat a half size window
  geo->width /=2;
  geo->height /=2;

	cookie = xcb_create_window_checked(c, G.s->root_depth, child, w,
      10, 10, geo->width, geo->height,
      1,
			XCB_WINDOW_CLASS_INPUT_OUTPUT, G.s->root_visual,
			mask, values);

  //check cookie error
  if(1){
    xcb_generic_error_t *err;
    err = xcb_request_check (c, cookie);
    if (err){
      int code = err->error_code;
      free (err);
      printf("X11 error %d", code);
      assert (code != 0);
    }
  }
  xcb_map_window(c, child); xcb_flush(c);

  // xcb_reparent_window(c, child,  0,100,100);  
  // root=0 return no affected.
  xcb_reparent_window(c, child,  G.s->root,100,100);
//  xcb_map_window(c, child);xcb_flush(c);

  // ? why make a pixmap as attribute of new sub window
  xcb_pixmap_t      pixmap;
  xcb_create_pixmap (G.conn, geo->depth, pixmap,
      child, geo->width, geo->height);

  values[1] |= XCB_EVENT_MASK_POINTER_MOTION |
     XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE;
  xcb_change_window_attributes_checked(c, child, mask, values); xcb_flush(c);

//  xcb_poly_fill_rectangle(c, child, g,  1, &r);
  // both map and flush need to show window up
  //getchar();
  //unmap is minimum window
//  xcb_unmap_window(c, child);
// xcb_destroy_window(c, child);

  create_dri_drawable();


  int done =0 ;
  xcb_generic_event_t *e;
  printf("wait event\n");
  while (!done ) {
		printf("\re=>(x%x)", e->response_type); fflush(stdout);
    e = xcb_wait_for_event(c);
    if(!e)printf("wait event error\n");
    else{
      switch (e->response_type & ~0x80) {
        case XCB_EXPOSE:    /* draw or redraw the window */
          printf("XCB_EXPOSE\n");
          draw_gc(child);
          break;
        case XCB_KEY_PRESS:  /* exit on key press */
          //gwj done = 1;
          break;
      }
      free(e);
    }
  }
  xcb_unmap_window(c, child);
  xcb_destroy_window(c, child);
}
Exemplo n.º 13
0
SNIProxy::SNIProxy(xcb_window_t wid, QObject* parent):
    QObject(parent),
    //Work round a bug in our SNIWatcher with multiple SNIs per connection.
    //there is an undocumented feature that you can register an SNI by path, however it doesn't detect an object on a service being removed, only the entire service closing
    //instead lets use one DBus connection per SNI
    m_dbus(QDBusConnection::connectToBus(QDBusConnection::SessionBus, QStringLiteral("XembedSniProxy%1").arg(s_serviceCount++))),
    m_windowId(wid)
{
    //create new SNI
    new StatusNotifierItemAdaptor(this);
    m_dbus.registerObject(QStringLiteral("/StatusNotifierItem"), this);

    auto statusNotifierWatcher = new org::kde::StatusNotifierWatcher(QStringLiteral(SNI_WATCHER_SERVICE_NAME), QStringLiteral(SNI_WATCHER_PATH), QDBusConnection::sessionBus(), this);
    auto reply = statusNotifierWatcher->RegisterStatusNotifierItem(m_dbus.baseService());
    reply.waitForFinished();
    if (reply.isError()) {
        qCWarning(SNIPROXY) << "could not register SNI:" << reply.error().message();
    }

    auto c = QX11Info::connection();

    auto cookie = xcb_get_geometry(c, m_windowId);
    QScopedPointer<xcb_get_geometry_reply_t> clientGeom(xcb_get_geometry_reply(c, cookie, Q_NULLPTR));

    //create a container window
    auto screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
    m_containerWid = xcb_generate_id(c);
    uint32_t             values[2];
    auto mask = XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT;
    values[0] = screen->black_pixel; //draw a solid background so the embeded icon doesn't get garbage in it
    values[1] = true; //bypass wM
    xcb_create_window (c,                          /* connection    */
                    XCB_COPY_FROM_PARENT,          /* depth         */
                     m_containerWid,               /* window Id     */
                     screen->root,                 /* parent window */
                     -500, 0,                       /* x, y          */
                     s_embedSize, s_embedSize,     /* width, height */
                     0,                           /* border_width  */
                     XCB_WINDOW_CLASS_INPUT_OUTPUT,/* class         */
                     screen->root_visual,          /* visual        */
                     mask, values);                /* masks         */

    /*
        We need the window to exist and be mapped otherwise the child won't render it's contents

        We also need it to exist in the right place to get the clicks working as GTK will check sendEvent locations to see if our window is in the right place. So even though our contents are drawn via compositing we still put this window in the right place

        We can't composite it away anything parented owned by the root window (apparently)
        Stack Under works in the non composited case, but it doesn't seem to work in kwin's composited case (probably need set relevant NETWM hint)

        As a last resort set opacity to 0 just to make sure this container never appears
    */

#ifndef VISUAL_DEBUG
    const uint32_t stackBelowData[] = {XCB_STACK_MODE_BELOW};
    xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackBelowData);

    NETWinInfo wm(c, m_containerWid, screen->root, 0);
    wm.setOpacity(0);
#endif

    xcb_flush(c);

    xcb_map_window(c, m_containerWid);

    xcb_reparent_window(c, wid,
                        m_containerWid,
                        0, 0);

    /*
     * Render the embedded window offscreen
     */
    xcb_composite_redirect_window(c, wid, XCB_COMPOSITE_REDIRECT_MANUAL);


    /* we grab the window, but also make sure it's automatically reparented back
     * to the root window if we should die.
    */
    xcb_change_save_set(c, XCB_SET_MODE_INSERT, wid);

    //tell client we're embedding it
    xembed_message_send(wid, XEMBED_EMBEDDED_NOTIFY, m_containerWid, 0, 0);

    //move window we're embedding
    const uint32_t windowMoveConfigVals[2] = { 0, 0 };

    xcb_configure_window(c, wid,
                             XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
                             windowMoveConfigVals);


    //if the window is a clearly stupid size resize to be something sensible
    //this is needed as chormium and such when resized just fill the icon with transparent space and only draw in the middle
    //however spotify does need this as by default the window size is 900px wide.
    //use an artbitrary heuristic to make sure icons are always sensible
    if (clientGeom->width < 12 || clientGeom->width > s_embedSize ||
        clientGeom->height < 12 || clientGeom->height > s_embedSize)
    {
        const uint32_t windowMoveConfigVals[2] = { s_embedSize, s_embedSize };
        xcb_configure_window(c, wid,
                                XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
                                windowMoveConfigVals);
    }

    //show the embedded window otherwise nothing happens
    xcb_map_window(c, wid);

    xcb_clear_area(c, 0, wid, 0, 0, qMin(clientGeom->width, s_embedSize), qMin(clientGeom->height, s_embedSize));

    xcb_flush(c);

    //there's no damage event for the first paint, and sometimes it's not drawn immediately
    //not ideal, but it works better than nothing
    //test with xchat before changing
    QTimer::singleShot(500, this, &SNIProxy::update);
}
Exemplo n.º 14
0
void QXcbWindow::setParent(const QPlatformWindow *parent)
{
    QPoint topLeft = geometry().topLeft();
    Q_XCB_CALL(xcb_reparent_window(xcb_connection(), window(), static_cast<const QXcbWindow *>(parent)->window(), topLeft.x(), topLeft.y()));
}
Exemplo n.º 15
0
void Client::complete()
{
    WindowManager *wm = WindowManager::instance();
    xcb_connection_t* conn = wm->connection();
    xcb_ewmh_connection_t* ewmhConn = wm->ewmhConnection();
    if (mEwmhState.contains(ewmhConn->_NET_WM_STATE_STICKY)) {
        // don't put in layout
#warning support strut windows in layouts (reserved space)
#warning support partial struts
        Rect rect = wm->rect(mScreenNumber);
        if (mStrut.left) {
            if (mRect.width != static_cast<int>(mStrut.left))
                mRect.width = mStrut.left;
            mRect.x = rect.x;
            rect.x += mRect.width;
            rect.width -= mRect.width;
        } else if (mStrut.right) {
            if (mRect.width != static_cast<int>(mStrut.right))
                mRect.width = mStrut.right;
            mRect.x = rect.x + rect.width - mStrut.right;
            rect.width -= mStrut.right;
        } else if (mStrut.top) {
            if (mRect.height != static_cast<int>(mStrut.top))
                mRect.height = mStrut.top;
            mRect.y = rect.y;
            rect.y += mRect.height;
            rect.height -= mRect.height;
        } else if (mStrut.bottom) {
            if (mRect.height != static_cast<int>(mStrut.bottom))
                mRect.height = mStrut.bottom;
            mRect.y = rect.y + rect.height - mStrut.bottom;
            rect.height -= mStrut.bottom;
        }
        wm->setRect(rect, mScreenNumber);
        warning() << "fixed at" << mRect;
    } else {
        if (shouldLayout()) {
            wm->js().onLayout(this);
            warning() << "laid out at" << mRect;
        }
    }
#warning do startup-notification stuff here
    if (!mOwned)
        xcb_change_save_set(conn, XCB_SET_MODE_INSERT, mWindow);
    xcb_screen_t* scr = screen();
    mFrame = xcb_generate_id(conn);
    const uint32_t values[] = {
        scr->black_pixel,
        XCB_GRAVITY_NORTH_WEST,
        XCB_GRAVITY_NORTH_WEST,
        1,
        (XCB_EVENT_MASK_STRUCTURE_NOTIFY
         | XCB_EVENT_MASK_ENTER_WINDOW
         | XCB_EVENT_MASK_LEAVE_WINDOW
         | XCB_EVENT_MASK_EXPOSURE
         | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
         | XCB_EVENT_MASK_POINTER_MOTION
         | XCB_EVENT_MASK_BUTTON_PRESS
         | XCB_EVENT_MASK_BUTTON_RELEASE)
    };
    warning() << "creating frame window" << mRect;
    xcb_create_window(conn, XCB_COPY_FROM_PARENT, mFrame, scr->root,
                      mRect.x, mRect.y, mRect.width, mRect.height, 0,
                      XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT,
                      XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | XCB_CW_WIN_GRAVITY
                      | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, values);
    {
        ServerGrabScope grabScope(conn);
        const uint32_t noValue[] = { 0 };
        xcb_change_window_attributes(conn, scr->root, XCB_CW_EVENT_MASK, noValue);
        xcb_reparent_window(conn, mWindow, mFrame, 0, 0);
        const uint32_t rootEvent[] = { Types::RootEventMask };
        xcb_change_window_attributes(conn, scr->root, XCB_CW_EVENT_MASK, rootEvent);
        xcb_grab_button(conn, false, mWindow, XCB_EVENT_MASK_BUTTON_PRESS,
                        XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, scr->root,
                        XCB_NONE, 1, XCB_BUTTON_MASK_ANY);
        const uint32_t windowEvent[] = { Types::ClientInputMask };
        xcb_change_window_attributes(conn, mWindow, XCB_CW_EVENT_MASK, windowEvent);
    }

    {
        uint16_t windowMask = XCB_CONFIG_WINDOW_WIDTH|XCB_CONFIG_WINDOW_HEIGHT|XCB_CONFIG_WINDOW_BORDER_WIDTH;
        uint32_t windowValues[3];
        int i = 0;
        windowValues[i++] = mRect.width;
        windowValues[i++] = mRect.height;
        windowValues[i++] = 0;
        xcb_configure_window(conn, mWindow, windowMask, windowValues);
    }

#warning do xinerama placement
    const uint32_t stateMode[] = { XCB_ICCCM_WM_STATE_NORMAL, XCB_NONE };
    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, mWindow, Atoms::WM_STATE, Atoms::WM_STATE, 32, 2, stateMode);

    map();
    raise();
    warning() << "created and mapped parent client for frame" << mFrame << "with window" << mWindow;
}