static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) { swayc_t *c = get_swayc_for_handle(view, &root_container); switch (state) { case WLC_BIT_FULLSCREEN: // i3 just lets it become fullscreen wlc_view_set_state(view, state, toggle); if (c) { sway_log(L_DEBUG, "setting view %ld %s, fullscreen %d", view, c->name, toggle); arrange_windows(c->parent, -1, -1); // Set it as focused window for that workspace if its going fullscreen if (toggle) { swayc_t *ws = swayc_parent_by_type(c, C_WORKSPACE); // Set ws focus to c set_focused_container_for(ws, c); } } break; case WLC_BIT_MAXIMIZED: case WLC_BIT_RESIZING: case WLC_BIT_MOVING: break; case WLC_BIT_ACTIVATED: sway_log(L_DEBUG, "View %p requested to be activated", c); break; } return; }
struct cmd_results *cmd_floating_maximum_size(int argc, char **argv) { struct cmd_results *error = NULL; int32_t width; int32_t height; char *ptr; if ((error = checkarg(argc, "floating_maximum_size", EXPECTED_EQUAL_TO, 3))) { return error; } width = strtol(argv[0], &ptr, 10); height = strtol(argv[2], &ptr, 10); if (width < -1) { sway_log(L_DEBUG, "floating_maximum_size invalid width value: '%s'", argv[0]); } else { config->floating_maximum_width = width; } if (height < -1) { sway_log(L_DEBUG, "floating_maximum_size invalid height value: '%s'", argv[2]); } else { config->floating_maximum_height = height; } sway_log(L_DEBUG, "New floating_maximum_size: '%d' x '%d'", config->floating_maximum_width, config->floating_maximum_height); return cmd_results_new(CMD_SUCCESS, NULL, NULL); }
void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { struct wlr_xdg_surface_v6 *xdg_surface = data; if (xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { sway_log(SWAY_DEBUG, "New xdg_shell_v6 popup"); return; } sway_log(SWAY_DEBUG, "New xdg_shell_v6 toplevel title='%s' app_id='%s'", xdg_surface->toplevel->title, xdg_surface->toplevel->app_id); wlr_xdg_surface_v6_ping(xdg_surface); struct sway_xdg_shell_v6_view *xdg_shell_v6_view = calloc(1, sizeof(struct sway_xdg_shell_v6_view)); if (!sway_assert(xdg_shell_v6_view, "Failed to allocate view")) { return; } view_init(&xdg_shell_v6_view->view, SWAY_VIEW_XDG_SHELL_V6, &view_impl); xdg_shell_v6_view->view.wlr_xdg_surface_v6 = xdg_surface; xdg_shell_v6_view->map.notify = handle_map; wl_signal_add(&xdg_surface->events.map, &xdg_shell_v6_view->map); xdg_shell_v6_view->unmap.notify = handle_unmap; wl_signal_add(&xdg_surface->events.unmap, &xdg_shell_v6_view->unmap); xdg_shell_v6_view->destroy.notify = handle_destroy; wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_v6_view->destroy); xdg_surface->data = xdg_shell_v6_view; }
bool load_config(const char *file) { input_init(); char *path; if (file != NULL) { path = strdup(file); } else { path = get_config_path(); } sway_log(L_INFO, "Loading config from %s", path); if (path == NULL) { sway_log(L_ERROR, "Unable to find a config file!"); return false; } FILE *f = fopen(path, "r"); if (!f) { fprintf(stderr, "Unable to open %s for reading", path); free(path); return false; } free(path); bool config_load_success; if (config) { config_load_success = read_config(f, true); } else { config_load_success = read_config(f, false); } fclose(f); return config_load_success; }
void swaynag_log(const char *swaynag_command, struct swaynag_instance *swaynag, const char *fmt, ...) { if (!swaynag_command) { return; } if (!swaynag->detailed) { sway_log(SWAY_ERROR, "Attempting to write to non-detailed swaynag inst"); return; } if (swaynag->pid <= 0 && !swaynag_spawn(swaynag_command, swaynag)) { return; } va_list args; va_start(args, fmt); size_t length = vsnprintf(NULL, 0, fmt, args) + 1; va_end(args); char *temp = malloc(length + 1); if (!temp) { sway_log(SWAY_ERROR, "Failed to allocate buffer for swaynag log entry."); return; } va_start(args, fmt); vsnprintf(temp, length, fmt, args); va_end(args); write(swaynag->fd[1], temp, length); free(temp); }
char *libinput_dev_unique_id(struct libinput_device *device) { int vendor = libinput_device_get_id_vendor(device); int product = libinput_device_get_id_product(device); char *name = strdup(libinput_device_get_name(device)); char *p = name; for (; *p; ++p) { if (*p == ' ') { *p = '_'; } } sway_log(L_DEBUG, "rewritten name %s", name); int len = strlen(name) + sizeof(char) * 6; char *identifier = malloc(len); if (!identifier) { sway_log(L_ERROR, "Unable to allocate unique input device name"); return NULL; } const char *fmt = "%d:%d:%s"; snprintf(identifier, len, fmt, vendor, product, name); free(name); return identifier; }
struct input_config *new_input_config(const char* identifier) { struct input_config *input = calloc(1, sizeof(struct input_config)); if (!input) { sway_log(L_DEBUG, "Unable to allocate input config"); return NULL; } sway_log(L_DEBUG, "new_input_config(%s)", identifier); if (!(input->identifier = strdup(identifier))) { free(input); sway_log(L_DEBUG, "Unable to allocate input config"); return NULL; } input->tap = INT_MIN; input->drag_lock = INT_MIN; input->dwt = INT_MIN; input->send_events = INT_MIN; input->click_method = INT_MIN; input->middle_emulation = INT_MIN; input->natural_scroll = INT_MIN; input->accel_profile = INT_MIN; input->pointer_accel = FLT_MIN; input->scroll_method = INT_MIN; input->left_handed = INT_MIN; return input; }
static bool load_config(const char *path, struct sway_config *config) { sway_log(L_INFO, "Loading config from %s", path); current_config_path = path; struct stat sb; if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { return false; } if (path == NULL) { sway_log(L_ERROR, "Unable to find a config file!"); return false; } FILE *f = fopen(path, "r"); if (!f) { sway_log(L_ERROR, "Unable to open %s for reading", path); return false; } bool config_load_success = read_config(f, config); fclose(f); if (!config_load_success) { sway_log(L_ERROR, "Error(s) loading config!"); } current_config_path = NULL; return true; }
bool read_config(FILE *file, bool is_active) { struct sway_config *temp_config = malloc(sizeof(struct sway_config)); config_defaults(temp_config); if (is_active) { sway_log(L_DEBUG, "Performing configuration file reload"); temp_config->reloading = true; temp_config->active = true; } bool success = true; int temp_depth = 0; // Temporary: skip all config sections with depth while (!feof(file)) { int _; char *line = read_line(file); line = strip_whitespace(line, &_); line = strip_comments(line); if (!line[0]) { goto _continue; } if (temp_depth && line[0] == '}') { temp_depth--; goto _continue; } // Any command which would require wlc to be initialized // should be queued for later execution list_t *args = split_string(line, " "); if (!is_active && ( strcmp("exec", args->items[0]) == 0 || strcmp("exec_always", args->items[0]) == 0 )) { sway_log(L_DEBUG, "Deferring command %s", line); char *cmd = malloc(strlen(line) + 1); strcpy(cmd, line); list_add(temp_config->cmd_queue, cmd); } else if (!temp_depth && !handle_command(temp_config, line)) { sway_log(L_DEBUG, "Config load failed for line %s", line); success = false; temp_config->failed = true; } list_free(args); _continue: if (line && line[strlen(line) - 1] == '{') { temp_depth++; } free(line); } if (is_active) { temp_config->reloading = false; container_map(&root_container, reset_gaps, NULL); arrange_windows(&root_container, -1, -1); } config = temp_config; return success; }
static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, uint32_t button, enum wlc_button_state state) { swayc_t *focused = get_focused_container(&root_container); if (state == WLC_BUTTON_STATE_PRESSED) { sway_log(L_DEBUG, "Mouse button %u pressed", button); if (button == 272) { m1_held = true; } if (button == 273) { m2_held = true; } swayc_t *pointer = container_under_pointer(); set_focused_container(pointer); return (pointer && pointer != focused); } else { sway_log(L_DEBUG, "Mouse button %u released", button); if (button == 272) { m1_held = false; } if (button == 273) { m2_held = false; } } return false; }
int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) { struct ipc_client *client = data; if (mask & WLC_EVENT_ERROR) { sway_log(L_INFO, "IPC Client socket error, removing client"); client->fd = -1; ipc_client_disconnect(client); return 0; } if (mask & WLC_EVENT_HANGUP) { client->fd = -1; ipc_client_disconnect(client); return 0; } int read_available; if (ioctl(client_fd, FIONREAD, &read_available) == -1) { sway_log_errno(L_INFO, "Unable to read IPC socket buffer size"); ipc_client_disconnect(client); return 0; } // Wait for the rest of the command payload in case the header has already been read if (client->payload_length > 0) { if ((uint32_t)read_available >= client->payload_length) { ipc_client_handle_command(client); } return 0; } if (read_available < ipc_header_size) { return 0; } uint8_t buf[ipc_header_size]; uint32_t *buf32 = (uint32_t*)(buf + sizeof(ipc_magic)); ssize_t received = recv(client_fd, buf, ipc_header_size, 0); if (received == -1) { sway_log_errno(L_INFO, "Unable to receive header from IPC client"); ipc_client_disconnect(client); return 0; } if (memcmp(buf, ipc_magic, sizeof(ipc_magic)) != 0) { sway_log(L_DEBUG, "IPC header check failed"); ipc_client_disconnect(client); return 0; } client->payload_length = buf32[0]; client->current_command = (enum ipc_command_type)buf32[1]; if (read_available - received >= (long)client->payload_length) { ipc_client_handle_command(client); } return 0; }
char *workspace_next_name(void) { sway_log(L_DEBUG, "Workspace: Generating new name"); int i; int l = 1; // Scan all workspace bindings to find the next available workspace name, // if none are found/available then default to a number struct sway_mode *mode = config->current_mode; for (i = 0; i < mode->bindings->length; ++i) { struct sway_binding *binding = mode->bindings->items[i]; const char* command = binding->command; list_t *args = split_string(command, " "); if (strcmp("workspace", args->items[0]) == 0 && args->length > 1) { sway_log(L_DEBUG, "Got valid workspace command for target: '%s'", (char *)args->items[1]); char* target = malloc(strlen(args->items[1]) + 1); strcpy(target, args->items[1]); while (*target == ' ' || *target == '\t') target++; // Make sure that the command references an actual workspace // not a command about workspaces if (strcmp(target, "next") == 0 || strcmp(target, "prev") == 0 || strcmp(target, "next_on_output") == 0 || strcmp(target, "prev_on_output") == 0 || strcmp(target, "number") == 0 || strcmp(target, "back_and_forth") == 0 || strcmp(target, "current") == 0) { free_flat_list(args); continue; } // Make sure that the workspace doesn't already exist if (workspace_by_name(target)) { free_flat_list(args); continue; } free_flat_list(args); sway_log(L_DEBUG, "Workspace: Found free name %s", target); return target; } free_flat_list(args); } // As a fall back, get the current number of active workspaces // and return that + 1 for the next workspace's name int ws_num = root_container.children->length; if (ws_num >= 10) { l = 2; } else if (ws_num >= 100) { l = 3; } char *name = malloc(l + 1); sprintf(name, "%d", ws_num++); return name; }
static void wlc_log_handler(enum wlc_log_type type, const char *str) { if (type == WLC_LOG_ERROR) { sway_log(L_ERROR, "[wlc] %s", str); } else if (type == WLC_LOG_WARN) { sway_log(L_INFO, "[wlc] %s", str); } else { sway_log(L_DEBUG, "[wlc] %s", str); } }
void bar_run(struct bar *bar) { int pfds = bar->outputs->length + 2; struct pollfd *pfd = malloc(pfds * sizeof(struct pollfd)); bool dirty = true; pfd[0].fd = bar->ipc_event_socketfd; pfd[0].events = POLLIN; pfd[1].fd = bar->status_read_fd; pfd[1].events = POLLIN; int i; for (i = 0; i < bar->outputs->length; ++i) { struct output *output = bar->outputs->items[i]; pfd[i+2].fd = wl_display_get_fd(output->registry->display); pfd[i+2].events = POLLIN; } while (1) { if (dirty) { int i; for (i = 0; i < bar->outputs->length; ++i) { struct output *output = bar->outputs->items[i]; if (window_prerender(output->window) && output->window->cairo) { render(output, bar->config, bar->status); window_render(output->window); wl_display_flush(output->registry->display); } } } dirty = false; poll(pfd, pfds, -1); if (pfd[0].revents & POLLIN) { sway_log(L_DEBUG, "Got IPC event."); dirty = handle_ipc_event(bar); } if (bar->config->status_command && pfd[1].revents & POLLIN) { sway_log(L_DEBUG, "Got update from status command."); dirty = handle_status_line(bar); } // dispatch wl_display events for (i = 0; i < bar->outputs->length; ++i) { struct output *output = bar->outputs->items[i]; if (pfd[i+2].revents & POLLIN) { if (wl_display_dispatch(output->registry->display) == -1) { sway_log(L_ERROR, "failed to dispatch wl: %d", errno); } } else { wl_display_dispatch_pending(output->registry->display); } } } }
void arrange_workspace(struct sway_workspace *workspace) { if (config->reloading) { return; } if (!workspace->output) { // Happens when there are no outputs connected return; } struct sway_output *output = workspace->output; struct wlr_box *area = &output->usable_area; sway_log(SWAY_DEBUG, "Usable area for ws: %dx%d@%d,%d", area->width, area->height, area->x, area->y); workspace_remove_gaps(workspace); bool first_arrange = workspace->width == 0 && workspace->height == 0; double prev_x = workspace->x; double prev_y = workspace->y; workspace->width = area->width; workspace->height = area->height; workspace->x = output->wlr_output->lx + area->x; workspace->y = output->wlr_output->ly + area->y; // Adjust any floating containers double diff_x = workspace->x - prev_x; double diff_y = workspace->y - prev_y; if (!first_arrange && (diff_x != 0 || diff_y != 0)) { for (int i = 0; i < workspace->floating->length; ++i) { struct sway_container *floater = workspace->floating->items[i]; container_floating_translate(floater, diff_x, diff_y); double center_x = floater->x + floater->width / 2; double center_y = floater->y + floater->height / 2; struct wlr_box workspace_box; workspace_get_box(workspace, &workspace_box); if (!wlr_box_contains_point(&workspace_box, center_x, center_y)) { container_floating_move_to_center(floater); } } } workspace_add_gaps(workspace); node_set_dirty(&workspace->node); sway_log(SWAY_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name, workspace->x, workspace->y); if (workspace->fullscreen) { struct sway_container *fs = workspace->fullscreen; fs->x = output->lx; fs->y = output->ly; fs->width = output->width; fs->height = output->height; arrange_container(fs); } else { struct wlr_box box; workspace_get_box(workspace, &box); arrange_children(workspace->tiling, workspace->layout, &box); arrange_floating(workspace->floating); } }
int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) { struct ipc_client *client = data; sway_log(L_DEBUG, "Event on IPC client socket %d", client_fd); if (mask & WLC_EVENT_ERROR) { sway_log(L_INFO, "IPC Client socket error, removing client"); ipc_client_disconnect(client); return 0; } if (mask & WLC_EVENT_HANGUP) { ipc_client_disconnect(client); return 0; } int read_available; ioctl(client_fd, FIONREAD, &read_available); // Wait for the rest of the command payload in case the header has already been read if (client->payload_length > 0) { if (read_available >= client->payload_length) { ipc_client_handle_command(client); } else { sway_log(L_DEBUG, "Too little data to read payload on IPC Client socket, waiting for more (%d < %d)", read_available, client->payload_length); } return 0; } if (read_available < ipc_header_size) { sway_log(L_DEBUG, "Too little data to read header on IPC Client socket, waiting for more (%d < %d)", read_available, ipc_header_size); return 0; } char buf[ipc_header_size]; ssize_t received = recv(client_fd, buf, ipc_header_size, 0); if (received == -1) { sway_log_errno(L_INFO, "Unable to receive header from IPC client"); ipc_client_disconnect(client); return 0; } if (memcmp(buf, ipc_magic, sizeof(ipc_magic)) != 0) { sway_log(L_DEBUG, "IPC header check failed"); ipc_client_disconnect(client); return 0; } client->payload_length = *(uint32_t *)&buf[sizeof(ipc_magic)]; client->current_command = (enum ipc_command_type) *(uint32_t *)&buf[sizeof(ipc_magic)+4]; if (read_available - received >= client->payload_length) { ipc_client_handle_command(client); } return 0; }
void apply_output_config(struct output_config *oc, swayc_t *output) { if (oc && oc->width > 0 && oc->height > 0) { output->width = oc->width; output->height = oc->height; sway_log(L_DEBUG, "Set %s size to %ix%i", oc->name, oc->width, oc->height); struct wlc_size new_size = { .w = oc->width, .h = oc->height }; wlc_output_set_resolution(output->handle, &new_size); } // Find position for it if (oc && oc->x != -1 && oc->y != -1) { sway_log(L_DEBUG, "Set %s position to %d, %d", oc->name, oc->x, oc->y); output->x = oc->x; output->y = oc->y; } else { int x = 0; for (int i = 0; i < root_container.children->length; ++i) { swayc_t *c = root_container.children->items[i]; if (c->type == C_OUTPUT) { if (c->width + c->x > x) { x = c->width + c->x; } } } output->x = x; } if (oc && oc->background) { int i; for (i = 0; i < root_container.children->length; ++i) { if (root_container.children->items[i] == output) { break; } } sway_log(L_DEBUG, "Setting background for output %d to %s", i, oc->background); size_t bufsize = 4; char output_id[bufsize]; snprintf(output_id, bufsize, "%d", i); output_id[bufsize-1] = 0; char *const cmd[] = { "swaybg", output_id, oc->background, oc->background_option, NULL, }; if (fork() == 0) { execvp(cmd[0], cmd); } } }
static bool load_include_config(const char *path, const char *parent_dir, struct sway_config *config) { // save parent config const char *parent_config = config->current_config; char *full_path = strdup(path); int len = strlen(path); if (len >= 1 && path[0] != '/') { len = len + strlen(parent_dir) + 2; full_path = malloc(len * sizeof(char)); if (!full_path) { sway_log(L_ERROR, "Unable to allocate full path to included config"); return false; } snprintf(full_path, len, "%s/%s", parent_dir, path); } char *real_path = realpath(full_path, NULL); free(full_path); if (real_path == NULL) { sway_log(L_DEBUG, "%s not found.", path); return false; } // check if config has already been included int j; for (j = 0; j < config->config_chain->length; ++j) { char *old_path = config->config_chain->items[j]; if (strcmp(real_path, old_path) == 0) { sway_log(L_DEBUG, "%s already included once, won't be included again.", real_path); free(real_path); return false; } } config->current_config = real_path; list_add(config->config_chain, real_path); int index = config->config_chain->length - 1; if (!load_config(real_path, config)) { free(real_path); config->current_config = parent_config; list_del(config->config_chain, index); return false; } // restore current_config config->current_config = parent_config; return true; }
swayc_t *workspace_for_pid(pid_t pid) { int i; swayc_t *ws = NULL; struct pid_workspace *pw = NULL; sway_log(L_DEBUG, "looking for workspace for pid %d", pid); // leaving this here as it's useful for debugging // sway_log(L_DEBUG, "all pid_workspaces"); // for (int k = 0; k < config->pid_workspaces->length; k++) { // pw = config->pid_workspaces->items[k]; // sway_log(L_DEBUG, "pid %d workspace %s time_added %li", *pw->pid, pw->workspace, *pw->time_added); // } do { for (i = 0; i < config->pid_workspaces->length; i++) { pw = config->pid_workspaces->items[i]; pid_t *pw_pid = pw->pid; if (pid == *pw_pid) { sway_log(L_DEBUG, "found pid_workspace for pid %d, workspace %s", pid, pw->workspace); break; // out of for loop } pw = NULL; } if (pw) { break; // out of do-while loop } pid = get_parent_pid(pid); // no sense in looking for matches for pid 0. // also, if pid == getpid(), that is the compositor's // pid, which definitely isn't helpful } while (pid > 0 && pid != getpid()); if (pw) { ws = workspace_by_name(pw->workspace); if (!ws) { sway_log(L_DEBUG, "Creating workspace %s for pid %d because it disappeared", pw->workspace, pid); ws = workspace_create(pw->workspace); } list_del(config->pid_workspaces, i); } return ws; }
static struct panel_config *find_or_create_panel_config(struct wl_resource *resource) { for (int i = 0; i < desktop_shell.panels->length; i++) { struct panel_config *conf = desktop_shell.panels->items[i]; if (conf->wl_resource == resource) { sway_log(L_DEBUG, "Found existing panel config for resource %p", resource); return conf; } } sway_log(L_DEBUG, "Creating panel config for resource %p", resource); struct panel_config *config = calloc(1, sizeof(struct panel_config)); list_add(desktop_shell.panels, config); config->wl_resource = resource; return config; }
swayc_t *destroy_view(swayc_t *view) { if (view == NULL) { sway_log(L_DEBUG, "Warning: NULL passed into destroy_view"); return NULL; } sway_log(L_DEBUG, "Destroying view '%p'", view); swayc_t *parent = view->parent; free_swayc(view); //Destroy empty containers if (parent->type == C_CONTAINER) { return destroy_container(parent); } return parent; }
bool workspace_switch(swayc_t *workspace) { if (!workspace) { return false; } swayc_t *active_ws = swayc_active_workspace(); if (config->auto_back_and_forth && active_ws == workspace && prev_workspace_name) { swayc_t *new_ws = workspace_by_name(prev_workspace_name); workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); } if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) && active_ws != workspace)) { free(prev_workspace_name); prev_workspace_name = malloc(strlen(active_ws->name)+1); strcpy(prev_workspace_name, active_ws->name); } // move sticky containers if (swayc_parent_by_type(active_ws, C_OUTPUT) == swayc_parent_by_type(workspace, C_OUTPUT)) { // don't change list while traversing it, use intermediate list instead list_t *stickies = create_list(); for (int i = 0; i < active_ws->floating->length; i++) { swayc_t *cont = active_ws->floating->items[i]; if (cont->sticky) { list_add(stickies, cont); } } for (int i = 0; i < stickies->length; i++) { swayc_t *cont = stickies->items[i]; sway_log(L_DEBUG, "Moving sticky container %p to %p:%s", cont, workspace, workspace->name); swayc_t *parent = remove_child(cont); add_floating(workspace, cont); // Destroy old container if we need to destroy_container(parent); } list_free(stickies); } sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); if (!set_focused_container(get_focused_view(workspace))) { return false; } swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT); arrange_backgrounds(); arrange_windows(output, -1, -1); return true; }
swayc_t *new_output(wlc_handle handle) { const struct wlc_size* size = wlc_output_get_resolution(handle); const char *name = wlc_output_get_name(handle); sway_log(L_DEBUG, "Added output %u %s", (unsigned int)handle, name); swayc_t *output = new_swayc(C_OUTPUT); output->width = size->w; output->height = size->h; output->handle = handle; if (name) { output->name = strdup(name); } add_child(&root_container, output); //TODO something with this int total_width = 0; container_map(&root_container, add_output_widths, &total_width); //Create workspace char *ws_name = workspace_next_name(); new_workspace(output, ws_name); free(ws_name); return output; }
int function_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { const char* msg_style_names[] = { NULL, "PAM_PROMPT_ECHO_OFF", "PAM_PROMPT_ECHO_ON", "PAM_ERROR_MSG", "PAM_TEXT_INFO", }; /* PAM expects an array of responses, one for each message */ struct pam_response *pam_reply = calloc(num_msg, sizeof(struct pam_response)); *resp = pam_reply; for(int i=0; i<num_msg; ++i) { sway_log(L_DEBUG, "msg[%d]: (%s) %s", i, msg_style_names[msg[i]->msg_style], msg[i]->msg); switch (msg[i]->msg_style) { case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_ON: pam_reply[i].resp = password; break; case PAM_ERROR_MSG: case PAM_TEXT_INFO: break; } } return PAM_SUCCESS; }
static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) { switch(state) { case WLC_BIT_FULLSCREEN: { //I3 just lets it become fullscreen wlc_view_set_state(view,state,toggle); swayc_t *c = get_swayc_for_handle(view, &root_container); sway_log(L_DEBUG, "setting view %ld %s, fullscreen %d",view,c->name,toggle); if (c) { arrange_windows(c->parent, -1, -1); //Set it as focused window for that workspace if its going //fullscreen if (toggle) { swayc_t *ws = c; while (ws->type != C_WORKSPACE) { ws = ws->parent; } //Set ws focus to c focus_view_for(ws, c); } } break; } case WLC_BIT_MAXIMIZED: case WLC_BIT_RESIZING: case WLC_BIT_MOVING: case WLC_BIT_ACTIVATED: break; } return; }
static void handle_view_destroyed(wlc_handle handle) { sway_log(L_DEBUG, "Destroying window %lu", handle); swayc_t *view = get_swayc_for_handle(handle, &root_container); switch (wlc_view_get_type(handle)) { // regular view created regularly case 0: case WLC_BIT_MODAL: if (view) { swayc_t *parent = destroy_view(view); arrange_windows(parent, -1, -1); } break; // takes keyboard focus case WLC_BIT_OVERRIDE_REDIRECT: locked_view_focus = false; break; // Takes container focus case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: locked_container_focus = false; case WLC_BIT_POPUP: break; } set_focused_container(get_focused_view(&root_container)); }
// de-dupe pid_workspaces to ensure pid uniqueness void pid_workspace_add(struct pid_workspace *pw) { struct pid_workspace *list_pw = NULL; struct timespec ts; time_t *now = malloc(sizeof(time_t)); if (!now) { sway_log(L_ERROR, "Allocating time for pid_workspace failed"); return; } pid_workspace_cleanup(); // add current time to pw clock_gettime(CLOCK_MONOTONIC, &ts); *now = ts.tv_sec; pw->time_added = now; // work backwards through list and delete any entries that // have the same pid as that in our new pid_workspace for (int i = config->pid_workspaces->length - 1; i > -1; i--) { list_pw = config->pid_workspaces->items[i]; if (pw->pid == list_pw->pid) { free_pid_workspace(config->pid_workspaces->items[i]); list_del(config->pid_workspaces, i); } } list_add(config->pid_workspaces, pw); }
static char *get_config_path(void) { static const char *config_paths[] = { "$HOME/.sway/config", "$XDG_CONFIG_HOME/sway/config", "$HOME/.i3/config", "$XDG_CONFIG_HOME/i3/config", FALLBACK_CONFIG_DIR "/config", "/etc/i3/config", }; if (!getenv("XDG_CONFIG_HOME")) { char *home = getenv("HOME"); char *config_home = malloc(strlen("home") + strlen("/.config") + 1); strcpy(config_home, home); strcat(config_home, "/.config"); setenv("XDG_CONFIG_HOME", config_home, 1); sway_log(L_DEBUG, "Set XDG_CONFIG_HOME to %s", config_home); } wordexp_t p; char *path; int i; for (i = 0; i < (int)(sizeof(config_paths) / sizeof(char *)); ++i) { if (wordexp(config_paths[i], &p, 0) == 0) { path = p.we_wordv[0]; if (file_exists(path)) { return path; } } } return NULL; // Not reached }
static void handle_view_destroyed(wlc_handle handle) { sway_log(L_DEBUG, "Destroying window %lu", handle); swayc_t *view = get_swayc_for_handle(handle, &root_container); switch (wlc_view_get_type(handle)) { // regular view created regularly case 0: case WLC_BIT_MODAL: case WLC_BIT_POPUP: if (view) { swayc_t *parent = destroy_view(view); arrange_windows(parent, -1, -1); } break; // DMENU has this flag, and takes view_focus, but other things with this // flag dont case WLC_BIT_OVERRIDE_REDIRECT: // locked_view_focus = false; break; case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: locked_container_focus = false; break; } set_focused_container(get_focused_view(&root_container)); }
struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) { const char *cmd_name = "tray_padding"; #ifndef ENABLE_TRAY return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command" "%s called, but sway was compiled without tray support", cmd_name, cmd_name); #else struct cmd_results *error = NULL; if ((error = checkarg(argc, cmd_name, EXPECTED_AT_LEAST, 1))) { return error; } if (!config->current_bar) { return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined."); } if (argc == 1 || (argc == 2 && strcasecmp("px", argv[1]) == 0)) { char *inv; uint32_t padding = strtoul(argv[0], &inv, 10); if (*inv == '\0' || strcasecmp(inv, "px") == 0) { config->current_bar->tray_padding = padding; sway_log(L_DEBUG, "Enabling tray padding of %d px on bar: %s", padding, config->current_bar->id); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } } return cmd_results_new(CMD_FAILURE, cmd_name, "Expected 'tray_padding <padding>[px]'"); #endif }