| 1324 | } |
| 1325 | |
| 1326 | func (wm *WindowManager) declareSupportedAtoms() { |
| 1327 | // List the names of EWMH atoms your WM supports |
| 1328 | atomNames := []string{ |
| 1329 | "_NET_SUPPORTED", |
| 1330 | "_NET_WM_STATE", |
| 1331 | "_NET_WM_NAME", |
| 1332 | "_WM_NAME", |
| 1333 | "_NET_WM_STATE_FULLSCREEN", |
| 1334 | "_NET_CURRENT_DESKTOP", |
| 1335 | "_NET_NUMBER_OF_DESKTOPS", |
| 1336 | "_NET_ACTIVE_WINDOW", |
| 1337 | "_NET_WM_DESKTOP", |
| 1338 | "_NET_CLIENT_LIST", |
| 1339 | "_NET_CLOSE_WINDOW", |
| 1340 | "_NET_WM_MOVERESIZE", |
| 1341 | "_NET_WM_STATE_MAXIMIZED_HORZ", |
| 1342 | "_NET_WM_STATE_MAXIMIZED_VERT", |
| 1343 | } |
| 1344 | |
| 1345 | var atoms []xproto.Atom |
| 1346 | for _, name := range atomNames { |
| 1347 | atom, err := xproto.InternAtom(wm.conn, false, uint16(len(name)), name).Reply() |
| 1348 | if err != nil { |
| 1349 | slog.Error("intern atom", "name", name, "err", err) |
| 1350 | continue |
| 1351 | } |
| 1352 | wm.atoms[name] = atom.Atom |
| 1353 | atoms = append(atoms, atom.Atom) |
| 1354 | } |
| 1355 | |
| 1356 | // Build the property data |
| 1357 | data := make([]byte, 4*len(atoms)) |
| 1358 | for i, atom := range atoms { |
| 1359 | binary.LittleEndian.PutUint32(data[i*4:], uint32(atom)) |
| 1360 | } |
| 1361 | |
| 1362 | // Set the _NET_SUPPORTED property |
| 1363 | err := xproto.ChangePropertyChecked( |
| 1364 | wm.conn, |
| 1365 | xproto.PropModeReplace, |
| 1366 | wm.root, |
| 1367 | wm.atoms["_NET_SUPPORTED"], |
| 1368 | xproto.AtomAtom, |
| 1369 | 32, |
| 1370 | uint32(len(atoms)), |
| 1371 | data, |
| 1372 | ).Check() |
| 1373 | if err != nil { |
| 1374 | slog.Error("could not set _NET_SUPPORTED", "err", err) |
| 1375 | } |
| 1376 | } |
| 1377 | func focusWindow(conn *xgb.Conn, win xproto.Window) { |
| 1378 | err := xproto.SetInputFocusChecked( |
| 1379 | conn, |