diff --git a/Examples/test_script_mode.sh b/Examples/test_script_mode.sh
index 68b931be1..bae2816f8 100755
--- a/Examples/test_script_mode.sh
+++ b/Examples/test_script_mode.sh
@@ -1,32 +1,29 @@
#!/usr/bin/env bash
-if [ "$*" = "quit" ]
-then
- exit 0
+if [ "$*" = "quit" ]; then
+ exit 0
fi
-if [ "$@" ]
-then
- # Override the previously set prompt.
- echo -en "\x00prompt\x1fChange prompt\n"
- for a in {1..10}
- do
- echo "$a"
- done
- echo "quit"
+if [ "$@" ]; then
+ # Override the previously set prompt.
+ echo -en "\x00prompt\x1fChange prompt\n"
+ for a in {1..10}; do
+ echo "$a"
+ done
+ echo "quit"
else
- echo -en "\x00prompt\x1ftesting\n"
- echo -en "\0urgent\x1f0,2\n"
- echo -en "\0active\x1f1\n"
- echo -en "\0markup-rows\x1ftrue\n"
- echo -en "\0message\x1fSpecial boldmessage\n"
+ echo -en "\x00prompt\x1ftesting\n"
+ echo -en "\0urgent\x1f0,2\n"
+ echo -en "\0active\x1f1\n"
+ echo -en "\0markup-rows\x1ftrue\n"
+ echo -en "\0message\x1fSpecial boldmessage\n"
- echo -en "aap\0icon\x1ffolder\n"
- echo -en "blob\0icon\x1ffolder\x1fdisplay\x1fblub\n"
- echo "noot"
- echo "mies"
- echo -en "-------------\0nonselectable\x1ftrue\n"
- echo "testing"
- echo "Bold"
- echo "quit"
+ echo -en "aap\0icon\x1ffolder\n"
+ echo -en "blob\0icon\x1ffolder\x1fdisplay\x1fblub\n"
+ echo "noot"
+ echo "mies"
+ echo -en "-------------\0nonselectable\x1ftrue\x1fpermanent\x1ftrue\n"
+ echo "testing"
+ echo "Bold"
+ echo "quit"
fi
diff --git a/INSTALL.md b/INSTALL.md
index 38da5508b..eb3f668c8 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -42,7 +42,7 @@ You can also use [Meson](https://mesonbuild.com/) as an alternative.
- libcairo-xcb
-- libglib2.0 >= 2.68
+- libglib2.0 >= 2.72
- gmodule-2.0
- gio-unix-2.0
diff --git a/configure.ac b/configure.ac
index 908b2f809..2b97e3662 100644
--- a/configure.ac
+++ b/configure.ac
@@ -74,7 +74,7 @@ AM_PROG_AR
dnl ---------------------------------------------------------------------
dnl Base CFLAGS
dnl ---------------------------------------------------------------------
-AM_CFLAGS="-Wall -Wextra -Wparentheses -Winline -pedantic -Wunreachable-code"
+AM_CFLAGS="-Wall -Wextra -Wparentheses -Winline -pedantic -Wno-overlength-strings -Wunreachable-code"
dnl ---------------------------------------------------------------------
dnl Enable source code coverage reporting for GCC
@@ -139,7 +139,7 @@ dnl ---------------------------------------------------------------------
dnl PKG_CONFIG based dependencies
dnl ---------------------------------------------------------------------
glib_min_major="2"
-glib_min_minor="40"
+glib_min_minor="72"
glib_min_version="${glib_min_major}.${glib_min_minor}"
NK_INIT([bindings xdg-theme])
PKG_CHECK_MODULES([glib], [glib-2.0 >= ${glib_min_version} gio-unix-2.0 gmodule-2.0])
diff --git a/doc/meson.build b/doc/meson.build
index 8a2f8c5c7..e898a5b08 100644
--- a/doc/meson.build
+++ b/doc/meson.build
@@ -25,8 +25,8 @@ endif
doxy_conf = configuration_data()
doxy_conf.set('PACKAGE', meson.project_name())
doxy_conf.set('VERSION', meson.project_version())
-doxy_conf.set('abs_builddir', join_paths(meson.build_root(), meson.current_build_dir()))
-doxy_conf.set('abs_top_srcdir', meson.source_root())
+doxy_conf.set('abs_builddir', join_paths(meson.project_build_root(), meson.current_build_dir()))
+doxy_conf.set('abs_top_srcdir', meson.project_source_root())
doxyfile = configure_file(
input: 'rofi.doxy.in',
diff --git a/doc/rofi-script.5 b/doc/rofi-script.5
index a09e2decf..6b0c2126b 100644
--- a/doc/rofi-script.5
+++ b/doc/rofi-script.5
@@ -185,6 +185,8 @@ The following options are supported:
.IP \(bu 2
\fBnonselectable\fP: If true the row cannot activated.
.IP \(bu 2
+\fBpermantent\fP: If true the row always shows, independent of filter.
+.IP \(bu 2
\fBinfo\fP: Info that, on selection, gets placed in the \fB\fCROFI_INFO\fR
environment variable. This entry does not get searched for filtering.
.IP \(bu 2
diff --git a/doc/rofi-script.5.markdown b/doc/rofi-script.5.markdown
index 03df5bc92..65bb318da 100644
--- a/doc/rofi-script.5.markdown
+++ b/doc/rofi-script.5.markdown
@@ -143,6 +143,8 @@ The following options are supported:
- **nonselectable**: If true the row cannot activated.
+- **permantent**: If true the row always shows, independent of filter.
+
- **info**: Info that, on selection, gets placed in the `ROFI_INFO`
environment variable. This entry does not get searched for filtering.
diff --git a/include/modes/dmenuscriptshared.h b/include/modes/dmenuscriptshared.h
index bf83d7412..56a22c8c0 100644
--- a/include/modes/dmenuscriptshared.h
+++ b/include/modes/dmenuscriptshared.h
@@ -26,6 +26,9 @@ typedef struct {
/** non-selectable */
gboolean nonselectable;
+ /** permanent */
+ gboolean permanent;
+
/** urgent */
gboolean urgent;
/** active */
diff --git a/include/rofi-types.h b/include/rofi-types.h
index 4fdb3e37b..9ca29f565 100644
--- a/include/rofi-types.h
+++ b/include/rofi-types.h
@@ -370,6 +370,7 @@ typedef struct rofi_int_matcher_t {
*/
typedef struct _thread_state {
void (*callback)(struct _thread_state *t, gpointer data);
+ void (*free)(void *);
int priority;
} thread_state;
diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y
index 4d118619b..57651a212 100644
--- a/lexer/theme-parser.y
+++ b/lexer/theme-parser.y
@@ -672,11 +672,11 @@ t_property_scale_type
t_color_list
: t_property_color {
- $$ = g_list_append ( NULL, g_memdup ( (gconstpointer)&($1), sizeof ( ThemeColor )));
+ $$ = g_list_append ( NULL, g_memdup2 ( (gconstpointer)&($1), sizeof ( ThemeColor )));
}
| t_color_list T_COMMA t_property_color {
- $$ = g_list_append ($1, g_memdup ( (gconstpointer)&($3), sizeof ( ThemeColor )));
+ $$ = g_list_append ($1, g_memdup2 ( (gconstpointer)&($3), sizeof ( ThemeColor )));
}
;
diff --git a/meson.build b/meson.build
index ff5fb2b35..57260a5a2 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
project('rofi', 'c',
version: '1.7.5-dev',
- meson_version: '>=0.47.0',
+ meson_version: '>=0.59.0',
license: [ 'MIT' ],
default_options: [
'c_std=c99',
@@ -11,8 +11,8 @@ project('rofi', 'c',
c_compiler = meson.get_compiler('c')
add_project_arguments(
- '-I@0@'.format(meson.build_root()),
- '-I@0@'.format(join_paths(meson.source_root(), 'include')),
+ '-I@0@'.format(meson.project_build_root()),
+ '-I@0@'.format(join_paths(meson.project_source_root(), 'include')),
'-D_DEFAULT_SOURCE=1',
language: 'c'
)
@@ -22,6 +22,7 @@ flags = [
'-Winline',
'-Wunreachable-code',
'-Werror=missing-prototypes',
+ '-Wno-overlength-strings',
'-Wno-inline' # A bit too noisy with Bison…
]
foreach f : flags
@@ -42,7 +43,7 @@ desktop_install_dir = join_paths(get_option('datadir'), 'applications')
icondir = join_paths(get_option('datadir'), 'icons','hicolor', 'scalable', 'apps')
glib_min_major=2
-glib_min_minor=40
+glib_min_minor=72
glib_min_version='@0@.@1@'.format(glib_min_major, glib_min_minor)
plugins_deps = [
dependency('glib-2.0', version: '>= @0@'.format(glib_min_version)),
@@ -129,7 +130,7 @@ config_h = configure_file(output: 'config.h', configuration: header_conf)
nk_options = [
'bindings=true',
- 'git-work-tree=@0@'.format(meson.source_root()),
+ 'git-work-tree=@0@'.format(meson.project_source_root()),
]
nk = subproject('libnkutils', default_options: nk_options)
nk_subproject_options = nk.get_variable('nk_options')
@@ -538,7 +539,7 @@ if cppcheck.found()
'--enable=all',
'-Uerror_dialog',
'--inconclusive',
- '-I@0@'.format(join_paths(meson.source_root(), 'include')),
+ '-I@0@'.format(join_paths(meson.project_source_root(), 'include')),
rofi_sources
],
)
diff --git a/source/helper.c b/source/helper.c
index 34d6bc01c..53f366bf0 100644
--- a/source/helper.c
+++ b/source/helper.c
@@ -816,7 +816,7 @@ char *rofi_force_utf8(const gchar *data, ssize_t length) {
GString *string;
if (g_utf8_validate(data, length, &end)) {
- return g_memdup(data, length + 1);
+ return g_memdup2(data, length + 1);
}
string = g_string_sized_new(length + 16);
diff --git a/source/modes/dmenu.c b/source/modes/dmenu.c
index d6a0189e4..d393fd36f 100644
--- a/source/modes/dmenu.c
+++ b/source/modes/dmenu.c
@@ -139,6 +139,7 @@ static void read_add_block(DmenuModePrivateData *pd, Block **block, char *data,
(*block)->values[(*block)->length].meta = NULL;
(*block)->values[(*block)->length].info = NULL;
(*block)->values[(*block)->length].nonselectable = FALSE;
+ (*block)->values[(*block)->length].permanent = FALSE;
char *end = data;
while (end < data + len && *end != '\0') {
end++;
@@ -668,6 +669,11 @@ static int dmenu_token_match(const Mode *sw, rofi_int_matcher **tokens,
/** Strip out the markup when matching. */
char *esc = NULL;
+ if (rmpd->cmd_list[index].permanent == TRUE) {
+ // Always match
+ return 1;
+ }
+
if (rmpd->do_markup) {
pango_parse_markup(rmpd->cmd_list[index].entry, -1, 0, NULL, &esc, NULL,
NULL);
diff --git a/source/modes/drun.c b/source/modes/drun.c
index b05ce48e4..c18d8f95b 100644
--- a/source/modes/drun.c
+++ b/source/modes/drun.c
@@ -1010,6 +1010,7 @@ static gboolean drun_read_cache(DRunModePrivateData *pd,
drun_read_stringv(fd, &(entry->keywords));
drun_read_string(fd, &(entry->comment));
+ drun_read_string(fd, &(entry->url));
int32_t type = 0;
drun_read_integer(fd, &(type));
entry->type = type;
@@ -1081,7 +1082,7 @@ static void get_apps(DRunModePrivateData *pd) {
g_free(cache_file);
}
-static void drun_mode_parse_entry_fields() {
+static void drun_mode_parse_entry_fields(void) {
char *savept = NULL;
// Make a copy, as strtok will modify it.
char *switcher_str = g_strdup(config.drun_match_fields);
@@ -1117,7 +1118,7 @@ static void drun_mode_parse_entry_fields() {
g_free(switcher_str);
}
-static void drun_mode_parse_display_format() {
+static void drun_mode_parse_display_format(void) {
for (int i = 0; i < DRUN_MATCH_NUM_FIELDS; i++) {
if (matching_entry_fields[i].enabled_display)
continue;
diff --git a/source/modes/recursivebrowser.c b/source/modes/recursivebrowser.c
index 67528b62f..c5ab54d0e 100644
--- a/source/modes/recursivebrowser.c
+++ b/source/modes/recursivebrowser.c
@@ -335,7 +335,7 @@ static unsigned int recursive_browser_mode_get_num_entries(const Mode *sw) {
return pd->array_length;
}
-static ModeMode recursive_browser_mode_result(Mode *sw, int mretv, char **input,
+static ModeMode recursive_browser_mode_result(Mode *sw, int mretv, G_GNUC_UNUSED char **input,
unsigned int selected_line) {
ModeMode retv = MODE_EXIT;
FileBrowserModePrivateData *pd =
diff --git a/source/modes/run.c b/source/modes/run.c
index 4bc5ec038..8af097467 100644
--- a/source/modes/run.c
+++ b/source/modes/run.c
@@ -91,10 +91,13 @@ typedef struct {
/**
* @param cmd The cmd to execute
* @param run_in_term Indicate if command should be run in a terminal
+ * @param orig The cmd to store in history
*
* Execute command and add to history.
+ * Exact entries should be stored unquoted any custom or with filename
+ * should be saved in history quoted.
*/
-static gboolean exec_cmd(const char *cmd, int run_in_term) {
+static gboolean exec_cmd(const char *cmd, int run_in_term, const char *orig) {
GError *error = NULL;
if (!cmd || !cmd[0]) {
return FALSE;
@@ -118,12 +121,12 @@ static gboolean exec_cmd(const char *cmd, int run_in_term) {
* It is allowed to be a bit slower.
*/
- history_set(path, cmd);
+ history_set(path, orig);
g_free(path);
g_free(lf_cmd);
return TRUE;
}
- history_remove(path, cmd);
+ history_remove(path, orig);
g_free(path);
g_free(lf_cmd);
return FALSE;
@@ -444,12 +447,17 @@ static ModeMode run_mode_result(Mode *sw, int mretv, char **input,
&path);
if (retv == MODE_EXIT) {
if (path == NULL) {
- exec_cmd(rmpd->cmd_list[rmpd->selected_line].entry, run_in_term);
+ char *arg = g_shell_quote(rmpd->cmd_list[rmpd->selected_line].entry);
+ exec_cmd(arg, run_in_term, rmpd->cmd_list[rmpd->selected_line].entry);
+ g_free(arg);
} else {
- char *arg = g_strdup_printf(
- "%s '%s'", rmpd->cmd_list[rmpd->selected_line].entry, path);
- exec_cmd(arg, run_in_term);
+ char *earg = g_shell_quote(rmpd->cmd_list[rmpd->selected_line].entry);
+ char *epath = g_shell_quote(path);
+ char *arg = g_strdup_printf("%s %s", earg, epath);
+ exec_cmd(arg, run_in_term, arg);
g_free(arg);
+ g_free(earg);
+ g_free(epath);
}
}
g_free(path);
@@ -458,12 +466,14 @@ static ModeMode run_mode_result(Mode *sw, int mretv, char **input,
}
if ((mretv & MENU_OK) && rmpd->cmd_list[selected_line].entry != NULL) {
- if (!exec_cmd(rmpd->cmd_list[selected_line].entry, run_in_term)) {
+ char *earg = g_shell_quote(rmpd->cmd_list[selected_line].entry);
+ if (!exec_cmd(earg, run_in_term, rmpd->cmd_list[selected_line].entry)) {
retv = RELOAD_DIALOG;
}
+ g_free(earg);
} else if ((mretv & MENU_CUSTOM_INPUT) && *input != NULL &&
*input[0] != '\0') {
- if (!exec_cmd(*input, run_in_term)) {
+ if (!exec_cmd(*input, run_in_term, *input)) {
retv = RELOAD_DIALOG;
}
} else if ((mretv & MENU_ENTRY_DELETE) &&
diff --git a/source/modes/script.c b/source/modes/script.c
index dfd5bf321..f98117041 100644
--- a/source/modes/script.c
+++ b/source/modes/script.c
@@ -101,6 +101,9 @@ void dmenuscript_parse_entry_extras(G_GNUC_UNUSED Mode *sw,
} else if (strcasecmp(key, "nonselectable") == 0) {
entry->nonselectable = g_ascii_strcasecmp(value, "true") == 0;
g_free(value);
+ } else if (strcasecmp(key, "permanent") == 0) {
+ entry->permanent = g_ascii_strcasecmp(value, "true") == 0;
+ g_free(value);
} else if (strcasecmp(key, "urgent") == 0) {
entry->urgent = g_ascii_strcasecmp(value, "true") == 0;
g_free(value);
@@ -252,6 +255,7 @@ static DmenuScriptEntry *execute_executor(Mode *sw, char *arg,
retv[(*length)].icon_fetch_uid = 0;
retv[(*length)].icon_fetch_size = 0;
retv[(*length)].nonselectable = FALSE;
+ retv[(*length)].permanent = FALSE;
if (buf_length > 0 && (read_length > (ssize_t)buf_length)) {
dmenuscript_parse_entry_extras(sw, &(retv[(*length)]),
buffer + buf_length,
@@ -454,6 +458,12 @@ static int script_token_match(const Mode *sw, rofi_int_matcher **tokens,
ScriptModePrivateData *rmpd = sw->private_data;
/** Strip out the markup when matching. */
char *esc = NULL;
+
+ if (rmpd->cmd_list[index].permanent == TRUE) {
+ // Always match
+ return 1;
+ }
+
if (rmpd->do_markup) {
pango_parse_markup(rmpd->cmd_list[index].entry, -1, 0, NULL, &esc, NULL,
NULL);
diff --git a/source/modes/window.c b/source/modes/window.c
index 1d93e957f..27798c81c 100644
--- a/source/modes/window.c
+++ b/source/modes/window.c
@@ -161,7 +161,7 @@ winlist *cache_client = NULL;
*
* @returns A new window list.
*/
-static winlist *winlist_new() {
+static winlist *winlist_new(void) {
winlist *l = g_malloc(sizeof(winlist));
l->len = 0;
l->array = g_malloc_n(WINLIST + 1, sizeof(xcb_window_t));
@@ -176,7 +176,7 @@ static winlist *winlist_new() {
*
* Add one entry. If Full, extend with WINLIST entries.
*
- * @returns 0 if failed, 1 is successful.
+ * @returns -1 if failed, 0 or higher is successful.
*/
static int winlist_append(winlist *l, xcb_window_t w, client *d) {
if (l->len > 0 && !(l->len % WINLIST)) {
@@ -187,7 +187,7 @@ static int winlist_append(winlist *l, xcb_window_t w, client *d) {
// Make clang-check happy.
// TODO: make clang-check clear this should never be 0.
if (l->data == NULL || l->array == NULL) {
- return 0;
+ return -1;
}
l->data[l->len] = d;
@@ -386,7 +386,13 @@ static client *window_client(WindowModePrivateData *pd, xcb_window_t win) {
c->hint_flags = r.flags;
}
- winlist_append(cache_client, c->window, c);
+ idx = winlist_append(cache_client, c->window, c);
+ // Should never happen.
+ if (idx < 0) {
+ client_free(c);
+ g_free(c);
+ c = NULL;
+ }
g_free(attr);
return c;
}
@@ -470,7 +476,7 @@ static int window_match(const Mode *sw, rofi_int_matcher **tokens,
return match;
}
-static void window_mode_parse_fields() {
+static void window_mode_parse_fields(void) {
window_matching_fields_parsed = TRUE;
char *savept = NULL;
// Make a copy, as strtok will modify it.
@@ -971,7 +977,7 @@ static cairo_user_data_key_t data_key;
static cairo_surface_t *draw_surface_from_data(uint32_t width, uint32_t height,
uint32_t const *const data) {
// limit surface size.
- if ( width >= 65536 || height >= 65536){
+ if (width >= 65536 || height >= 65536) {
return NULL;
}
uint32_t len = width * height;
@@ -1138,8 +1144,8 @@ Mode window_mode = {.name = "window",
._get_completion = NULL,
._preprocess_input = NULL,
.private_data = NULL,
- .free = NULL,
- .type = MODE_TYPE_SWITCHER };
+ .free = NULL,
+ .type = MODE_TYPE_SWITCHER};
Mode window_mode_cd = {.name = "windowcd",
.cfg_name_key = "display-windowcd",
._init = window_mode_init_cd,
@@ -1153,6 +1159,6 @@ Mode window_mode_cd = {.name = "windowcd",
._preprocess_input = NULL,
.private_data = NULL,
.free = NULL,
- .type = MODE_TYPE_SWITCHER };
+ .type = MODE_TYPE_SWITCHER};
#endif // WINDOW_MODE
diff --git a/source/rofi-icon-fetcher.c b/source/rofi-icon-fetcher.c
index 02181fed7..22dc72bd3 100644
--- a/source/rofi-icon-fetcher.c
+++ b/source/rofi-icon-fetcher.c
@@ -94,6 +94,8 @@ typedef struct {
IconFetcherNameEntry *entry;
} IconFetcherEntry;
+// Free method.
+static void rofi_icon_fetch_entry_free(gpointer data);
/**
* The icon fetcher internal state.
*/
@@ -709,7 +711,7 @@ static void rofi_icon_fetcher_worker(thread_state *sdata,
icon_path, sentry->wsize, sentry->hsize, TRUE, &error);
if (error != NULL) {
g_warning("Failed to load image: |%s| %d %d %s (%p)", icon_path,
- sentry->wsize, sentry->hsize, error->message, pb);
+ sentry->wsize, sentry->hsize, error->message, (void *)pb);
g_error_free(error);
if (pb) {
g_object_unref(pb);
@@ -763,6 +765,7 @@ uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize,
// Push into fetching queue.
sentry->state.callback = rofi_icon_fetcher_worker;
+ sentry->state.free = rofi_icon_fetch_entry_free;
sentry->state.priority = G_PRIORITY_LOW;
g_thread_pool_push(tpool, sentry, NULL);
diff --git a/source/theme.c b/source/theme.c
index fe70574cf..e39531fd1 100644
--- a/source/theme.c
+++ b/source/theme.c
@@ -29,7 +29,6 @@
#define G_LOG_DOMAIN "Theme"
#include "config.h"
-#include
#include
#include
#include
@@ -169,7 +168,7 @@ Property *rofi_theme_property_copy(const Property *p,
for (GList *l = g_list_first(p->value.image.colors); l;
l = g_list_next(l)) {
retv->value.image.colors = g_list_append(
- retv->value.image.colors, g_memdup(l->data, sizeof(ThemeColor)));
+ retv->value.image.colors, g_memdup2(l->data, sizeof(ThemeColor)));
}
break;
}
@@ -599,11 +598,6 @@ void rofi_theme_print(ThemeWidget *widget) {
}
}
-/**
- * Main lex parser.
- */
-int yyparse();
-
/**
* Destroy the internal of lex parser.
*/
diff --git a/source/view.c b/source/view.c
index c27fcb87e..15c728656 100644
--- a/source/view.c
+++ b/source/view.c
@@ -29,7 +29,6 @@
#define G_LOG_DOMAIN "View"
#include "config.h"
-#include
#include
#include
#include
@@ -64,7 +63,6 @@
#include "mode.h"
#include "modes/modes.h"
#include "xcb-internal.h"
-#include "xrmoptions.h"
#include "view-internal.h"
#include "view.h"
@@ -218,12 +216,12 @@ static int lev_sort(const void *p1, const void *p2, void *arg) {
* Stores a screenshot of Rofi at that point in time.
*/
void rofi_capture_screenshot(void) {
- const char *outp = g_getenv("ROFI_PNG_OUTPUT");
- if (CacheState.edit_surf == NULL) {
- // Nothing to store.
- g_warning("There is no rofi surface to store");
+ RofiViewState *state = current_active_menu;
+ if (state == NULL || state->main_window == NULL) {
+ g_warning("Nothing to screenshot.");
return;
}
+ const char *outp = g_getenv("ROFI_PNG_OUTPUT");
const char *xdg_pict_dir = g_get_user_special_dir(G_USER_DIRECTORY_PICTURES);
if (outp == NULL && xdg_pict_dir == NULL) {
g_warning("XDG user picture directory or ROFI_PNG_OUTPUT is not set. "
@@ -254,12 +252,30 @@ void rofi_capture_screenshot(void) {
fpath = g_strdup(outp);
}
fprintf(stderr, color_green "Storing screenshot %s\n" color_reset, fpath);
- cairo_status_t status =
- cairo_surface_write_to_png(CacheState.edit_surf, fpath);
+ cairo_surface_t *surf = cairo_image_surface_create(
+ CAIRO_FORMAT_ARGB32, state->width, state->height);
+ cairo_status_t status = cairo_surface_status(surf);
if (status != CAIRO_STATUS_SUCCESS) {
g_warning("Failed to produce screenshot '%s', got error: '%s'", fpath,
cairo_status_to_string(status));
+ } else {
+ cairo_t *draw = cairo_create(surf);
+ status = cairo_status(draw);
+ if (status != CAIRO_STATUS_SUCCESS) {
+ g_warning("Failed to produce screenshot '%s', got error: '%s'", fpath,
+ cairo_status_to_string(status));
+ } else {
+ widget_draw(WIDGET(state->main_window), draw);
+ status = cairo_surface_write_to_png(surf, fpath);
+ if (status != CAIRO_STATUS_SUCCESS) {
+ g_warning("Failed to produce screenshot '%s', got error: '%s'", fpath,
+ cairo_status_to_string(status));
+ }
+ }
+ cairo_destroy(draw);
}
+ // Cleanup
+ cairo_surface_destroy(surf);
g_free(fpath);
g_free(filename);
g_free(timestmp);
@@ -1444,6 +1460,7 @@ static gboolean rofi_view_refilter_real(RofiViewState *state) {
states[i].plen = plen;
states[i].pattern = pattern;
states[i].st.callback = filter_elements;
+ states[i].st.free = NULL;
states[i].st.priority = G_PRIORITY_HIGH;
if (i > 0) {
g_thread_pool_push(tpool, &states[i], NULL);
@@ -1581,7 +1598,7 @@ void rofi_view_finalize(RofiViewState *state) {
* This function should be called when the input of the entry is changed.
* TODO: Evaluate if this needs to be a 'signal' on textbox?
*/
-static void rofi_view_input_changed() {
+static void rofi_view_input_changed(void) {
rofi_view_take_action("inputchange");
RofiViewState *state = current_active_menu;
@@ -2575,7 +2592,7 @@ void rofi_view_hide(void) {
}
}
-void rofi_view_cleanup() {
+void rofi_view_cleanup(void) {
// Clear clipboard data.
xcb_stuff_set_clipboard(NULL);
g_debug("Cleanup.");
@@ -2626,12 +2643,21 @@ void rofi_view_cleanup() {
input_history_save();
}
-static int rofi_thread_workers_sort(gconstpointer a,gconstpointer b, gpointer data G_GNUC_UNUSED)
-{
+static int rofi_thread_workers_sort(gconstpointer a, gconstpointer b,
+ gpointer data G_GNUC_UNUSED) {
thread_state *tsa = (thread_state *)a;
thread_state *tsb = (thread_state *)b;
- // lower number is lower priority.. a is sorted above is a > b.
- return tsa->priority-tsb->priority;
+ // lower number is lower priority.. a is sorted above is a > b.
+ return tsa->priority - tsb->priority;
+}
+
+static void rofi_thread_pool_state_free(gpointer data) {
+ if (data) {
+ thread_state *ts = (thread_state *)data;
+ if (ts->free) {
+ ts->free(data);
+ }
+ }
}
void rofi_view_workers_initialize(void) {
@@ -2645,8 +2671,9 @@ void rofi_view_workers_initialize(void) {
}
// Create thread pool
GError *error = NULL;
- tpool = g_thread_pool_new(rofi_view_call_thread, NULL, config.threads, FALSE,
- &error);
+ tpool = g_thread_pool_new_full(rofi_view_call_thread, NULL,
+ rofi_thread_pool_state_free, config.threads,
+ FALSE, &error);
if (error == NULL) {
// Idle threads should stick around for a max of 60 seconds.
g_thread_pool_set_max_idle_time(60000);
diff --git a/source/widgets/box.c b/source/widgets/box.c
index 3a5c49d49..e0425b8e3 100644
--- a/source/widgets/box.c
+++ b/source/widgets/box.c
@@ -96,6 +96,7 @@ static int box_get_desired_height(widget *wid, const int width) {
box *b = (box *)wid;
int spacing = distance_get_pixel(b->spacing, b->type);
int height = 0;
+ int nw = width - widget_padding_get_padding_width(wid);
if (b->type == ROFI_ORIENTATION_VERTICAL) {
int active_widgets = 0;
for (GList *iter = g_list_first(b->children); iter != NULL;
@@ -105,7 +106,7 @@ static int box_get_desired_height(widget *wid, const int width) {
continue;
}
active_widgets++;
- height += widget_get_desired_height(child, width);
+ height += widget_get_desired_height(child, nw);
}
if (active_widgets > 0) {
height += (active_widgets - 1) * spacing;
@@ -117,7 +118,7 @@ static int box_get_desired_height(widget *wid, const int width) {
if (!child->enabled) {
continue;
}
- height = MAX(widget_get_desired_height(child, width), height);
+ height = MAX(widget_get_desired_height(child, nw), height);
}
}
height += widget_padding_get_padding_height(wid);
diff --git a/source/xcb.c b/source/xcb.c
index 4e1039790..ccdec05af 100644
--- a/source/xcb.c
+++ b/source/xcb.c
@@ -558,7 +558,7 @@ static int x11_is_extension_present(const char *extension) {
return present;
}
-static void x11_build_monitor_layout_xinerama() {
+static void x11_build_monitor_layout_xinerama(void) {
xcb_xinerama_query_screens_cookie_t screens_cookie =
xcb_xinerama_query_screens_unchecked(xcb->connection);
@@ -589,7 +589,7 @@ static void x11_build_monitor_layout_xinerama() {
free(screens_reply);
}
-static void x11_build_monitor_layout() {
+static void x11_build_monitor_layout(void) {
if (xcb->monitors) {
return;
}
@@ -775,7 +775,7 @@ static int monitor_get_dimension(int monitor_id, workarea *mon) {
// find the dimensions of the monitor displaying point x,y
static void monitor_dimensions(int x, int y, workarea *mon) {
if (mon == NULL) {
- g_error("%s: mon == NULL", __FUNCTION__);
+ g_error("%s: mon == NULL", __func__);
return;
}
memset(mon, 0, sizeof(workarea));
@@ -818,7 +818,7 @@ static int pointer_get(xcb_window_t root, int *x, int *y) {
static int monitor_active_from_winid(xcb_drawable_t id, workarea *mon) {
if (mon == NULL) {
- g_error("%s: mon == NULL", __FUNCTION__);
+ g_error("%s: mon == NULL", __func__);
return FALSE;
}
xcb_window_t root = xcb->screen->root;
@@ -851,7 +851,7 @@ static int monitor_active_from_id_focused(int mon_id, workarea *mon) {
xcb_window_t active_window;
xcb_get_property_cookie_t awc;
if (mon == NULL) {
- g_error("%s: mon == NULL", __FUNCTION__);
+ g_error("%s: mon == NULL", __func__);
return retv;
}
awc = xcb_ewmh_get_active_window(&xcb->ewmh, xcb->screen_nbr);
@@ -920,7 +920,7 @@ static int monitor_active_from_id(int mon_id, workarea *mon) {
xcb_window_t root = xcb->screen->root;
int x, y;
if (mon == NULL) {
- g_error("%s: mon == NULL", __FUNCTION__);
+ g_error("%s: mon == NULL", __func__);
return FALSE;
}
g_debug("Monitor id: %d", mon_id);
@@ -1000,7 +1000,7 @@ workarea mon_cache = {
};
int monitor_active(workarea *mon) {
if (mon == NULL) {
- g_error("%s: mon == NULL", __FUNCTION__);
+ g_error("%s: mon == NULL", __func__);
return FALSE;
}
g_debug("Monitor active");
diff --git a/test/textbox-test.c b/test/textbox-test.c
index 3c7d67980..8ae3c9b6f 100644
--- a/test/textbox-test.c
+++ b/test/textbox-test.c
@@ -79,7 +79,7 @@ gboolean config_parse_set_property(G_GNUC_UNUSED const Property *p,
void rofi_add_error_message(G_GNUC_UNUSED GString *msg) {}
void rofi_add_warning_message(G_GNUC_UNUSED GString *msg) {}
-void rofi_view_queue_redraw() {}
+void rofi_view_queue_redraw(void) {}
void rofi_view_get_current_monitor(G_GNUC_UNUSED int *width,
G_GNUC_UNUSED int *height) {}
int rofi_view_error_dialog(const char *msg, G_GNUC_UNUSED int markup) {