/** Update the WM hints of a client.
 * \param c The client.
 * \param reply (Optional) An existing reply.
 */
void
property_update_wm_hints(client_t *c, xcb_get_property_reply_t *reply)
{
    xcb_icccm_wm_hints_t wmh;

    if(reply)
    {
        if(!xcb_icccm_get_wm_hints_from_reply(&wmh, reply))
            return;
    }
    else
    {
        if(!xcb_icccm_get_wm_hints_reply(globalconf.connection,
                                         xcb_icccm_get_wm_hints_unchecked(globalconf.connection, c->window),
                                         &wmh, NULL))
            return;
    }

    luaA_object_push(globalconf.L, c);
    client_set_urgent(globalconf.L, -1, xcb_icccm_wm_hints_get_urgency(&wmh));
    if(wmh.flags & XCB_ICCCM_WM_HINT_STATE &&
       wmh.initial_state == XCB_ICCCM_WM_STATE_WITHDRAWN)
        client_set_border_width(globalconf.L, -1, 0);

    if(wmh.flags & XCB_ICCCM_WM_HINT_INPUT)
        c->nofocus = !wmh.input;

    if(wmh.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP)
        client_set_group_window(globalconf.L, -1, wmh.window_group);

#ifdef LAB126
    /* pop client */
    lua_pop(globalconf.L, 1);
#endif
}
Example #2
0
void client_clear_urgent(Client *c) {
	xcb_icccm_wm_hints_t wmh;
	xcb_get_property_cookie_t wmh_cookie;

	wmh_cookie = xcb_icccm_get_wm_hints_unchecked(conn, c->win);
	c->isurgent = false;
	if(!xcb_icccm_get_wm_hints_reply(conn, wmh_cookie, &wmh, NULL))
		return;
	wmh.flags &= ~XCB_ICCCM_WM_HINT_X_URGENCY;
	xcb_icccm_set_wm_hints(conn, c->win, &wmh);
}
Example #3
0
// === SetAsPanel() ===
void LXCB::SetAsPanel(WId win){
  if(DEBUG){ qDebug() << "XCB: SetAsPanel()"; }
  if(win==0){ return; }
  SetDisableWMActions(win); //also need to disable WM actions for this window
  //Disable Input focus (panel activation ruins task manager window detection routines)
  //  - Disable Input flag in WM_HINTS
  xcb_icccm_wm_hints_t hints;
  //qDebug() << " - Disable WM_HINTS input flag";
  xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints_unchecked(QX11Info::connection(), win);
  //qDebug() << " -- got cookie";
  if(1 == xcb_icccm_get_wm_hints_reply(QX11Info::connection(), cookie, &hints, NULL) ){
    //qDebug() << " -- Set no inputs flag";
     xcb_icccm_wm_hints_set_input(&hints, false); //set no input focus
     xcb_icccm_set_wm_hints(QX11Info::connection(), win, &hints); //save hints back to window
  }
  //  - Remove WM_TAKE_FOCUS from the WM_PROTOCOLS for the window
  //  - - Generate the necessary atoms
  //qDebug() << " - Generate WM_PROTOCOLS and WM_TAKE_FOCUS atoms";
  xcb_atom_t WM_PROTOCOLS, WM_TAKE_FOCUS; //the two atoms needed
  xcb_intern_atom_reply_t *preply = xcb_intern_atom_reply(QX11Info::connection(), \
			xcb_intern_atom(QX11Info::connection(), 0, 12, "WM_PROTOCOLS"), NULL);
  xcb_intern_atom_reply_t *freply = xcb_intern_atom_reply(QX11Info::connection(), \
			xcb_intern_atom(QX11Info::connection(), 0, 13, "WM_TAKE_FOCUS"), NULL); 
  bool gotatoms = false;
  if(preply && freply){
    WM_PROTOCOLS = preply->atom;
    WM_TAKE_FOCUS = freply->atom;
    free(preply);
    free(freply);
    gotatoms = true;
    //qDebug() << " -- success";
  }
  //  - - Now update the protocols for the window
  if(gotatoms){ //requires the atoms
    //qDebug() << " - Get WM_PROTOCOLS";
    xcb_icccm_get_wm_protocols_reply_t proto;
    if( 1 == xcb_icccm_get_wm_protocols_reply(QX11Info::connection(), \
			xcb_icccm_get_wm_protocols_unchecked(QX11Info::connection(), win, WM_PROTOCOLS), \
			&proto, NULL) ){
	
      //Found the current protocols, see if it has the focus atom set
			//remove the take focus atom and re-save them
      bool needremove = false;
      //Note: This first loop is required so that we can initialize the modified list with a valid size
      //qDebug() << " -- Check current protocols";
      for(unsigned int i=0; i<proto.atoms_len; i++){
        if(proto.atoms[i] == WM_TAKE_FOCUS){ needremove = true; break;}
      }
      if(needremove){
	//qDebug() << " -- Remove WM_TAKE_FOCUS protocol";
	xcb_atom_t *protolist = new xcb_atom_t[proto.atoms_len-1];
	int num = 0;
	for(unsigned int i=0; i<proto.atoms_len; i++){
	  if(proto.atoms[i] != WM_TAKE_FOCUS){
	    protolist[num] = proto.atoms[i];
	    num++;
	  }
	}
	//qDebug() << " -- Re-save modified protocols";
	xcb_icccm_set_wm_protocols(QX11Info::connection(), win, WM_PROTOCOLS, num, protolist);
      }
      //qDebug() << " -- Clear protocols reply";
      xcb_icccm_get_wm_protocols_reply_wipe(&proto);
    }//end of get protocols check
  } //end of gotatoms check
  //Make sure it has the "dock" window type
  //  - get the current window types (Not necessary, only 1 type of window needed)
  
  //  - set the adjusted window type(s)
  //qDebug() << " - Adjust window type";
  xcb_atom_t list[1]; 
    list[0] = EWMH._NET_WM_WINDOW_TYPE_DOCK;
  xcb_ewmh_set_wm_window_type(&EWMH, win, 1, list);
  
  //Make sure it is on all workspaces
  //qDebug() << " - Set window as sticky";
  SetAsSticky(win);
	
}
Example #4
0
xcb_get_property_cookie_t
property_get_wm_hints(client_t *c)
{
    return xcb_icccm_get_wm_hints_unchecked(globalconf.connection, c->window);
}
Example #5
0
static int
widget_update (struct widget *widget, xcb_ewmh_connection_t *ewmh, int screen_nbr) {
	unsigned short i;
	uint32_t desktop_curr, desktop_len, client_desktop;
	char desktop_name[COPY_PROP_BUFSIZ];
	xcb_ewmh_get_utf8_strings_reply_t desktop_names;
	xcb_ewmh_get_windows_reply_t clients;
	xcb_icccm_wm_hints_t window_hints;
	struct desktop *desktops;

	/* get current desktop */
	int desktop_curr_success = xcb_ewmh_get_current_desktop_reply(ewmh, xcb_ewmh_get_current_desktop_unchecked(ewmh, screen_nbr), &desktop_curr, NULL);
	if (!desktop_curr_success) {
		LOG_DEBUG("ewmh: could not get current desktop");

		return 1;
	}

	/* get desktop count */
	int desktop_len_success = xcb_ewmh_get_number_of_desktops_reply(ewmh, xcb_ewmh_get_number_of_desktops_unchecked(ewmh, screen_nbr), &desktop_len, NULL);
	if (!desktop_len_success) {
		LOG_DEBUG("ewmh: could not get desktop count");

		return 2;
	}

	desktops = calloc(desktop_len, sizeof(struct desktop));

	int desktop_names_success = xcb_ewmh_get_desktop_names_reply(ewmh, xcb_ewmh_get_desktop_names_unchecked(ewmh, screen_nbr), &desktop_names, NULL);
	if (!desktop_names_success) {
		LOG_DEBUG("ewmh: could not get desktop names");
	}

	for (i = 0; i < desktop_len; i++) {
		desktops[i].is_selected = i == desktop_curr;
		desktops[i].is_urgent = false;
		desktops[i].clients_len = 0;

		if (desktop_names_success && desktop_names.strings) {
			copy_prop(desktop_name, desktop_names.strings, desktop_names.strings_len, i, desktop_len);
		}
		else {
			snprintf(desktop_name, COPY_PROP_BUFSIZ - 1, "%i", i + 1);
		}
		desktops[i].name = strndup(desktop_name, strlen(desktop_name));
	}

	/* get clients */
	int clients_success = xcb_ewmh_get_client_list_reply(ewmh, xcb_ewmh_get_client_list_unchecked(ewmh, screen_nbr), &clients, NULL);
	if (!clients_success) {
		LOG_DEBUG("ewmh: could not get client list");
	}
	else {
		for (i = 0; i < clients.windows_len; i++) {
			if (!xcb_ewmh_get_wm_desktop_reply(ewmh, xcb_ewmh_get_wm_desktop_unchecked(ewmh, clients.windows[i]), &client_desktop, NULL)) {
				/* window isn't associated with a desktop */
				continue;
			}
			desktops[client_desktop].clients_len++;

			/* check icccm urgency hint on client */
			if (!xcb_icccm_get_wm_hints_reply(ewmh->connection, xcb_icccm_get_wm_hints_unchecked(ewmh->connection, clients.windows[i]), &window_hints, NULL)) {
				LOG_DEBUG("icccm: could not get window hints");
			}
			if (window_hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY) {
				desktops[client_desktop].is_urgent = true;
			}
		}
	}

	json_t *json_data_object = json_object();
	json_t *json_desktops_array = json_array();
	json_object_set_new(json_data_object, "desktops", json_desktops_array);

	for (i = 0; i < desktop_len; i++) {
		json_t *json_desktop = json_object();
		json_object_set_new(json_desktop, "name", json_string(desktops[i].name));
		json_object_set_new(json_desktop, "clients_len", json_integer(desktops[i].clients_len));
		json_object_set_new(json_desktop, "is_urgent", json_boolean(desktops[i].is_urgent));
		json_array_append_new(json_desktops_array, json_desktop);

		if (desktops[i].is_selected) {
			json_object_set_new(json_data_object, "current_desktop", json_integer(i));
		}
	}

	char *json_str = strdup(json_dumps(json_data_object, 0));
	widget_data_callback(widget, widget_data_arg_string(json_str));

	json_decref(json_data_object);
	free(json_str);

	/* cleanup */
	if (desktop_names_success) {
		xcb_ewmh_get_utf8_strings_reply_wipe(&desktop_names);
	}
	if (clients_success) {
		xcb_ewmh_get_windows_reply_wipe(&clients);
	}
	for (i = 0; i < desktop_len; i++) {
		free(desktops[i].name);
	}
	free(desktops);

	return 0;
}