{"id":29628088,"url":"https://github.com/mrvladus/swcl","last_synced_at":"2025-07-21T08:35:02.381Z","repository":{"id":303114244,"uuid":"830640745","full_name":"mrvladus/swcl","owner":"mrvladus","description":"Simple Wayland Client Library","archived":false,"fork":false,"pushed_at":"2025-07-05T18:57:57.000Z","size":335,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-05T19:59:36.823Z","etag":null,"topics":["header-only","header-only-library","library","linux","wayland","wayland-client"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrvladus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-07-18T17:06:19.000Z","updated_at":"2025-07-05T19:02:13.000Z","dependencies_parsed_at":"2025-07-05T19:59:43.245Z","dependency_job_id":"ad2e2080-93e6-47af-8e31-ff40c1715dc9","html_url":"https://github.com/mrvladus/swcl","commit_stats":null,"previous_names":["mrvladus/swcl"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mrvladus/swcl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrvladus%2Fswcl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrvladus%2Fswcl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrvladus%2Fswcl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrvladus%2Fswcl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrvladus","download_url":"https://codeload.github.com/mrvladus/swcl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrvladus%2Fswcl/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266267525,"owners_count":23902388,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["header-only","header-only-library","library","linux","wayland","wayland-client"],"created_at":"2025-07-21T08:35:01.888Z","updated_at":"2025-07-21T08:35:02.370Z","avatar_url":"https://github.com/mrvladus.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ![SWCL logo](logo.svg) SWCL - Simple Wayland Client Library\n\nCreate Wayland clients easily.\n\nThis stb-style header-only library simplifies creating native Wayland window, receiving mouse or keyboard events, natively drag and resize the window.\n\nIn a few lines of code you will have a window with OpenGL context inside of it that you can use to create whatever you want:\n\n- Applications\n- GUI toolkits\n- Game engines\n\nYou can also port your existing applications to support Wayland with this library.\n\n**SWCL** is written in **C** and it's just one stb-style header file `swcl.h`. You can put it directly in your project.\n\n## Tutorial\n\n### Setup\n\nInstall Wayland development dependencies:\n\nFor Fedora/RHEL based distros:\n\n```sh\nsudo dnf install wayland-devel mesa-libGL-devel\n```\n\nFor Debian/Ubuntu based distros:\n\n```sh\nsudo apt install libwayland-dev mesa-common-dev\n```\n\n### Creating your project\n\nCopy `swcl.h` to your project. Then create `main.c` so your project directory looks like this:\n\n```\nmyproject\n│── swcl.h\n└── main.c\n```\n\nInside of the `main.c` file write this:\n\n```c\n// Include implementation in ONE source file.\n// In other file just include swcl.h\n#define SWCL_IMPLEMENTATION\n#include \"swcl.h\"\n\n// ---------- EVENT CALLBACKS ---------- //\n\n// This function is triggered when pointer enters the window.\nvoid pointer_enter_cb(SWCLWindow *win, size_t x, size_t y) {\n  // We need to set cursor when pointer enters window, otherwise it won't be changed.\n  swcl_application_set_cursor(win-\u003eapp, \"left_ptr\", 16);\n  printf(\"Pointer entered at x=%zu, y=%zu\\n\", x, y);\n}\n\n// In this function we can track pointer position over window.\nvoid pointer_motion_cb(SWCLWindow *win, size_t x, size_t y) { printf(\"Pointer motion at x=%zu, y=%zu\\n\", x, y); }\n\n// This function is triggered when pointer leaves the window.\nvoid pointer_leave_cb(SWCLWindow *win) { printf(\"Pointer leave\\n\"); }\n\n// Mouse button events inside the window callback\nvoid mouse_button_cb(SWCLWindow *win, SWCLMouseButton btn, SWCLButtonState state) {\n  printf(\"Mouse button %d %s\\n\", btn, state == SWCL_BUTTON_PRESSED ? \"pressed\" : \"released\");\n\n  // Get mouse position\n  size_t x = win-\u003eapp-\u003ecursor_pos_x;\n  size_t y = win-\u003eapp-\u003ecursor_pos_y;\n\n  // Drag window if left mouse button is clicked and mouse Y position is less than 30px from the top of the window.\n  if (btn == SWCL_MOUSE_1 \u0026\u0026 state == SWCL_BUTTON_PRESSED \u0026\u0026 y \u003c 30) swcl_window_drag(win);\n\n  // Resize window if clicked on the window edges\n  size_t border = 10; // Edge click area size\n  if (x \u003c border \u0026\u0026 y \u003c border) swcl_window_resize(win, SWCL_WINDOW_EDGE_TOP_LEFT);\n  else if (x \u003e win-\u003ewidth - border \u0026\u0026 y \u003c border) swcl_window_resize(win, SWCL_WINDOW_EDGE_TOP_RIGHT);\n  else if (x \u003c border \u0026\u0026 y \u003e win-\u003eheight - border) swcl_window_resize(win, SWCL_WINDOW_EDGE_BOTTOM_LEFT);\n  else if (x \u003e win-\u003ewidth - border \u0026\u0026 y \u003e win-\u003eheight - border) swcl_window_resize(win, SWCL_WINDOW_EDGE_BOTTOM_RIGHT);\n  else if (y \u003c border) swcl_window_resize(win, SWCL_WINDOW_EDGE_TOP);\n  else if (y \u003e win-\u003eheight - border) swcl_window_resize(win, SWCL_WINDOW_EDGE_BOTTOM);\n  else if (x \u003c border) swcl_window_resize(win, SWCL_WINDOW_EDGE_LEFT);\n  else if (x \u003e win-\u003ewidth - border) swcl_window_resize(win, SWCL_WINDOW_EDGE_RIGHT);\n}\n\n// Scroll event inside the window callback\nvoid mouse_scroll_cb(SWCLWindow *win, SWCLScrollDirection dir) {\n  printf(\"Scroll %s\\n\", dir == SWCL_SCROLL_DOWN ? \"down\" : \"up\");\n}\n\n// Keyboard key events inside the window callback\nvoid keyboard_key_cb(SWCLWindow *win, size_t key, SWCLButtonState state) {\n  printf(\"Keyboard key %zu %s\\n\", key, state == SWCL_BUTTON_PRESSED ? \"pressed\" : \"released\");\n\n  // Close application if ESC pressed\n  if (key == 1 \u0026\u0026 state == SWCL_BUTTON_PRESSED) swcl_application_quit(win-\u003eapp);\n}\n\n// Keyboard modifiers events inside the window callback\nvoid keyboard_mod_key_cb(SWCLWindow *win, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked,\n                         uint32_t group) {\n  printf(\"Key: mods_depressed=%d, mods_latched=%d, mods_locked=%d, group=%d\\n\", mods_depressed, mods_latched,\n         mods_locked, group);\n}\n\n// Draw window callback. Called every frame.\nvoid draw_window_cb(SWCLWindow *win) {\n  // We will use OpenGL directly here but libraries can be used like rlgl.h\n  // Draw white background\n  glClearColor(1, 1, 1, 1);\n  glClear(GL_COLOR_BUFFER_BIT);\n  // Swap buffers. This function needs to be called at the end.\n  swcl_window_swap_buffers(win);\n}\n\n// ---------- MAIN ---------- //\n\nint main(int argc, char *argv[]) {\n  // Create application and provide callbacks for events\n  SWCLApplication *app = swcl_application_new(\"com.example.App\", pointer_enter_cb, pointer_motion_cb, pointer_leave_cb,\n                                              mouse_button_cb, mouse_scroll_cb, keyboard_key_cb, keyboard_mod_key_cb);\n  // Create window\n  SWCLWindow *win = swcl_window_new(app, \"Hello SWCL!\", 800, 600, 100, 100, false, false, draw_window_cb);\n  swcl_window_show(win);\n  // Run application\n  swcl_application_run(app);\n  return 0;\n}\n```\n\nNow compile it with this command:\n\n```sh\ngcc main.c -o myapp -lwayland-client -lwayland-egl -lwayland-cursor -lGL -lEGL\n```\n\n- `gcc main.c` compiles your code\n- `-o myapp` outputs it to executable file `myapp`\n- `-lwayland-client -lwayland-egl -lwayland-cursor -lGL -lEGL` links our program with needed wayland and OpenGL libraries\n\nAnd then run it with:\n\n```sh\n./myapp\n```\n\nCongratulations! You've created your first Wayland window!\n\n### Running the example\n\n- Clone this repo\n- Run `make example` inside it\n- Run `./example`\n\n### Documentation\n\nSee `swcl.h` for documentation. All of the functions and structs have comments. It's pretty simple.\n\n### Contributions\n\nAll contributions are welcome!\n\n### Donations\n\nIf you like **SWCL** and want to support it, you can send your donations here:\n\n- BTC\n\n```\n14pPYfZohS61PyGyXJyiGQHDFai4JR2q9w\n```\n\n- USDT\n\n```\nTCQn85c3vrRR7yMAfJABZmCXBa7gQvUcX5\n```\n\n- TON\n\n```\nUQBrhmho9259KsNZ8wYx6y_eeOwdcAo9aroOTRWRtnmcUmdr\n```\n\nThank you!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrvladus%2Fswcl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrvladus%2Fswcl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrvladus%2Fswcl/lists"}